diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..99f7c54 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +pk_generated_parent.pom linguist-generated=true +dependencies.md linguist-generated=true +doc/changes/changelog.md linguist-generated=true +.github/workflows/broken_links_checker.yml linguist-generated=true +.github/workflows/ci-build.yml linguist-generated=true +.github/workflows/ci-build-next-java.yml linguist-generated=true +.github/workflows/dependencies_check.yml linguist-generated=true +.github/workflows/dependencies_update.yml linguist-generated=true +.github/workflows/release.yml linguist-generated=true +.settings/org.eclipse.jdt.core.prefs linguist-generated=true +.settings/org.eclipse.jdt.ui.prefs linguist-generated=true diff --git a/.github/workflows/broken_links_checker.yml b/.github/workflows/broken_links_checker.yml new file mode 100644 index 0000000..39612b7 --- /dev/null +++ b/.github/workflows/broken_links_checker.yml @@ -0,0 +1,39 @@ +# Generated by Project Keeper +# https://github.com/exasol/project-keeper/blob/main/project-keeper/src/main/resources/templates/.github/workflows/broken_links_checker.yml +name: Broken Links Checker + +on: + schedule: + - cron: "0 5 * * 0" + push: + branches: + - main + pull_request: + +jobs: + linkChecker: + runs-on: ubuntu-latest + permissions: + contents: read + defaults: + run: + shell: "bash" + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: + - uses: actions/checkout@v4 + - name: Configure broken links checker + run: | + mkdir -p ./target + echo '{"aliveStatusCodes": [429, 200], "ignorePatterns": [' \ + '{"pattern": "^https?://(www|dev).mysql.com/"},' \ + '{"pattern": "^https?://(www.)?opensource.org"}' \ + '{"pattern": "^https?://(www.)?eclipse.org"}' \ + '{"pattern": "^https?://projects.eclipse.org"}' \ + ']}' > ./target/broken_links_checker.json + - uses: gaurav-nelson/github-action-markdown-link-check@v1 + with: + use-quiet-mode: "yes" + use-verbose-mode: "yes" + config-file: ./target/broken_links_checker.json diff --git a/.github/workflows/ci-build-next-java.yml b/.github/workflows/ci-build-next-java.yml new file mode 100644 index 0000000..e8302fe --- /dev/null +++ b/.github/workflows/ci-build-next-java.yml @@ -0,0 +1,36 @@ +# Generated by Project Keeper +# https://github.com/exasol/project-keeper/blob/main/project-keeper/src/main/resources/templates/.github/workflows/ci-build-next-java.yml +name: CI Build next Java +on: + push: + branches: + - main + pull_request: + +jobs: + java-17-compatibility: + runs-on: ubuntu-latest + defaults: + run: + shell: "bash" + permissions: + contents: read + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: 17 + cache: "maven" + - name: Run tests and build with Maven + run: | + mvn --batch-mode --update-snapshots clean package -DtrimStackTrace=false \ + -Djava.version=17 \ + -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml new file mode 100644 index 0000000..f29eed1 --- /dev/null +++ b/.github/workflows/ci-build.yml @@ -0,0 +1,172 @@ +# This file was generated by Project Keeper. +name: CI Build +on: + push: + branches: [ + main + ] + + pull_request: null +jobs: + matrix-build: + runs-on: ubuntu-20.04 + defaults: + run: { + shell: bash + } + permissions: { + contents: read + } + concurrency: { + group: '${{ github.workflow }}-${{ github.ref }}-${{ matrix.exasol_db_version }}', + cancel-in-progress: true + } + strategy: + fail-fast: false + matrix: + exasol_db_version: [ + 8.31.0, + 7.1.29 + ] + + env: { + DEFAULT_EXASOL_DB_VERSION: 8.31.0 + } + steps: + - name: Free Disk Space + id: free-disk-space + if: ${{ false }} + run: | + sudo rm -rf /usr/local/lib/android + sudo rm -rf /usr/share/dotnet + - name: Checkout the repository + id: checkout + uses: actions/checkout@v4 + with: { + fetch-depth: 0 + } + - name: Set up JDKs + id: setup-java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 11 + 17 + cache: maven + - name: Cache SonarCloud packages + id: cache-sonar + uses: actions/cache@v4 + with: { + path: ~/.sonar/cache, + key: '${{ runner.os }}-sonar', + restore-keys: '${{ runner.os }}-sonar' + } + - { + name: Enable testcontainer reuse, + id: enable-testcontainer-reuse, + run: echo 'testcontainers.reuse.enable=true' > "$HOME/.testcontainers.properties" + } + - name: Configure Snowflake credentials + id: configure-snowflake-credentials + run: | + cat > test.properties <> \"$GITHUB_STEP_SUMMARY\"\n}\n\nprint_message \"### Release Artifacts\"\n\nIFS=$'\\n' artifacts_array=($ARTIFACTS)\nmissing_files=()\nfor file in \"${artifacts_array[@]}\";\ndo \n echo \"Checking if file $file exists...\"\n if ! [[ -f \"$file\" ]]; then\n print_message \"* ⚠️ \\`$file\\` does not exist ⚠️\"\n echo \"Content of directory $(dirname \"$file\"):\"\n ls \"$(dirname \"$file\")\"\n missing_files+=(\"$file\")\n else\n print_message \"* \\`$file\\` ✅\" \n fi\ndone\nprint_message \"\"\nnumber_of_missing_files=${#missing_files[@]}\nif [[ $number_of_missing_files -gt 0 ]]; then\n print_message \"⚠️ $number_of_missing_files release artifact(s) missing ⚠️\"\n exit 1\nfi\n" + env: { + ARTIFACTS: '${{ steps.build-pk-verify.outputs.release-artifacts }}' + } + - name: Upload artifacts + id: upload-artifacts + uses: actions/upload-artifact@v4 + with: { + name: 'artifacts-exasol-${{ matrix.exasol_db_version }}', + path: '${{ steps.build-pk-verify.outputs.release-artifacts }}', + retention-days: 5 + } + build: + needs: matrix-build + runs-on: ubuntu-latest + defaults: + run: { + shell: bash + } + permissions: { + contents: read, + issues: read + } + outputs: { + release-required: '${{ steps.check-release.outputs.release-required }}' + } + steps: + - name: Checkout the repository + uses: actions/checkout@v4 + with: { + fetch-depth: 0 + } + - name: Set up JDKs + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 11 + 17 + cache: maven + - name: Check if release is needed + id: check-release + run: | + if mvn --batch-mode com.exasol:project-keeper-maven-plugin:verify-release --projects .; then + echo "### ✅ Release preconditions met, start release" >> "$GITHUB_STEP_SUMMARY" + echo "release-required=true" >> "$GITHUB_OUTPUT" + else + echo "### 🛑 Not all release preconditions met, skipping release" >> "$GITHUB_STEP_SUMMARY" + echo "See log output for details." >> "$GITHUB_STEP_SUMMARY" + echo "release-required=false" >> "$GITHUB_OUTPUT" + fi + env: { + GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}' + } + start_release: + needs: build + if: ${{ github.ref == 'refs/heads/main' && needs.build.outputs.release-required == 'true' }} + concurrency: { + cancel-in-progress: false, + group: release + } + secrets: inherit + permissions: { + contents: write, + actions: read, + issues: read + } + uses: ./.github/workflows/release.yml + with: { + started-from-ci: true + } diff --git a/.github/workflows/dependencies_check.yml b/.github/workflows/dependencies_check.yml new file mode 100644 index 0000000..9c2365c --- /dev/null +++ b/.github/workflows/dependencies_check.yml @@ -0,0 +1,80 @@ +# This file was generated by Project Keeper. +name: Report Security Issues +on: + workflow_dispatch: null + schedule: + - { + cron: 0 2 * * * + } +jobs: + report_security_issues: + runs-on: ubuntu-latest + defaults: + run: { + shell: bash + } + permissions: { + contents: read, + issues: write + } + outputs: { + created-issues: '${{ steps.security-issues.outputs.created-issues }}' + } + concurrency: { + group: '${{ github.workflow }}-report_security_issues', + cancel-in-progress: true + } + steps: + - { + name: Checkout, + id: checkout, + uses: actions/checkout@v4 + } + - name: Set up JDKs + id: setup-jdks + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 11 + 17 + cache: maven + - name: Generate ossindex report + id: ossindex-report + run: | + mvn --batch-mode org.sonatype.ossindex.maven:ossindex-maven-plugin:audit \ + org.sonatype.ossindex.maven:ossindex-maven-plugin:audit-aggregate \ + -Dossindex.reportFile=$(pwd)/ossindex-report.json \ + -Dossindex.fail=false + - name: Report Security Issues + id: security-issues + uses: exasol/python-toolbox/.github/actions/security-issues@main + with: { + format: maven, + command: cat ossindex-report.json, + github-token: '${{ secrets.GITHUB_TOKEN }}' + } + - name: Output security issues (Debugging) + id: debug-print-security-issues + run: | + echo "$CREATED_ISSUES" > test.jsonl + cat test.jsonl + env: { + CREATED_ISSUES: '${{ steps.security-issues.outputs.created-issues }}' + } + start_dependency_udpate: + needs: report_security_issues + if: ${{ needs.report_security_issues.outputs.created-issues }} + concurrency: { + group: '${{ github.workflow }}-start_dependency_update', + cancel-in-progress: false + } + secrets: inherit + permissions: { + contents: write, + pull-requests: write + } + uses: ./.github/workflows/dependencies_update.yml + with: { + vulnerability_issues: '${{ needs.report_security_issues.outputs.created-issues }}' + } diff --git a/.github/workflows/dependencies_update.yml b/.github/workflows/dependencies_update.yml new file mode 100644 index 0000000..0fa7180 --- /dev/null +++ b/.github/workflows/dependencies_update.yml @@ -0,0 +1,176 @@ +# This file was generated by Project Keeper. +name: Update dependencies +on: + workflow_call: + inputs: + vulnerability_issues: { + description: GitHub issues for vulnerable dependencies as JSONL, + required: true, + type: string + } + workflow_dispatch: null +jobs: + update_dependencies: + runs-on: ubuntu-latest + defaults: + run: { + shell: bash + } + permissions: { + contents: write, + pull-requests: write + } + concurrency: { + group: '${{ github.workflow }}', + cancel-in-progress: false + } + steps: + - uses: actions/checkout@v4 + id: checkout + with: { + fetch-depth: 0 + } + - name: Set up JDKs + id: setup-jdks + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 11 + 17 + cache: maven + - name: Print issues + id: debug-print-issues + run: | + echo "Issues from Action input: $ISSUES" + env: { + ISSUES: '${{ inputs.vulnerability_issues }}' + } + - name: Fail if not running on a branch + id: check-branch + if: ${{ !startsWith(github.ref, 'refs/heads/') }} + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Not running on a branch, github.ref is ${{ github.ref }}. Please start this workflow only on main or a branch') + - name: Update dependencies + id: update-dependencies + run: | + mvn --batch-mode com.exasol:project-keeper-maven-plugin:update-dependencies --projects . \ + -Dproject-keeper:vulnerabilities="$CREATED_ISSUES" + env: { + CREATED_ISSUES: '${{ inputs.vulnerability_issues }}' + } + - name: Generate Pull Request comment + id: pr-comment + run: | + echo 'comment<> "$GITHUB_OUTPUT" + echo 'This Pull Request was created by [`dependencies_update.yml`](https://github.com/exasol/project-keeper/blob/main/project-keeper/src/main/resources/templates/.github/workflows/dependencies_update.yml) workflow.' >> "$GITHUB_OUTPUT" + if [ -n "$CREATED_ISSUES" ]; then + echo 'It updates dependencies to fix the following vulnerabilities:' >> "$GITHUB_OUTPUT" + echo $CREATED_ISSUES | jq --raw-output '. | "* Closes " + .issue_url + " (" + .cve + ")"' >> "$GITHUB_OUTPUT" + else + echo 'It updates dependencies.' >> "$GITHUB_OUTPUT" + fi + echo >> "$GITHUB_OUTPUT" + echo '# ⚠️ Notes ⚠️' >> "$GITHUB_OUTPUT" + echo '## Run PK fix manually' >> "$GITHUB_OUTPUT" + echo 'Due to restrictions workflow `dependencies_update.yml` cannot update other workflows, see https://github.com/exasol/project-keeper/issues/578 for details.' >> "$GITHUB_OUTPUT" + echo 'Please checkout this PR locally and run `mvn com.exasol:project-keeper-maven-plugin:fix --projects .`' >> "$GITHUB_OUTPUT" + echo '## This PR does not trigger CI workflows' >> "$GITHUB_OUTPUT" + echo 'Please click the **Close pull request** button and then **Reopen pull request** to trigger running checks.' >> "$GITHUB_OUTPUT" + echo 'See https://github.com/exasol/project-keeper/issues/534 for details.' >> "$GITHUB_OUTPUT" + echo 'EOF' >> "$GITHUB_OUTPUT" + + cat "$GITHUB_OUTPUT" + env: { + CREATED_ISSUES: '${{ inputs.vulnerability_issues }}' + } + - name: Generate Pull Request Title + id: pr-title + run: | + if [ -n "$CREATED_ISSUES" ]; then + echo "Security issues are available" + echo "title=🔐 Update dependencies to fix vulnerabilities" >> "$GITHUB_OUTPUT" + else + echo "Security issues are not available" + echo "title=Update dependencies" >> "$GITHUB_OUTPUT" + fi + + cat "$GITHUB_OUTPUT" + env: { + CREATED_ISSUES: '${{ inputs.vulnerability_issues }}' + } + - name: Configure git + id: configure-git + run: | + git config --global user.email "opensource@exasol.com" + git config --global user.name "Automatic Dependency Updater" + - name: Create branch + id: create-branch + if: ${{ github.ref == 'refs/heads/main' }} + run: | + branch_name="dependency-update/$(date "+%Y%m%d%H%M%S")" + echo "Creating branch $branch_name" + git checkout -b "$branch_name" + - name: Commit changes & push + id: publish-branch + if: ${{ startsWith(github.ref, 'refs/heads/' ) }} + run: | + branch_name=$(git rev-parse --abbrev-ref HEAD) + echo "Current branch: $branch_name" + echo "git diff --stat" + git diff --stat + echo "git diff --numstat" + git diff --numstat + echo "git diff --name-status" + git diff --name-status + echo "Adding untracked files:" + git add . --verbose --all + echo "Committing changes..." + git commit --message "$TITLE" + echo "Pushing branch $branch_name..." + git push --set-upstream origin "$branch_name" + echo "Done." + env: { + TITLE: '${{ steps.pr-title.outputs.title }}' + } + - name: Create pull request + id: create-pr + if: ${{ github.ref == 'refs/heads/main' }} + run: | + pr_url=$(gh pr create --base main --title "$TITLE" --body "$COMMENT") + echo "Created Pull Request: $pr_url" + echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT" + env: { + COMMENT: '${{ steps.pr-comment.outputs.comment }}', + TITLE: '${{ steps.pr-title.outputs.title }}', + GH_TOKEN: '${{ github.token }}' + } + - name: Report failure Status to Slack channel + id: report-failure-slack + if: ${{ always() }} + uses: ravsamhq/notify-slack-action@v2 + with: { + status: '${{ job.status }}', + token: '${{ secrets.GITHUB_TOKEN }}', + notification_title: 'Dependency check in {repo} has {status_message}', + message_format: '{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>', + notify_when: 'failure,cancelled,warnings' + } + env: { + SLACK_WEBHOOK_URL: '${{ secrets.INTEGRATION_TEAM_SLACK_NOTIFICATION_WEBHOOK }}' + } + - name: Report new Pull Request to Slack channel + id: report-pr-slack + if: ${{ steps.create-pr.outputs.pr_url }} + uses: ravsamhq/notify-slack-action@v2 + with: { + status: '${{ job.status }}', + token: '${{ secrets.GITHUB_TOKEN }}', + notification_title: 'Dependency update for {repo} created a Pull Request', + message_format: '{workflow} created Pull Request ${{ steps.create-pr.outputs.pr_url }}' + } + env: { + SLACK_WEBHOOK_URL: '${{ secrets.INTEGRATION_TEAM_SLACK_NOTIFICATION_WEBHOOK }}' + } diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a76c836 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,227 @@ +# This file was generated by Project Keeper. +name: Release +on: + workflow_call: + inputs: + started-from-ci: { + description: 'Marks this release as started from CI, skipping precondition check', + type: boolean, + required: true, + default: false + } + workflow_dispatch: + inputs: + skip-maven-central: { + description: Skip deployment to Maven Central, + required: true, + type: boolean, + default: false + } + skip-github-release: { + description: Skip creating the GitHub release, + required: true, + type: boolean, + default: false + } +jobs: + release: + runs-on: ubuntu-latest + defaults: + run: { + shell: bash + } + concurrency: { + group: '${{ github.workflow }}', + cancel-in-progress: false + } + permissions: { + contents: write, + actions: read, + issues: read + } + steps: + - name: Checkout the repository + id: checkout + uses: actions/checkout@v4 + with: { + fetch-depth: 0 + } + - name: Set up Maven Central Repository + id: configure-maven-central-credentials + if: ${{ false }} + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 11 + 17 + cache: maven + server-id: ossrh + server-username: MAVEN_USERNAME + server-password: MAVEN_PASSWORD + gpg-private-key: ${{ secrets.OSSRH_GPG_SECRET_KEY }} + gpg-passphrase: MAVEN_GPG_PASSPHRASE + - name: Set up JDKs + id: setup-jdks + if: ${{ ! false }} + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: | + 11 + 17 + cache: maven + - name: Fail if not running on main branch + id: check-main-branch + if: ${{ github.ref != 'refs/heads/main' }} + uses: actions/github-script@v7 + with: + script: | + core.setFailed('Not running on main branch, github.ref is ${{ github.ref }}. Please start this workflow only on main') + - name: Check CI build of this commit succeeded + id: check-ci-build-status + if: ${{ ! inputs.started-from-ci }} + run: | + echo "Commit SHA: $COMMIT_SHA" + gh run list --workflow ci-build.yml --branch main --event push --commit $COMMIT_SHA + ci_build_status=$(gh run list --workflow ci-build.yml --branch main --event push --commit $COMMIT_SHA --json conclusion --template '{{range .}}{{.conclusion}}{{"\n"}}{{end}}') + echo "CI build status at commit $COMMIT_SHA was '$ci_build_status'" + if [[ "$ci_build_status" != "success" ]]; then + gh run list --workflow ci-build.yml --commit $COMMIT_SHA >> $GITHUB_STEP_SUMMARY + echo "Status of CI build for commit $COMMIT_SHA was '$ci_build_status', expected 'success'" >> $GITHUB_STEP_SUMMARY + cat $GITHUB_STEP_SUMMARY + exit 1 + fi + env: { + COMMIT_SHA: '${{ github.sha }}', + GH_TOKEN: '${{ github.token }}' + } + - name: Verify release preconditions + id: verify-release + run: | + mvn --batch-mode com.exasol:project-keeper-maven-plugin:verify-release --projects . + echo "$GITHUB_OUTPUT" + env: { + GITHUB_TOKEN: '${{ github.token }}' + } + - name: Configure Snowflake credentials + id: configure-snowflake-credentials + run: |- + cat > test.properties <> "$GITHUB_STEP_SUMMARY" + mvn --batch-mode -Dgpg.skip=false -DskipTests deploy + echo "Published to Maven Central ✅" >> "$GITHUB_STEP_SUMMARY" + env: { + MAVEN_USERNAME: '${{ secrets.OSSRH_USERNAME }}', + MAVEN_PASSWORD: '${{ secrets.OSSRH_PASSWORD }}', + MAVEN_GPG_PASSPHRASE: '${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }}' + } + - name: Calculate Artifact Checksums + id: artifact-checksum + if: ${{ ! inputs.skip-github-release }} + run: | + echo "Calculating sha256 checksum for artifact files" + echo "artifacts<> "$GITHUB_OUTPUT" + IFS=$'\n' artifacts_array=($ARTIFACTS) + for file in "${artifacts_array[@]}"; + do + full_path=$(realpath "$file") + echo "Calculate sha256sum for file '$full_path'" + file_dir="$(dirname "$full_path")" + file_name=$(basename "$full_path") + pushd "$file_dir" + checksum_file_name="${file_name}.sha256" + sha256sum "$file_name" > "$checksum_file_name" + echo "$full_path" >> "$GITHUB_OUTPUT" + echo "${file_dir}/$checksum_file_name" >> "$GITHUB_OUTPUT" + popd + done + echo "EOF" >> "$GITHUB_OUTPUT" + echo "Full artifact file list" + cat "$GITHUB_OUTPUT" + env: { + ARTIFACTS: '${{ steps.verify-release.outputs.release-artifacts }}' + } + - name: Create GitHub Release + id: create-github-release + if: ${{ ! inputs.skip-github-release }} + run: | + echo "### GitHub Release" >> "$GITHUB_STEP_SUMMARY" + IFS=$'\n' artifacts_array=($ARTIFACTS) + echo "#### Attaching Release Artifacts" >> "$GITHUB_STEP_SUMMARY" + for file in "${artifacts_array[@]}"; + do + echo "Attaching artifact '$file'" + echo "* \`$file\`" >> "$GITHUB_STEP_SUMMARY" + done + echo "" >> "$GITHUB_STEP_SUMMARY" + release_url=$(gh release create --latest --title "$TITLE" --notes "$NOTES" --target main $TAG "${artifacts_array[@]}") + echo "Created release $TAG with title '$TITLE' at $release_url ✅" >> "$GITHUB_STEP_SUMMARY" + echo "release-url=$release_url" >> "$GITHUB_OUTPUT" + + # [impl->dsn~release-workflow.create-golang-tags~1] + echo "#### Creating Additional Tags" >> "$GITHUB_STEP_SUMMARY" + IFS=$'\n' tags_array=($ADDITIONAL_TAGS) + for tag in "${tags_array[@]}"; + do + echo "Creating tag '$tag'" + git tag "$tag" + git push origin "$tag" + echo "* \`$tag\`" >> "$GITHUB_STEP_SUMMARY" + done + + git fetch --tags origin + env: { + GH_TOKEN: '${{ github.token }}', + TAG: '${{ steps.verify-release.outputs.release-tag }}', + ADDITIONAL_TAGS: '${{ steps.verify-release.outputs.additional-release-tags }}', + NOTES: '${{ steps.verify-release.outputs.release-notes }}', + TITLE: '${{ steps.verify-release.outputs.release-title }}', + ARTIFACTS: '${{ steps.artifact-checksum.outputs.artifacts }}' + } + - name: Report failure Status to Slack channel + id: report-failure-status-slack + if: ${{ always() }} + uses: ravsamhq/notify-slack-action@v2 + with: { + status: '${{ job.status }}', + token: '${{ github.token }}', + notification_title: 'Release build in {repo} has {status_message}', + message_format: '{emoji} *{workflow}* {status_message} in <{repo_url}|{repo}>', + notify_when: 'failure,cancelled,warnings,skipped' + } + env: { + SLACK_WEBHOOK_URL: '${{ secrets.INTEGRATION_TEAM_SLACK_NOTIFICATION_WEBHOOK }}' + } + - name: Report new release to Slack channel + id: report-new-release-slack + if: ${{ steps.create-github-release.outputs.release-url }} + uses: ravsamhq/notify-slack-action@v2 + with: { + status: '${{ job.status }}', + token: '${{ github.token }}', + notification_title: 'Release build for {repo} created a new release', + message_format: '{workflow} created release ${{ steps.create-github-release.outputs.release-url }}' + } + env: { + SLACK_WEBHOOK_URL: '${{ secrets.INTEGRATION_TEAM_SLACK_NOTIFICATION_WEBHOOK }}' + } diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c6ca013 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +/target/ +pom.xml.versionsBackup + +# Eclipse and Maven +.classpath +.project +/.settings/org.eclipse.core.resources.prefs +/.settings/org.eclipse.m2e.core.prefs +/.settings/org.eclipse.jdt.apt.core.prefs +# .settings : we need Eclipse settings for code formatter and clean-up rules +target +.cache +dependency-reduced-pom.xml + +# Intellij +.idea +# Intellij recommends to share iml files, however, better don't share files which might be outdated +*.iml + + +# Others +.DS_Store +*.swp +local +Scripts +.dbeaver* +**/*.log +.directory +venv/ + +~* +*.lock +*.bak +*.orig +*.old +*.md.html +/.apt_generated/ +/.apt_generated_tests/ +*.flattened-pom.xml +/bin/ + +test.properties \ No newline at end of file diff --git a/.project-keeper.yml b/.project-keeper.yml new file mode 100644 index 0000000..caa6ed1 --- /dev/null +++ b/.project-keeper.yml @@ -0,0 +1,45 @@ +sources: + - type: maven + path: pom.xml + modules: + - integration_tests + - udf_coverage + - jar_artifact +version: + fromSource: pom.xml +build: + runnerOs: ubuntu-20.04 + freeDiskSpace: false + exasolDbVersions: + - "8.31.0" + - "7.1.29" + workflows: + - name: ci-build.yml + stepCustomizations: + # Configure Snowflake credentials + - action: INSERT_AFTER + stepId: enable-testcontainer-reuse + content: + name: Configure Snowflake credentials + id: configure-snowflake-credentials + run: | + cat > test.properties < test.properties < +# Dependencies + +## Compile Dependencies + +| Dependency | License | +| ------------------------------- | --------------------------------------------- | +| [Virtual Schema Common JDBC][0] | [MIT License][1] | +| [error-reporting-java][2] | [MIT License][3] | +| [Snowflake JDBC Driver][4] | [The Apache Software License, Version 2.0][5] | + +## Test Dependencies + +| Dependency | License | +| ----------------------------------------------- | --------------------------------------------- | +| [Hamcrest][6] | [BSD License 3][7] | +| [JUnit Jupiter (Aggregator)][8] | [Eclipse Public License v2.0][9] | +| [mockito-junit-jupiter][10] | [MIT][11] | +| [Virtual Schema Common JDBC][0] | [MIT License][1] | +| [Test containers for Exasol on Docker][12] | [MIT License][13] | +| [Testcontainers :: JUnit Jupiter Extension][14] | [MIT][15] | +| [Test Database Builder for Java][16] | [MIT License][17] | +| [Matcher for SQL Result Sets][18] | [MIT License][19] | +| [udf-debugging-java][20] | [MIT License][21] | +| [Markdown Generator][22] | [The Apache Software License, Version 2.0][5] | +| [Autogenerated resource verifier][23] | [MIT License][24] | +| [virtual-schema-shared-integration-tests][25] | [MIT License][26] | +| [JaCoCo :: Agent][27] | [EPL-2.0][28] | + +## Plugin Dependencies + +| Dependency | License | +| ------------------------------------------------------- | --------------------------------- | +| [SonarQube Scanner for Maven][29] | [GNU LGPL 3][30] | +| [Apache Maven Toolchains Plugin][31] | [Apache-2.0][32] | +| [Apache Maven Compiler Plugin][33] | [Apache-2.0][32] | +| [Apache Maven Enforcer Plugin][34] | [Apache-2.0][32] | +| [Maven Flatten Plugin][35] | [Apache Software Licenese][32] | +| [org.sonatype.ossindex.maven:ossindex-maven-plugin][36] | [ASL2][5] | +| [Maven Surefire Plugin][37] | [Apache-2.0][32] | +| [Versions Maven Plugin][38] | [Apache License, Version 2.0][32] | +| [duplicate-finder-maven-plugin Maven Mojo][39] | [Apache License 2.0][40] | +| [Apache Maven Assembly Plugin][41] | [Apache-2.0][32] | +| [Apache Maven JAR Plugin][42] | [Apache-2.0][32] | +| [Artifact reference checker and unifier][43] | [MIT License][44] | +| [Project Keeper Maven plugin][45] | [The MIT License][46] | +| [Apache Maven Dependency Plugin][47] | [Apache-2.0][32] | +| [Exec Maven Plugin][48] | [Apache License 2][32] | +| [Maven Failsafe Plugin][49] | [Apache-2.0][32] | +| [JaCoCo :: Maven Plugin][50] | [EPL-2.0][28] | +| [error-code-crawler-maven-plugin][51] | [MIT License][52] | +| [Reproducible Build Maven Plugin][53] | [Apache 2.0][5] | + +[0]: https://github.com/exasol/virtual-schema-common-jdbc/ +[1]: https://github.com/exasol/virtual-schema-common-jdbc/blob/main/LICENSE +[2]: https://github.com/exasol/error-reporting-java/ +[3]: https://github.com/exasol/error-reporting-java/blob/main/LICENSE +[4]: https://www.snowflake.net/ +[5]: http://www.apache.org/licenses/LICENSE-2.0.txt +[6]: http://hamcrest.org/JavaHamcrest/ +[7]: http://opensource.org/licenses/BSD-3-Clause +[8]: https://junit.org/junit5/ +[9]: https://www.eclipse.org/legal/epl-v20.html +[10]: https://github.com/mockito/mockito +[11]: https://opensource.org/licenses/MIT +[12]: https://github.com/exasol/exasol-testcontainers/ +[13]: https://github.com/exasol/exasol-testcontainers/blob/main/LICENSE +[14]: https://java.testcontainers.org +[15]: http://opensource.org/licenses/MIT +[16]: https://github.com/exasol/test-db-builder-java/ +[17]: https://github.com/exasol/test-db-builder-java/blob/main/LICENSE +[18]: https://github.com/exasol/hamcrest-resultset-matcher/ +[19]: https://github.com/exasol/hamcrest-resultset-matcher/blob/main/LICENSE +[20]: https://github.com/exasol/udf-debugging-java/ +[21]: https://github.com/exasol/udf-debugging-java/blob/main/LICENSE +[22]: https://github.com/Steppschuh/Java-Markdown-Generator +[23]: https://github.com/exasol/autogenerated-resource-verifier-java/ +[24]: https://github.com/exasol/autogenerated-resource-verifier-java/blob/main/LICENSE +[25]: https://github.com/exasol/virtual-schema-shared-integration-tests/ +[26]: https://github.com/exasol/virtual-schema-shared-integration-tests/blob/main/LICENSE +[27]: https://www.eclemma.org/jacoco/index.html +[28]: https://www.eclipse.org/legal/epl-2.0/ +[29]: http://sonarsource.github.io/sonar-scanner-maven/ +[30]: http://www.gnu.org/licenses/lgpl.txt +[31]: https://maven.apache.org/plugins/maven-toolchains-plugin/ +[32]: https://www.apache.org/licenses/LICENSE-2.0.txt +[33]: https://maven.apache.org/plugins/maven-compiler-plugin/ +[34]: https://maven.apache.org/enforcer/maven-enforcer-plugin/ +[35]: https://www.mojohaus.org/flatten-maven-plugin/ +[36]: https://sonatype.github.io/ossindex-maven/maven-plugin/ +[37]: https://maven.apache.org/surefire/maven-surefire-plugin/ +[38]: https://www.mojohaus.org/versions/versions-maven-plugin/ +[39]: https://basepom.github.io/duplicate-finder-maven-plugin +[40]: http://www.apache.org/licenses/LICENSE-2.0.html +[41]: https://maven.apache.org/plugins/maven-assembly-plugin/ +[42]: https://maven.apache.org/plugins/maven-jar-plugin/ +[43]: https://github.com/exasol/artifact-reference-checker-maven-plugin/ +[44]: https://github.com/exasol/artifact-reference-checker-maven-plugin/blob/main/LICENSE +[45]: https://github.com/exasol/project-keeper/ +[46]: https://github.com/exasol/project-keeper/blob/main/LICENSE +[47]: https://maven.apache.org/plugins/maven-dependency-plugin/ +[48]: https://www.mojohaus.org/exec-maven-plugin +[49]: https://maven.apache.org/surefire/maven-failsafe-plugin/ +[50]: https://www.jacoco.org/jacoco/trunk/doc/maven.html +[51]: https://github.com/exasol/error-code-crawler-maven-plugin/ +[52]: https://github.com/exasol/error-code-crawler-maven-plugin/blob/main/LICENSE +[53]: http://zlika.github.io/reproducible-build-maven-plugin diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md new file mode 100644 index 0000000..9e62d07 --- /dev/null +++ b/doc/changes/changelog.md @@ -0,0 +1,3 @@ +# Changes + +* [0.1.0](changes_0.1.0.md) diff --git a/doc/changes/changes_0.1.0.md b/doc/changes/changes_0.1.0.md new file mode 100644 index 0000000..05e133a --- /dev/null +++ b/doc/changes/changes_0.1.0.md @@ -0,0 +1,64 @@ +# Virtual Schema for Snowflake 0.1.0, released 2024-10-01 + +Code name: First version of the Snowflake virtual schema + +## Summary + +This is the first version of the virtual schema for Snowflake. +There might still be issues and the project is subject to further testing. +Consider this a first and early-access release. + +## Features + +* #1: Releasing the MVP (minimum viable product) + +## Dependency Updates + +### Compile Dependency Updates + +* Added `com.exasol:error-reporting-java:1.0.1` +* Added `com.exasol:virtual-schema-common-jdbc:12.0.0` +* Added `net.snowflake:snowflake-jdbc:3.16.1` + +### Test Dependency Updates + +* Added `com.exasol:autogenerated-resource-verifier-java:0.1.2` +* Added `com.exasol:exasol-testcontainers:7.1.1` +* Added `com.exasol:hamcrest-resultset-matcher:1.6.4` +* Added `com.exasol:test-db-builder-java:3.5.3` +* Added `com.exasol:udf-debugging-java:0.6.11` +* Added `com.exasol:virtual-schema-common-jdbc:12.0.0` +* Added `com.exasol:virtual-schema-shared-integration-tests:3.0.0` +* Added `net.steppschuh.markdowngenerator:markdowngenerator:1.3.1.1` +* Added `org.hamcrest:hamcrest:2.2` +* Added `org.jacoco:org.jacoco.agent:0.8.12` +* Added `org.junit.jupiter:junit-jupiter:5.10.1` +* Added `org.mockito:mockito-junit-jupiter:5.10.0` +* Added `org.testcontainers:junit-jupiter:1.19.4` + +### Plugin Dependency Updates + +* Added `com.exasol:artifact-reference-checker-maven-plugin:0.4.2` +* Added `com.exasol:error-code-crawler-maven-plugin:2.0.3` +* Added `com.exasol:project-keeper-maven-plugin:4.3.3` +* Added `io.github.zlika:reproducible-build-maven-plugin:0.16` +* Added `org.apache.maven.plugins:maven-assembly-plugin:3.7.1` +* Added `org.apache.maven.plugins:maven-clean-plugin:2.5` +* Added `org.apache.maven.plugins:maven-compiler-plugin:3.13.0` +* Added `org.apache.maven.plugins:maven-dependency-plugin:3.6.1` +* Added `org.apache.maven.plugins:maven-deploy-plugin:2.7` +* Added `org.apache.maven.plugins:maven-enforcer-plugin:3.5.0` +* Added `org.apache.maven.plugins:maven-failsafe-plugin:3.2.5` +* Added `org.apache.maven.plugins:maven-install-plugin:2.4` +* Added `org.apache.maven.plugins:maven-jar-plugin:3.4.1` +* Added `org.apache.maven.plugins:maven-resources-plugin:2.6` +* Added `org.apache.maven.plugins:maven-site-plugin:3.3` +* Added `org.apache.maven.plugins:maven-surefire-plugin:3.2.5` +* Added `org.apache.maven.plugins:maven-toolchains-plugin:3.2.0` +* Added `org.basepom.maven:duplicate-finder-maven-plugin:2.0.1` +* Added `org.codehaus.mojo:exec-maven-plugin:3.1.0` +* Added `org.codehaus.mojo:flatten-maven-plugin:1.6.0` +* Added `org.codehaus.mojo:versions-maven-plugin:2.16.2` +* Added `org.jacoco:jacoco-maven-plugin:0.8.12` +* Added `org.sonarsource.scanner.maven:sonar-maven-plugin:4.0.0.4121` +* Added `org.sonatype.ossindex.maven:ossindex-maven-plugin:3.2.0` diff --git a/doc/design.md b/doc/design.md new file mode 100644 index 0000000..0a5aeee --- /dev/null +++ b/doc/design.md @@ -0,0 +1,9 @@ +# Design for the Snowflake Virtual Schema adapter + +## General design notes +The snowflake virtual schema's capabilities, mapping and query pushdown are mainly based on the existing PostgreSql virtual schema. +This is because the PostgreSql database approaches Snowflake the closest, functionality wise. Currently there are few deviations but this is expected to change. + +## Notes on NUMERIC +The numeric datatype has a higher supported precision in Snowflake (38 vs 36 in Snowflake): +If the precision is higher than 36 the column gets mapped to varchar and will display 'Precision not supported' as value. \ No newline at end of file diff --git a/doc/developer_guide/developer_guide.md b/doc/developer_guide/developer_guide.md new file mode 100644 index 0000000..3333707 --- /dev/null +++ b/doc/developer_guide/developer_guide.md @@ -0,0 +1,24 @@ +# Developers Guide + +## Running the integration tests + +Located in `SnowflakeSqlDialectIT.java` + +### Locally + +You need to add a `test.properties` file to the project folder that has the following structure: +` +snowflake.username = +snowflake.accountname = +snowflake.password = +` + +### In the GitHub CI + +The credentials are stored in the following GitHub repository secrets: +- `USERNAME` +- `ACCOUNTNAME` +- `PASSWORD` +and get read out by the relevant CI workflows. + + diff --git a/doc/developers_guide/developers_guide.md b/doc/developers_guide/developers_guide.md new file mode 100644 index 0000000..1c2e6d2 --- /dev/null +++ b/doc/developers_guide/developers_guide.md @@ -0,0 +1,3 @@ +# Developers Guide + + diff --git a/doc/generated/capabilities.md b/doc/generated/capabilities.md new file mode 100644 index 0000000..230d986 --- /dev/null +++ b/doc/generated/capabilities.md @@ -0,0 +1,307 @@ + + +# Capabilities + +Capabilities tell the Exasol which SQL features / keywords a Virtual Schema adapter supports. If the Virtual Schema does not support a certain capability, Exasol rewrites the query without that feature. In case a Virtual Schema adapter has no capabilities at all, Exasol will rewrite all queries to `SELECT * FROM table`. That means, that it will always load the whole remote table, even if only a single row is requested.So, for optimizing your performance, make sure that at least all functions that you use in the `WHERE` clause of your queries are supported by the Virtual Schema adapter. + +## Main Capabilities + +| Capability | Supported | +| ----------------------------- |:---------:| +| SELECTLIST_PROJECTION | ✓ | +| SELECTLIST_EXPRESSIONS | ✓ | +| FILTER_EXPRESSIONS | ✓ | +| AGGREGATE_SINGLE_GROUP | ✓ | +| AGGREGATE_GROUP_BY_COLUMN | ✓ | +| AGGREGATE_GROUP_BY_EXPRESSION | ✓ | +| AGGREGATE_GROUP_BY_TUPLE | ✓ | +| AGGREGATE_HAVING | ✓ | +| ORDER_BY_COLUMN | ✓ | +| ORDER_BY_EXPRESSION | ✓ | +| LIMIT | ✓ | +| LIMIT_WITH_OFFSET | ✓ | +| JOIN | ✓ | +| JOIN_TYPE_INNER | ✓ | +| JOIN_TYPE_LEFT_OUTER | ✓ | +| JOIN_TYPE_RIGHT_OUTER | ✓ | +| JOIN_TYPE_FULL_OUTER | ✓ | +| JOIN_CONDITION_EQUI | ✓ | +| JOIN_CONDITION_ALL | | + +## Supported Literals + +| Literal | Supported | +| ------------- |:---------:| +| NULL | ✓ | +| BOOL | ✓ | +| DATE | ✓ | +| TIMESTAMP | ✓ | +| TIMESTAMP_UTC | ✓ | +| DOUBLE | ✓ | +| EXACTNUMERIC | ✓ | +| STRING | ✓ | +| INTERVAL | | + +## Supported Predicates + +| Predicate | Supported | +| ------------ |:---------:| +| AND | ✓ | +| OR | ✓ | +| NOT | ✓ | +| EQUAL | ✓ | +| NOTEQUAL | ✓ | +| LESS | ✓ | +| LESSEQUAL | ✓ | +| LIKE | ✓ | +| LIKE_ESCAPE | ✓ | +| REGEXP_LIKE | ✓ | +| BETWEEN | ✓ | +| IN_CONSTLIST | ✓ | +| IS_NULL | ✓ | +| IS_NOT_NULL | ✓ | +| IS_JSON | | +| IS_NOT_JSON | | + +## Supported Aggregate Functions + +| Aggregate Function | Supported | +| ---------------------------- |:---------:| +| COUNT | ✓ | +| COUNT_STAR | ✓ | +| COUNT_DISTINCT | ✓ | +| COUNT_TUPLE | | +| SUM | ✓ | +| SUM_DISTINCT | ✓ | +| MIN | ✓ | +| MAX | ✓ | +| AVG | ✓ | +| AVG_DISTINCT | ✓ | +| MEDIAN | ✓ | +| FIRST_VALUE | ✓ | +| LAST_VALUE | ✓ | +| STDDEV | ✓ | +| STDDEV_DISTINCT | ✓ | +| STDDEV_POP | ✓ | +| STDDEV_POP_DISTINCT | ✓ | +| STDDEV_SAMP | ✓ | +| STDDEV_SAMP_DISTINCT | ✓ | +| VARIANCE | ✓ | +| VARIANCE_DISTINCT | ✓ | +| VAR_POP | ✓ | +| VAR_POP_DISTINCT | ✓ | +| VAR_SAMP | ✓ | +| VAR_SAMP_DISTINCT | ✓ | +| GROUP_CONCAT | ✓ | +| GROUP_CONCAT_DISTINCT | | +| GROUP_CONCAT_SEPARATOR | | +| GROUP_CONCAT_ORDER_BY | | +| GEO_INTERSECTION_AGGREGATE | | +| GEO_UNION_AGGREGATE | | +| ST_INTERSECTION | | +| ST_UNION | | +| APPROXIMATE_COUNT_DISTINCT | | +| MUL | | +| MUL_DISTINCT | | +| EVERY | | +| SOME | | +| LISTAGG | | +| LISTAGG_DISTINCT | | +| LISTAGG_SEPARATOR | | +| LISTAGG_ON_OVERFLOW_ERROR | | +| LISTAGG_ON_OVERFLOW_TRUNCATE | | +| LISTAGG_ORDER_BY | | + +## Supported Scalar Functions + +| Scalar Function | Supported | +| ------------------- |:---------:| +| ADD | ✓ | +| SUB | ✓ | +| MULT | ✓ | +| FLOAT_DIV | ✓ | +| NEG | ✓ | +| ABS | ✓ | +| ACOS | ✓ | +| ASIN | ✓ | +| ATAN | ✓ | +| ATAN2 | ✓ | +| CEIL | ✓ | +| COS | ✓ | +| COSH | ✓ | +| COT | ✓ | +| DEGREES | ✓ | +| DIV | ✓ | +| EXP | ✓ | +| FLOOR | ✓ | +| GREATEST | ✓ | +| LEAST | ✓ | +| LN | ✓ | +| LOG | ✓ | +| MOD | ✓ | +| POWER | ✓ | +| RADIANS | ✓ | +| RAND | ✓ | +| ROUND | | +| SIGN | ✓ | +| SIN | ✓ | +| SINH | ✓ | +| SQRT | ✓ | +| TAN | ✓ | +| TANH | ✓ | +| TRUNC | ✓ | +| ASCII | ✓ | +| BIT_LENGTH | ✓ | +| CHR | ✓ | +| COLOGNE_PHONETIC | | +| CONCAT | | +| DUMP | | +| EDIT_DISTANCE | | +| INITCAP | ✓ | +| INSERT | | +| INSTR | | +| LENGTH | ✓ | +| LOCATE | | +| LOWER | ✓ | +| LPAD | ✓ | +| LTRIM | ✓ | +| OCTET_LENGTH | ✓ | +| REGEXP_INSTR | | +| REGEXP_REPLACE | ✓ | +| REGEXP_SUBSTR | | +| REPEAT | ✓ | +| REPLACE | ✓ | +| REVERSE | ✓ | +| RIGHT | ✓ | +| RPAD | ✓ | +| RTRIM | ✓ | +| SOUNDEX | | +| SPACE | | +| SUBSTR | ✓ | +| TRANSLATE | ✓ | +| TRIM | ✓ | +| UNICODE | | +| UNICODECHR | | +| UPPER | ✓ | +| ADD_DAYS | ✓ | +| ADD_HOURS | ✓ | +| ADD_MINUTES | ✓ | +| ADD_MONTHS | ✓ | +| ADD_SECONDS | ✓ | +| ADD_WEEKS | ✓ | +| ADD_YEARS | ✓ | +| CONVERT_TZ | | +| CURRENT_DATE | ✓ | +| CURRENT_TIMESTAMP | ✓ | +| DATE_TRUNC | ✓ | +| DAY | ✓ | +| DAYS_BETWEEN | | +| DBTIMEZONE | | +| EXTRACT | ✓ | +| FROM_POSIX_TIME | | +| HOUR | | +| HOURS_BETWEEN | | +| LOCALTIMESTAMP | ✓ | +| MINUTE | ✓ | +| MINUTES_BETWEEN | | +| MONTH | ✓ | +| MONTHS_BETWEEN | | +| NUMTODSINTERVAL | | +| NUMTOYMINTERVAL | | +| POSIX_TIME | | +| SECOND | | +| SECONDS_BETWEEN | | +| SESSIONTIMEZONE | | +| SYSDATE | | +| SYSTIMESTAMP | | +| WEEK | ✓ | +| YEAR | ✓ | +| YEARS_BETWEEN | | +| ST_X | | +| ST_Y | | +| ST_ENDPOINT | | +| ST_ISCLOSED | | +| ST_ISRING | | +| ST_LENGTH | | +| ST_NUMPOINTS | | +| ST_POINTN | | +| ST_STARTPOINT | | +| ST_AREA | | +| ST_EXTERIORRING | | +| ST_INTERIORRINGN | | +| ST_NUMINTERIORRINGS | | +| ST_GEOMETRYN | | +| ST_NUMGEOMETRIES | | +| ST_BOUNDARY | | +| ST_BUFFER | | +| ST_CENTROID | | +| ST_CONTAINS | | +| ST_CONVEXHULL | | +| ST_CROSSES | | +| ST_DIFFERENCE | | +| ST_DIMENSION | | +| ST_DISJOINT | | +| ST_DISTANCE | | +| ST_ENVELOPE | | +| ST_EQUALS | | +| ST_FORCE2D | | +| ST_GEOMETRYTYPE | | +| ST_INTERSECTION | | +| ST_INTERSECTS | | +| ST_ISEMPTY | | +| ST_ISSIMPLE | | +| ST_OVERLAPS | | +| ST_SETSRID | | +| ST_SYMDIFFERENCE | | +| ST_TOUCHES | | +| ST_TRANSFORM | | +| ST_UNION | | +| ST_WITHIN | | +| CAST | | +| IS_NUMBER | | +| IS_BOOLEAN | | +| IS_DATE | | +| IS_DSINTERVAL | | +| IS_YMINTERVAL | | +| IS_TIMESTAMP | | +| TO_CHAR | | +| TO_DATE | | +| TO_DSINTERVAL | | +| TO_YMINTERVAL | | +| TO_NUMBER | | +| TO_TIMESTAMP | | +| BIT_AND | | +| BIT_CHECK | | +| BIT_LROTATE | | +| BIT_LSHIFT | | +| BIT_NOT | | +| BIT_OR | | +| BIT_RROTATE | | +| BIT_RSHIFT | | +| BIT_SET | | +| BIT_TO_NUM | | +| BIT_XOR | | +| CASE | ✓ | +| CURRENT_SCHEMA | ✓ | +| CURRENT_SESSION | | +| CURRENT_STATEMENT | | +| CURRENT_USER | | +| HASH_MD5 | ✓ | +| HASHTYPE_MD5 | | +| HASH_SHA1 | | +| HASHTYPE_SHA1 | | +| HASH_SHA256 | | +| HASHTYPE_SHA256 | | +| HASH_SHA512 | | +| HASHTYPE_SHA512 | | +| HASH_TIGER | | +| HASHTYPE_TIGER | | +| NULLIFZERO | | +| SYS_GUID | | +| ZEROIFNULL | | +| JSON_VALUE | | +| SESSION_PARAMETER | ✓ | +| MIN_SCALE | | +| TYPEOF | ✓ | +| CURRENT_CLUSTER | ✓ | + diff --git a/doc/user_guide/snowflake_user_guide.md b/doc/user_guide/snowflake_user_guide.md new file mode 100644 index 0000000..1c54651 --- /dev/null +++ b/doc/user_guide/snowflake_user_guide.md @@ -0,0 +1,112 @@ +# Snowflake SQL Dialect User Guide + +[Snowflake](https://www.snowflake.com/) operates a platform that provides data storage via cloud computing and allows for data analysis. + +## Uploading the JDBC Driver to Exasol BucketFS + +1. Download the [SnowflakeJDBC driver](https://docs.snowflake.com/en/developer-guide/jdbc/jdbc-download). + +2. Upload the driver to BucketFS, see [BucketFS documentation](https://docs.exasol.com/db/latest/administration/on-premise/bucketfs/accessfiles.htm). + + Hint: Put the driver into folder `default/drivers/jdbc/` to register it for [ExaLoader](#registering-the-jdbc-driver-for-exaloader), too. + +## Registering the JDBC driver for ExaLoader + +In order to enable the ExaLoader to fetch data from the external database you must register the driver for ExaLoader as described in the [Installation procedure for JDBC drivers](https://github.com/exasol/docker-db/#installing-custom-jdbc-drivers). +1. ExaLoader expects the driver in BucketFS folder `default/drivers/jdbc`.
+ If you uploaded the driver for UDF to a different folder, then you need to [upload](#uploading-the-jdbc-driver-to-exasol-bucketfs) the driver again. +2. Additionally, you need to create file `settings.cfg` and [upload](#uploading-the-jdbc-driver-to-exasol-bucketfs) it to the same folder in BucketFS. Contents below: + +``` +DRIVERNAME=SNOWFLAKE_JDBC_DRIVER +JAR= +DRIVERMAIN=net.snowflake.client.jdbc.SnowflakeDriver +PREFIX=jdbc:snowflake: +FETCHSIZE=100000 +INSERTSIZE=-1 +NOSECURITY=YES + +``` +Make sure there's an empty line at the end of the `settings.cfg` file, as shown above, or it will not be properly read out, the EXALoader will display an error message. + +| Variable | Description | +|-----------------------------------------|----------------------------------| +| `` | E.g. `snowflake-jdbc-3.16.1.jar` | + +## Installing the Adapter Script + +[Upload](https://docs.exasol.com/db/latest/administration/on-premise/bucketfs/accessfiles.htm) the latest available release of [Snowflake Virtual Schema JDBC Adapter](https://github.com/exasol/snowflake-virtual-schema/releases) to Bucket FS. + +Then create a schema to hold the adapter script. + +```sql +CREATE SCHEMA ADAPTER; +``` + +The SQL statement below creates the adapter script, defines the Java class that serves as entry point and tells the UDF framework where to find the libraries (JAR files) for Virtual Schema and database driver. + +```sql +--/ +CREATE OR REPLACE JAVA ADAPTER SCRIPT ADAPTER.SNOWFLAKE_JDBC_ADAPTER AS + %scriptclass com.exasol.adapter.RequestDispatcher; + %jar /buckets///virtual-schema-dist-12.0.0-snowflake-0.1.0.jar; + %jar /buckets///drivers/jdbc/snowflake-jdbc-.jar; +/ +``` + +## Defining a Named Connection + +Define the connection to the Snowflake database as shown below. + +```sql +CREATE OR REPLACE CONNECTION SNOWFLAKE_CONNECTION +TO 'jdbc:snowflake://.snowflakecomputing.com' +USER '' +IDENTIFIED BY ''; +``` + +| Variable | Description | +|-----------------|-------------------------------------------------------------------------| +| ` + USING ADAPTER.SNOWFLAKE_JDBC_ADAPTER + WITH + CATALOG_NAME = '' + SCHEMA_NAME = '' + CONNECTION_NAME = 'SNOWFLAKE_CONNECTION'; +``` + +| Variable | Description | +|-------------------------|------------------------------------------------------------------------------------------------------| +| `` | Name of the virtual schema you want to use. | +| `` | Name of the catalog, usually equivalent to the name of the Snowflake database. Please use UPPERCASE. | +| `` | Name of the database schema you want to use in the Snowflake database. Please use UPPERCASE. | + + +For additional parameters (optional), see also [Adapter Properties for JDBC-Based Virtual Schemas](https://github.com/exasol/virtual-schema-common-jdbc#adapter-properties-for-jdbc-based-virtual-schemas). + +## Data Types Conversion + +| Snowflake Data Type | Supported | Converted Exasol Data Type | Known limitations | +|------------------------------------------------------------------------------------------------|-----------|----------------------------|-------------------------------------| +| NUMBER,DECIMAL , DEC , NUMERIC | ✓ | DECIMAL(36,0) | Precision > 36 is not supported. | +| INT , INTEGER , BIGINT , SMALLINT , TINYINT , BYTEINT | ✓ | VARCHAR(2000000) | Alias for NUMBER(38,0) in Snowflake | +| BOOLEAN | ✓ | BOOLEAN | | +| VARCHAR,CHAR, CHARACTER, NCHAR, STRING, TEXT, NVARCHAR, NVARCHAR2, CHAR VARYING, NCHAR VARYING | ✓ | VARCHAR | | +| DATE | ✓ | DATE | | +| FLOAT,DOUBLE PRECISION,DOUBLE , REAL | ✓ | DOUBLE | | +| TIME | ✓ | TIME | | +| TIMESTAMP | ✓ | TIMESTAMP | | +| TIMESTAMP WITH TIME ZONE | ✓ | TIMESTAMP (UTC) | | \ No newline at end of file diff --git a/error_code_config.yml b/error_code_config.yml new file mode 100644 index 0000000..71b9803 --- /dev/null +++ b/error_code_config.yml @@ -0,0 +1,6 @@ +error-tags: + VSSF: + packages: + - com.exasol.adapter.dialects.snowflake + - com.exasol.closeafterall + highest-index: 9 diff --git a/pk_generated_parent.pom b/pk_generated_parent.pom new file mode 100644 index 0000000..eeaf0cf --- /dev/null +++ b/pk_generated_parent.pom @@ -0,0 +1,380 @@ + + + 4.0.0 + com.exasol + snowflake-virtual-schema-generated-parent + 0.1.0 + pom + + UTF-8 + UTF-8 + 11 + exasol + https://sonarcloud.io + + + + + MIT License + https://github.com/exasol/snowflake-virtual-schema/blob/main/LICENSE + repo + + + + + Exasol + opensource@exasol.com + Exasol AG + https://www.exasol.com/ + + + + scm:git:https://github.com/exasol/snowflake-virtual-schema.git + scm:git:https://github.com/exasol/snowflake-virtual-schema.git + https://github.com/exasol/snowflake-virtual-schema/ + + + + org.jacoco + org.jacoco.agent + 0.8.12 + test + runtime + + + + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 4.0.0.4121 + + + org.apache.maven.plugins + maven-toolchains-plugin + 3.2.0 + + + + toolchain + + + + + + + ${java.version} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + ${java.version} + ${java.version} + true + + -Xlint:all + -Werror + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 3.5.0 + + + enforce-maven + + enforce + + + + + 3.6.3 + + + 17 + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.6.0 + + true + oss + + + + flatten + process-resources + + flatten + + + + flatten.clean + clean + + clean + + + + + + org.sonatype.ossindex.maven + ossindex-maven-plugin + 3.2.0 + + + audit + package + + audit + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 3.2.5 + + + -Djava.util.logging.config.file=src/test/resources/logging.properties ${argLine} + ${test.excludeTags} + + + + org.codehaus.mojo + versions-maven-plugin + 2.16.2 + + + display-updates + package + + display-plugin-updates + display-dependency-updates + + + + + file:///${project.basedir}/versionsMavenPluginRules.xml + false + true + true + true + false + true + true + true + false + true + true + + + + org.basepom.maven + duplicate-finder-maven-plugin + 2.0.1 + + + default + verify + + check + + + + + true + true + true + true + true + true + false + true + false + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.7.1 + + + src/assembly/all-dependencies.xml + + NAME_OF_YOUR_JAR + false + + + true + + + + + + make-assembly + package + + single + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.4.1 + + + default-jar + none + + + + + com.exasol + artifact-reference-checker-maven-plugin + 0.4.2 + + + verify + + verify + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.1 + + + copy-jacoco + + copy-dependencies + + compile + + org.jacoco.agent + runtime + ${project.build.directory}/jacoco-agent + true + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 3.2.5 + + + -Djava.util.logging.config.file=src/test/resources/logging.properties ${argLine} + + true + + ${test.excludeTags} + + + + verify + + integration-test + verify + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.12 + + + prepare-agent + + prepare-agent + + + + prepare-agent-integration + + prepare-agent-integration + + + + merge-results + verify + + merge + + + + + ${project.build.directory}/ + + jacoco*.exec + + + + ${project.build.directory}/aggregate.exec + + + + report + verify + + report + + + ${project.build.directory}/aggregate.exec + + + + + + com.exasol + error-code-crawler-maven-plugin + 2.0.3 + + + verify + + verify + + + + + + io.github.zlika + reproducible-build-maven-plugin + 0.16 + + + strip-jar + package + + strip-jar + + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8833b42 --- /dev/null +++ b/pom.xml @@ -0,0 +1,194 @@ + + + 4.0.0 + snowflake-virtual-schema + 0.1.0 + Virtual Schema for Snowflake + Virtual Schema for connecting Snowflake as data source to Exasol + https://github.com/exasol/snowflake-virtual-schema/ + + 12.0.0 + 1.19.4 + + + + com.exasol + virtual-schema-common-jdbc + ${vscjdbc.version} + + + com.exasol + error-reporting-java + 1.0.1 + + + net.snowflake + snowflake-jdbc + 3.16.1 + + + + org.hamcrest + hamcrest + 2.2 + test + + + org.junit.jupiter + junit-jupiter + 5.10.1 + test + + + org.mockito + mockito-junit-jupiter + 5.10.0 + test + + + + com.exasol + virtual-schema-common-jdbc + ${vscjdbc.version} + test-jar + test + + + com.exasol + exasol-testcontainers + 7.1.1 + test + + + org.testcontainers + junit-jupiter + ${org.testcontainers.version} + test + + + com.exasol + test-db-builder-java + 3.5.3 + test + + + com.exasol + hamcrest-resultset-matcher + 1.6.4 + test + + + com.exasol + udf-debugging-java + 0.6.11 + test + + + net.steppschuh.markdowngenerator + markdowngenerator + 1.3.1.1 + test + + + com.exasol + autogenerated-resource-verifier-java + 0.1.2 + test + + + com.exasol + virtual-schema-shared-integration-tests + 3.0.0 + test + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -Xlint:all,-path + -Werror + + + + + org.apache.maven.plugins + maven-assembly-plugin + + virtual-schema-dist-${vscjdbc.version}-snowflake-${project.version} + + + + com.exasol + project-keeper-maven-plugin + 4.3.3 + + + + verify + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-snowflake-driver + + copy-dependencies + + compile + + net.snowflake + snowflake-jdbc + ${project.build.directory}/snowflake-driver + true + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + validate-capabilities-report + + java + + package + + com.exasol.adapter.dialects.snowflake.docgeneration.SnowflakeAutogeneratedResourceVerifier + test + + + projectDir + ${project.basedir} + + + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + false + + + + + + snowflake-virtual-schema-generated-parent + com.exasol + 0.1.0 + pk_generated_parent.pom + + diff --git a/src/assembly/all-dependencies.xml b/src/assembly/all-dependencies.xml new file mode 100644 index 0000000..efe5abc --- /dev/null +++ b/src/assembly/all-dependencies.xml @@ -0,0 +1,22 @@ + + all-dependencies + + jar + + false + + + + metaInf-services + + + + + true + runtime + / + + + diff --git a/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeColumnMetadataReader.java b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeColumnMetadataReader.java new file mode 100644 index 0000000..da65283 --- /dev/null +++ b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeColumnMetadataReader.java @@ -0,0 +1,77 @@ +package com.exasol.adapter.dialects.snowflake; + +import java.sql.*; +import java.util.logging.Logger; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.IdentifierConverter; +import com.exasol.adapter.jdbc.BaseColumnMetadataReader; +import com.exasol.adapter.jdbc.JDBCTypeDescription; +import com.exasol.adapter.metadata.DataType; + +/** + * This class implements Snowflake-specific reading of column metadata. + */ +public class SnowflakeColumnMetadataReader extends BaseColumnMetadataReader { + private static final Logger LOGGER = Logger.getLogger(SnowflakeColumnMetadataReader.class.getName()); + private static final String SNOWFLAKE_VARBIT_TYPE_NAME = "varbit"; + + /** + * Create a new instance of the {@link SnowflakeColumnMetadataReader}. + * + * @param connection JDBC connection to the remote data source + * @param properties user-defined adapter properties + * @param identifierConverter converter between source and Exasol identifiers + */ + public SnowflakeColumnMetadataReader(final Connection connection, final AdapterProperties properties, + final IdentifierConverter identifierConverter) { + super(connection, properties, identifierConverter); + } + + /** + * Get the catalog name that is applied as filter criteria when looking up remote metadata. + * + * @return catalog name or null if metadata lookups are not limited by catalog + */ + @Override + public DataType mapJdbcType(final JDBCTypeDescription jdbcTypeDescription) { + switch (jdbcTypeDescription.getJdbcType()) { + case Types.OTHER: + return mapJdbcTypeOther(jdbcTypeDescription); + case Types.SQLXML: + case Types.DISTINCT: + case Types.BINARY: + return DataType.createMaximumSizeVarChar(DataType.ExaCharset.UTF8); + case Types.TIMESTAMP_WITH_TIMEZONE: + return DataType.createTimestamp(false); + default: + return super.mapJdbcType(jdbcTypeDescription); + } + } + + private DataType mapJdbcTypeOther(final JDBCTypeDescription jdbcTypeDescription) { + if (isVarBitColumn(jdbcTypeDescription)) { + final int n = jdbcTypeDescription.getPrecisionOrSize(); + LOGGER.finest(() -> "Mapping Snowflake datatype \"OTHER:varbit\" to VARCHAR(" + n + ")"); + return DataType.createVarChar(n, DataType.ExaCharset.UTF8); + } else { + LOGGER.finest(() -> "Mapping Snowflake datatype \"" + jdbcTypeDescription.getTypeName() + + "\" to maximum VARCHAR()"); + return DataType.createMaximumSizeVarChar(DataType.ExaCharset.UTF8); + } + } + + private boolean isVarBitColumn(final JDBCTypeDescription jdbcTypeDescription) { + return jdbcTypeDescription.getTypeName().equals(SNOWFLAKE_VARBIT_TYPE_NAME); + } + + @Override + public String readColumnName(final ResultSet columns) throws SQLException { + return super.readColumnName(columns); + } + + @Override + public String getSchemaNameFilter() { + return this.properties.getSchemaName().toUpperCase(); + } +} \ No newline at end of file diff --git a/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeMetadataReader.java b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeMetadataReader.java new file mode 100644 index 0000000..3d4386f --- /dev/null +++ b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeMetadataReader.java @@ -0,0 +1,44 @@ +package com.exasol.adapter.dialects.snowflake; + +import java.sql.Connection; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.BaseIdentifierConverter; +import com.exasol.adapter.dialects.IdentifierConverter; +import com.exasol.adapter.jdbc.*; + +/** + * This class implements a reader for Snowflake-specific metadata. + */ +public class SnowflakeMetadataReader extends AbstractRemoteMetadataReader { + /** + * Create a new instance of the {@link SnowflakeMetadataReader}. + * + * @param connection connection to the Snowflake database + * @param properties user-defined adapter properties + */ + public SnowflakeMetadataReader(final Connection connection, final AdapterProperties properties) { + super(connection, properties); + } + + @Override + public BaseTableMetadataReader createTableMetadataReader() { + return new SnowflakeTableMetadataReader(this.connection, getColumnMetadataReader(), this.properties, + getIdentifierConverter()); + } + + @Override + protected IdentifierConverter createIdentifierConverter() { + return BaseIdentifierConverter.createDefault(); + } + + @Override + public ColumnMetadataReader createColumnMetadataReader() { + return new SnowflakeColumnMetadataReader(this.connection, this.properties, getIdentifierConverter()); + } + + @Override + public String getSchemaNameFilter() { + return this.properties.getSchemaName().replace("_", "\\_").toUpperCase(); + } +} \ No newline at end of file diff --git a/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialect.java b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialect.java new file mode 100644 index 0000000..4170887 --- /dev/null +++ b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialect.java @@ -0,0 +1,195 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.adapter.AdapterProperties.*; +import static com.exasol.adapter.capabilities.AggregateFunctionCapability.*; +import static com.exasol.adapter.capabilities.LiteralCapability.*; +import static com.exasol.adapter.capabilities.MainCapability.*; +import static com.exasol.adapter.capabilities.PredicateCapability.*; +import static com.exasol.adapter.capabilities.ScalarFunctionCapability.*; +import static com.exasol.adapter.capabilities.ScalarFunctionCapability.ST_INTERSECTION; +import static com.exasol.adapter.capabilities.ScalarFunctionCapability.ST_UNION; + +import java.sql.SQLException; +import java.util.*; +import java.util.function.Predicate; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.capabilities.Capabilities; +import com.exasol.adapter.capabilities.ScalarFunctionCapability; +import com.exasol.adapter.dialects.*; +import com.exasol.adapter.dialects.rewriting.ImportIntoTemporaryTableQueryRewriter; +import com.exasol.adapter.dialects.rewriting.SqlGenerationContext; +import com.exasol.adapter.jdbc.*; +import com.exasol.adapter.sql.ScalarFunction; +import com.exasol.errorreporting.ExaError; + +/** + * This class implements the Snowflake dialect. + */ +public class SnowflakeSqlDialect extends AbstractSqlDialect { + static final String NAME = "SNOWFLAKE"; + + private static final Set DISABLED_SCALAR_FUNCTION = Set.of( + /* + * `Scalar Functions` section + */ + SECONDS_BETWEEN, MINUTES_BETWEEN, HOURS_BETWEEN, DAYS_BETWEEN, MONTHS_BETWEEN, YEARS_BETWEEN, // + ROUND, // Snowflake rounds `0.5` down while Exasol rounds it up + SECOND, // It presents precision issues + COLOGNE_PHONETIC, // No Snowflake equivalent + CONCAT, // It fails for boolean data types + INSTR, // not implemented; probably possible using strpos + POSIX_TIME, // Does not follow Exasol session timezone + // Currently not implemented: + DUMP, EDIT_DISTANCE, INSERT, LOCATE, REGEXP_INSTR, REGEXP_SUBSTR, SOUNDEX, SPACE, UNICODE, UNICODECHR, + DBTIMEZONE, FROM_POSIX_TIME, HOUR, SESSIONTIMEZONE, IS_NUMBER, IS_BOOLEAN, IS_DATE, IS_DSINTERVAL, + IS_YMINTERVAL, IS_TIMESTAMP, TO_CHAR, TO_DATE, TO_NUMBER, TO_TIMESTAMP, BIT_AND, BIT_CHECK, BIT_LROTATE, + BIT_LSHIFT, BIT_NOT, BIT_OR, BIT_RROTATE, BIT_RSHIFT, BIT_SET, BIT_TO_NUM, BIT_XOR, HASHTYPE_MD5, HASH_SHA1, + HASHTYPE_SHA1, HASH_SHA256, HASHTYPE_SHA256, HASH_SHA512, HASHTYPE_SHA512, HASH_TIGER, HASHTYPE_TIGER, + NULLIFZERO, ZEROIFNULL, MIN_SCALE, NUMTOYMINTERVAL, JSON_VALUE, TO_DSINTERVAL, CONVERT_TZ, NUMTODSINTERVAL, + TO_YMINTERVAL, CAST, SYS_GUID, SYSTIMESTAMP, CURRENT_STATEMENT, CURRENT_USER, SYSDATE, CURRENT_SESSION, // + // Geospatial are currently not supported: + ST_X, ST_Y, ST_ENDPOINT, ST_ISCLOSED, ST_ISRING, ST_LENGTH, ST_NUMPOINTS, ST_POINTN, ST_STARTPOINT, ST_AREA, + ST_EXTERIORRING, ST_INTERIORRINGN, ST_NUMINTERIORRINGS, ST_GEOMETRYN, ST_NUMGEOMETRIES, ST_BOUNDARY, + ST_BUFFER, ST_CENTROID, ST_CONTAINS, ST_CONVEXHULL, ST_CROSSES, ST_DIFFERENCE, ST_DIMENSION, ST_DISJOINT, + ST_DISTANCE, ST_ENVELOPE, ST_EQUALS, ST_FORCE2D, ST_GEOMETRYTYPE, ST_INTERSECTION, ST_INTERSECTS, + ST_ISEMPTY, ST_ISSIMPLE, ST_OVERLAPS, ST_SETSRID, ST_SYMDIFFERENCE, ST_TOUCHES, ST_TRANSFORM, ST_UNION, + ST_WITHIN); + private static final Capabilities CAPABILITIES = createCapabilityList(); + static final String DATABASE_NAME_PROPERTY = "DATABASE_NAME"; + static final String ACCOUNT_NAME_PROPERTY = "ACCOUNT_NAME"; + + /* + * IMPORTANT! Before adding new capabilities, check the `doc/design.md` file if there is a note on why the + * capability is not supported. + */ + private static Capabilities createCapabilityList() { + return Capabilities.builder() + .addMain(SELECTLIST_PROJECTION, SELECTLIST_EXPRESSIONS, FILTER_EXPRESSIONS, AGGREGATE_SINGLE_GROUP, + AGGREGATE_GROUP_BY_COLUMN, AGGREGATE_GROUP_BY_EXPRESSION, AGGREGATE_GROUP_BY_TUPLE, + AGGREGATE_HAVING, ORDER_BY_COLUMN, ORDER_BY_EXPRESSION, LIMIT, LIMIT_WITH_OFFSET, JOIN, + JOIN_TYPE_INNER, JOIN_TYPE_LEFT_OUTER, JOIN_TYPE_RIGHT_OUTER, JOIN_TYPE_FULL_OUTER, + JOIN_CONDITION_EQUI) + .addPredicate(AND, OR, NOT, EQUAL, NOTEQUAL, LESS, LESSEQUAL, LIKE, LIKE_ESCAPE, BETWEEN, REGEXP_LIKE, + IN_CONSTLIST, IS_NULL, IS_NOT_NULL) + .addLiteral(BOOL, NULL, DATE, TIMESTAMP, TIMESTAMP_UTC, DOUBLE, EXACTNUMERIC, STRING) + .addAggregateFunction(COUNT, COUNT_STAR, COUNT_DISTINCT, SUM, SUM_DISTINCT, MIN, MAX, AVG, AVG_DISTINCT, + MEDIAN, FIRST_VALUE, LAST_VALUE, STDDEV, STDDEV_DISTINCT, STDDEV_POP, STDDEV_POP_DISTINCT, + STDDEV_SAMP, STDDEV_SAMP_DISTINCT, VARIANCE, VARIANCE_DISTINCT, VAR_POP, VAR_POP_DISTINCT, + VAR_SAMP, VAR_SAMP_DISTINCT, GROUP_CONCAT) + .addScalarFunction(getEnabledScalarFunctionCapabilities()).build(); + } + + /** + * Return all {@link ScalarFunctionCapability}s that are not explicitly excluded by + * {@link #DISABLED_SCALAR_FUNCTION}. + * + * @return list enabled scalar function capabilities + */ + private static ScalarFunctionCapability[] getEnabledScalarFunctionCapabilities() { + return Arrays.stream(ScalarFunctionCapability.values()) + .filter(Predicate.not(DISABLED_SCALAR_FUNCTION::contains)).toArray(ScalarFunctionCapability[]::new); + } + + /** + * Create a new instance of the {@link SnowflakeSqlDialect}. + * + * @param connectionFactory factory for the JDBC connection to the remote data source + * @param properties user-defined adapter properties + */ + public SnowflakeSqlDialect(final ConnectionFactory connectionFactory, final AdapterProperties properties) { + super(connectionFactory, properties, // + Set.of(SCHEMA_NAME_PROPERTY, CATALOG_NAME_PROPERTY, ACCOUNT_NAME_PROPERTY), // + List.of()); + } + + @Override + public String getName() { + return NAME; + } + + @Override + protected RemoteMetadataReader createRemoteMetadataReader() { + try { + return new SnowflakeMetadataReader(this.connectionFactory.getConnection(), this.properties); + } catch (final SQLException exception) { + throw new RemoteMetadataReaderException(ExaError.messageBuilder("E-VSSF-3") + .message("Unable to create Snowflake remote metadata reader. Caused by: {{cause}}", + exception.getMessage()) + .toString(), exception); + } + } + + @Override + protected QueryRewriter createQueryRewriter() { + return new ImportIntoTemporaryTableQueryRewriter(this, createRemoteMetadataReader(), this.connectionFactory); + } + + @Override + public boolean omitParentheses(final ScalarFunction function) { + return function.name().equals("CURRENT_DATE") || function.name().equals("CURRENT_TIMESTAMP") + || function.name().equals("LOCALTIMESTAMP"); + } + + @Override + public Capabilities getCapabilities() { + return CAPABILITIES; + } + + @Override + public Map getScalarFunctionAliases() { + final Map scalarAliases = new EnumMap<>(ScalarFunction.class); + scalarAliases.put(ScalarFunction.SUBSTR, "SUBSTRING"); + scalarAliases.put(ScalarFunction.HASH_MD5, "MD5"); + scalarAliases.put(ScalarFunction.RAND, "RANDOM"); + return scalarAliases; + } + + @Override + public StructureElementSupport supportsJdbcCatalogs() { + return StructureElementSupport.MULTIPLE; + } + + @Override + public StructureElementSupport supportsJdbcSchemas() { + return StructureElementSupport.MULTIPLE; + } + + @Override + public String applyQuote(String identifier) { + return super.quoteIdentifierWithDoubleQuotes(identifier); + } + + //Changing this to true fixes java.sql.SQLException: ETL-5402: JDBC-Client-Error: Failed to initialize Query: Cannot perform SELECT. This session does not have a current database. Call 'USE DATABASE', or use a qualified name. + //By using database/catalog name as a prefix. + @Override + public boolean requiresCatalogQualifiedTableNames(final SqlGenerationContext context) { + return true; + } + + @Override + public boolean requiresSchemaQualifiedTableNames(final SqlGenerationContext context) { + return true; + } + + @Override + public NullSorting getDefaultNullSorting() { + return NullSorting.NULLS_SORTED_AT_END; + } + + @Override + public SqlGenerator getSqlGenerator(final SqlGenerationContext context) { + return new SnowflakeSqlGenerationVisitor(this, context); + } + + @Override + + public String getStringLiteral(final String value) { + if (value == null) { + return "NULL"; + } + // We use an escape string constant to be independent of the parameter standard_conforming_strings. + // We use '' instead of \' to be independent of the parameter backslash_quote. + return "E'" + value.replace("\\", "\\\\").replace("'", "''") + "'"; + } +} diff --git a/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectFactory.java b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectFactory.java new file mode 100644 index 0000000..7b4aef9 --- /dev/null +++ b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectFactory.java @@ -0,0 +1,30 @@ +package com.exasol.adapter.dialects.snowflake; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.SqlDialect; +import com.exasol.adapter.dialects.SqlDialectFactory; +import com.exasol.adapter.jdbc.ConnectionFactory; +import com.exasol.logging.VersionCollector; + +/** + * Factory for the Snowflake SQL dialect. + */ +public class SnowflakeSqlDialectFactory implements SqlDialectFactory { + + @Override + public String getSqlDialectName() { + return SnowflakeSqlDialect.NAME; + } + + @Override + public SqlDialect createSqlDialect(final ConnectionFactory connectionFactory, final AdapterProperties properties) { + return new SnowflakeSqlDialect(connectionFactory, properties); + } + + @Override + public String getSqlDialectVersion() { + final VersionCollector versionCollector = new VersionCollector( + "META-INF/maven/com.exasol/virtual-schema-jdbc-adapter/pom.properties"); + return versionCollector.getVersionNumber(); + } +} \ No newline at end of file diff --git a/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlGenerationVisitor.java b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlGenerationVisitor.java new file mode 100644 index 0000000..73e06cc --- /dev/null +++ b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlGenerationVisitor.java @@ -0,0 +1,206 @@ +package com.exasol.adapter.dialects.snowflake; + +import java.util.*; + +import com.exasol.adapter.AdapterException; +import com.exasol.adapter.adapternotes.ColumnAdapterNotes; +import com.exasol.adapter.adapternotes.ColumnAdapterNotesJsonConverter; +import com.exasol.adapter.dialects.SqlDialect; +import com.exasol.adapter.dialects.rewriting.SqlGenerationContext; +import com.exasol.adapter.dialects.rewriting.SqlGenerationVisitor; +import com.exasol.adapter.metadata.ColumnMetadata; +import com.exasol.adapter.metadata.DataType; +import com.exasol.adapter.sql.*; + +/** + * This class generates SQL queries for the {@link SnowflakeSqlDialect}. + */ +public class SnowflakeSqlGenerationVisitor extends SqlGenerationVisitor { + private static final List TYPE_NAMES_NOT_SUPPORTED = List.of("bytea"); + + /** + * Create a new instance of the {@link com.exasol.adapter.dialects.snowflake.SnowflakeSqlGenerationVisitor}. + * + * @param dialect {@link SnowflakeSqlDialect} SQL dialect + * @param context SQL generation context + */ + public SnowflakeSqlGenerationVisitor(final SqlDialect dialect, final SqlGenerationContext context) { + super(dialect, context); + } + + @Override + protected String representAnyColumnInSelectList() { + return SqlConstants.ONE; + } + + @Override + public String visit(final SqlColumn column) throws AdapterException { + final String projectionString = super.visit(column); + return getColumnProjectionString(column, projectionString); + } + + private String getColumnProjectionString(final SqlColumn column, final String projectionString) + throws AdapterException { + + if (super.isDirectlyInSelectList(column)) { // + final ColumnAdapterNotesJsonConverter converter = ColumnAdapterNotesJsonConverter.getInstance(); + ColumnMetadata metaData = column.getMetadata(); + DataType mappedType = metaData.getType(); + ColumnAdapterNotes columnAdapterNotes = converter.convertFromJsonToColumnAdapterNotes(metaData.getAdapterNotes(), column.getName()); + String sourceTypeName = columnAdapterNotes.getTypeName(); + + return buildColumnProjectionString(sourceTypeName, mappedType, projectionString); + } else { + return projectionString; + } + } + + @Override + public String visit(final SqlFunctionScalar function) throws AdapterException { + final List arguments = function.getArguments(); + final List argumentsSql = new ArrayList<>(arguments.size()); + for (final SqlNode node : arguments) { + argumentsSql.add(node.accept(this)); + } + final ScalarFunction scalarFunction = function.getFunction(); + switch (scalarFunction) { + case ADD_DAYS: + return getAddDateTime(argumentsSql, "days"); + case ADD_HOURS: + return getAddDateTime(argumentsSql, "hours"); + case ADD_MINUTES: + return getAddDateTime(argumentsSql, "mins"); + case ADD_SECONDS: + return getAddDateTime(argumentsSql, "secs"); + case ADD_WEEKS: + return getAddDateTime(argumentsSql, "weeks"); + case ADD_YEARS: + return getAddDateTime(argumentsSql, "years"); + case ADD_MONTHS: + return getAddDateTime(argumentsSql, "months"); + case SECOND: + case MINUTE: + case DAY: + case WEEK: + case MONTH: + case YEAR: + return getDateTime(argumentsSql, scalarFunction); + case POSIX_TIME: + return getPosixTime(argumentsSql); + case FLOAT_DIV: + return getCastToDoublePrecisionAndDivide(argumentsSql); + default: + return super.visit(function); + } + } + + private String getCastToDoublePrecisionAndDivide(final List sqlArguments) { + return "( CAST (" + sqlArguments.get(0) + " AS DOUBLE PRECISION) / CAST (" + sqlArguments.get(1) + + " AS DOUBLE PRECISION))"; + } + + private String getAddDateTime(final List argumentsSql, final String unit) { + final StringBuilder builder = new StringBuilder(); + builder.append(argumentsSql.get(0)); + builder.append(" + "); + builder.append(buildInterval(argumentsSql, unit)); + return builder.toString(); + } + + private String buildInterval(final List argumentsSql, final String unit) { + return "make_interval(" + unit + " => " + argumentsSql.get(1) + ")"; + } + + private String getDateTime(final List argumentsSql, final ScalarFunction scalarFunction) { + final StringBuilder builder = new StringBuilder(); + builder.append("CAST(DATE_PART("); + appendDatePart(scalarFunction, builder); + builder.append(","); + builder.append(argumentsSql.get(0)); + builder.append(") AS DECIMAL("); + appendDecimalSize(scalarFunction, builder); + builder.append(",0))"); + return builder.toString(); + } + + private static void appendDatePart(ScalarFunction scalarFunction, StringBuilder builder) { + switch (scalarFunction) { + case SECOND: + builder.append("'SECOND'"); + break; + case MINUTE: + builder.append("'MINUTE'"); + break; + case DAY: + builder.append("'DAY'"); + break; + case WEEK: + builder.append("'WEEK'"); + break; + case MONTH: + builder.append("'MONTH'"); + break; + case YEAR: + builder.append("'YEAR'"); + break; + default: + break; + } + } + + private static void appendDecimalSize(ScalarFunction scalarFunction, StringBuilder builder) { + switch (scalarFunction) { + case SECOND: + case MINUTE: + case DAY: + case WEEK: + case MONTH: + builder.append("2"); + break; + case YEAR: + builder.append("4"); + break; + default: + break; + } + } + + private String getPosixTime(final List argumentsSql) { + return "EXTRACT(EPOCH FROM " + argumentsSql.get(0) + ")"; + } + + private String buildColumnProjectionString(final String typeName, DataType mappedType, final String projectionString) { + if (typeName.startsWith("NUMBER") && mappedType.getExaDataType() == DataType.ExaDataType.VARCHAR) { + return "'Number precision not supported'"; + } else if (typeName.startsWith("TIMESTAMPTZ")) { + return "TO_TIMESTAMP_NTZ(" + projectionString + ")"; + } else if (checkIfNeedToCastToVarchar(typeName)) { + return "CAST(" + projectionString + " as VARCHAR )"; + } else if (TYPE_NAMES_NOT_SUPPORTED.contains(typeName)) { + return "cast('" + typeName + " NOT SUPPORTED' as varchar) as not_supported"; + } else { + return projectionString; + } + } + + private boolean checkIfNeedToCastToVarchar(final String typeName) { + final List typesToVarcharCast = Arrays.asList("point", "line", "varbit", "lseg", "box", "path", + "polygon", "circle", "cidr", "citext", "inet", "macaddr", "interval", "json", "jsonb", "uuid", + "tsquery", "tsvector", "xml"); + return typesToVarcharCast.contains(typeName); + } + + @Override + public String visit(final SqlFunctionAggregateGroupConcat function) throws AdapterException { + final StringBuilder builder = new StringBuilder(); + builder.append("STRING_AGG"); + builder.append("("); + final String expression = function.getArgument().accept(this); + builder.append(expression); + builder.append(", "); + final String separator = function.hasSeparator() ? function.getSeparator().accept(this) : "','"; + builder.append(separator); + builder.append(") "); + return builder.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeTableMetadataReader.java b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeTableMetadataReader.java new file mode 100644 index 0000000..687403d --- /dev/null +++ b/src/main/java/com/exasol/adapter/dialects/snowflake/SnowflakeTableMetadataReader.java @@ -0,0 +1,31 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.adapter.AdapterProperties.IGNORE_ERRORS_PROPERTY; + +import java.sql.Connection; +import java.util.logging.Logger; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.IdentifierConverter; +import com.exasol.adapter.jdbc.*; +import com.exasol.errorreporting.ExaError; + +/** + * This class handles the specifics of mapping Snowflake table metadata to Exasol. + */ +public class SnowflakeTableMetadataReader extends BaseTableMetadataReader { + static final Logger LOGGER = Logger.getLogger(SnowflakeTableMetadataReader.class.getName()); + + /** + * Create a new {@link SnowflakeTableMetadataReader} instance. + * + * @param connection JDBC connection to the remote data source + * @param columnMetadataReader reader to be used to map the metadata of the tables columns + * @param properties user-defined adapter properties + * @param identifierConverter converter between source and Exasol identifiers + */ + public SnowflakeTableMetadataReader(final Connection connection, final ColumnMetadataReader columnMetadataReader, + final AdapterProperties properties, final IdentifierConverter identifierConverter) { + super(connection, columnMetadataReader, properties, identifierConverter); + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/services/com.exasol.adapter.dialects.SqlDialectFactory b/src/main/resources/META-INF/services/com.exasol.adapter.dialects.SqlDialectFactory new file mode 100644 index 0000000..0e0c9f8 --- /dev/null +++ b/src/main/resources/META-INF/services/com.exasol.adapter.dialects.SqlDialectFactory @@ -0,0 +1 @@ +com.exasol.adapter.dialects.snowflake.SnowflakeSqlDialectFactory \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/DialectTestData.java b/src/test/java/com/exasol/adapter/dialects/DialectTestData.java new file mode 100644 index 0000000..7202485 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/DialectTestData.java @@ -0,0 +1,69 @@ +package com.exasol.adapter.dialects; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import com.exasol.adapter.adapternotes.ColumnAdapterNotes; +import com.exasol.adapter.adapternotes.ColumnAdapterNotesJsonConverter; +import com.exasol.adapter.metadata.*; +import com.exasol.adapter.sql.*; + +public class DialectTestData { + + public static SqlNode getTestSqlNode() { + // SELECT USER_ID, count(URL) FROM CLICKS + // WHERE 1 < USER_ID + // GROUP BY USER_ID + // HAVING 1 < COUNT(URL) + // ORDER BY USER_ID + // LIMIT 10; + final TableMetadata clicksMeta = getClicksTableMetadata(); + final SqlTable fromClause = new SqlTable("CLICKS", clicksMeta); + final SqlSelectList selectList = SqlSelectList.createRegularSelectList( + List.of(new SqlColumn(0, clicksMeta.getColumns().get(0)), new SqlFunctionAggregate( + AggregateFunction.COUNT, List.of(new SqlColumn(1, clicksMeta.getColumns().get(1))), false))); + final SqlNode whereClause = new SqlPredicateLess(new SqlLiteralExactnumeric(BigDecimal.ONE), + new SqlColumn(0, clicksMeta.getColumns().get(0))); + final SqlExpressionList groupBy = new SqlGroupBy(List.of(new SqlColumn(0, clicksMeta.getColumns().get(0)))); + final SqlNode countUrl = new SqlFunctionAggregate(AggregateFunction.COUNT, + List.of(new SqlColumn(1, clicksMeta.getColumns().get(1))), false); + final SqlNode having = new SqlPredicateLess(new SqlLiteralExactnumeric(BigDecimal.ONE), countUrl); + final SqlOrderBy orderBy = new SqlOrderBy(List.of(new SqlColumn(0, clicksMeta.getColumns().get(0))), + List.of(true), List.of(true)); + final SqlLimit limit = new SqlLimit(10); + return SqlStatementSelect.builder().selectList(selectList).fromClause(fromClause).whereClause(whereClause) + .groupBy(groupBy).having(having).orderBy(orderBy).limit(limit).build(); + } + + public static TableMetadata getClicksTableMetadata() { + final ColumnAdapterNotesJsonConverter converter = ColumnAdapterNotesJsonConverter.getInstance(); + final List columns = new ArrayList<>(); + final ColumnAdapterNotes decimalAdapterNotes = ColumnAdapterNotes.builder() // + .jdbcDataType(3) // + .typeName("DECIMAL") // + .build(); + final ColumnAdapterNotes varcharAdapterNotes = ColumnAdapterNotes.builder() // + .jdbcDataType(12) // + .typeName("VARCHAR") // + .build(); + columns.add(ColumnMetadata.builder() // + .name("USER_ID") // + .adapterNotes(converter.convertToJson(decimalAdapterNotes)).type(DataType.createDecimal(18, 0)) // + .nullable(true) // + .identity(false) // + .defaultValue("") // + .comment("") // + .build()); + columns.add(ColumnMetadata.builder() // + .name("URL") // + .adapterNotes(converter.convertToJson(varcharAdapterNotes)) // + .type(DataType.createVarChar(10000, DataType.ExaCharset.UTF8)) // + .nullable(true) // + .identity(false) // + .defaultValue("") // + .comment("") // + .build()); + return new TableMetadata("CLICKS", "", columns, ""); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeColumnMetadataReaderTest.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeColumnMetadataReaderTest.java new file mode 100644 index 0000000..15cb163 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeColumnMetadataReaderTest.java @@ -0,0 +1,57 @@ +package com.exasol.adapter.dialects.snowflake; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import java.sql.Types; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.BaseIdentifierConverter; +import com.exasol.adapter.jdbc.JDBCTypeDescription; +import com.exasol.adapter.metadata.DataType; + +class SnowflakeColumnMetadataReaderTest { + private SnowflakeColumnMetadataReader columnMetadataReader; + private Map rawProperties; + + @BeforeEach + void beforeEach() { + this.columnMetadataReader = createDefaultSnowflakeColumnMetadataReader(); + this.rawProperties = new HashMap<>(); + } + + private SnowflakeColumnMetadataReader createDefaultSnowflakeColumnMetadataReader() { + return new SnowflakeColumnMetadataReader(null, AdapterProperties.emptyProperties(), + BaseIdentifierConverter.createDefault()); + } + + @Test + void testMapJdbcTypeOther() { + assertThat(mapJdbcType(Types.OTHER), equalTo(DataType.createMaximumSizeVarChar(DataType.ExaCharset.UTF8))); + } + + protected DataType mapJdbcType(final int type) { + final JDBCTypeDescription jdbcTypeDescription = new JDBCTypeDescription(type, 0, 0, 0, ""); + return this.columnMetadataReader.mapJdbcType(jdbcTypeDescription); + } + + @ValueSource(ints = {Types.SQLXML, Types.DISTINCT}) + @ParameterizedTest + void testMapJdbcTypeFallbackToMaxVarChar(final int type) { + assertThat(mapJdbcType(type), equalTo(DataType.createMaximumSizeVarChar(DataType.ExaCharset.UTF8))); + } + + @Test + void testMapJdbcTypeFallbackToParent() { + assertThat(mapJdbcType(Types.BOOLEAN), equalTo(DataType.createBool())); + } + + +} diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeMetadataReaderTest.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeMetadataReaderTest.java new file mode 100644 index 0000000..f484566 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeMetadataReaderTest.java @@ -0,0 +1,32 @@ +package com.exasol.adapter.dialects.snowflake; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.IdentifierCaseHandling; +import com.exasol.adapter.dialects.IdentifierConverter; + +class SnowflakeMetadataReaderTest { + private SnowflakeMetadataReader reader; + + @BeforeEach + void beforeEach() { + this.reader = new SnowflakeMetadataReader(null, AdapterProperties.emptyProperties()); + } + + @Test + void testGetTableMetadataReader() { + assertThat(this.reader.getTableMetadataReader(), instanceOf(SnowflakeTableMetadataReader.class)); + } + + @Test + void testGetColumnMetadataReader() { + assertThat(this.reader.getColumnMetadataReader(), instanceOf(SnowflakeColumnMetadataReader.class)); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectFactoryTest.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectFactoryTest.java new file mode 100644 index 0000000..2acb0f0 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectFactoryTest.java @@ -0,0 +1,30 @@ +package com.exasol.adapter.dialects.snowflake; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.MatcherAssert.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import com.exasol.adapter.AdapterProperties; + +public class SnowflakeSqlDialectFactoryTest { + private SnowflakeSqlDialectFactory factory; + + @BeforeEach + void beforeEach() { + this.factory = new SnowflakeSqlDialectFactory(); + } + + @Test + void testGetName() { + assertThat(this.factory.getSqlDialectName(), equalTo("SNOWFLAKE")); + } + + @Test + void testCreateDialect() { + assertThat(this.factory.createSqlDialect(null, AdapterProperties.emptyProperties()), + instanceOf(SnowflakeSqlDialect.class)); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectIT.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectIT.java new file mode 100644 index 0000000..5327f86 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectIT.java @@ -0,0 +1,361 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.matcher.ResultSetMatcher.matchesResultSet; +import static com.exasol.matcher.ResultSetStructureMatcher.table; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.sql.*; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.hamcrest.MatcherAssert; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtendWith; + +import com.exasol.closeafterall.CloseAfterAll; +import com.exasol.closeafterall.CloseAfterAllExtension; +import com.exasol.dbbuilder.dialects.Schema; +import com.exasol.dbbuilder.dialects.exasol.VirtualSchema; +import com.exasol.matcher.TypeMatchMode; + +@Tag("integration") +@ExtendWith({CloseAfterAllExtension.class}) +class SnowflakeSqlDialectIT { + @CloseAfterAll + private static final SnowflakeVirtualSchemaIntegrationTestSetup SETUP = new SnowflakeVirtualSchemaIntegrationTestSetup(); + private static final String SCHEMA_SNOWFLAKE = "SCHEMA_SNOWFLAKE"; + private static final String SCHEMA_SNOWFLAKE_UPPERCASE_TABLE = "SCHEMA_SNOWFLAKE_UPPER"; + private static final String TABLE_SNOWFLAKE_SIMPLE = "table_snowflake_simple"; + private static final String TABLE_SNOWFLAKE_ALL_DATA_TYPES = "table_snowflake_all_data_types"; + private static Schema exasolSchema; + private static VirtualSchema virtualSchemaSnowflake; + private static VirtualSchema virtualSchemaSnowflakeUppercaseTable; + private static final String TABLE_JOIN_1 = "TABLE_JOIN_1"; + private static final String TABLE_JOIN_2 = "TABLE_JOIN_2"; + private static VirtualSchema virtualSchemaSnowflakePreserveOriginalCase; + private static String QUALIFIED_TABLE_JOIN_NAME_1; + private static String QUALIFIED_TABLE_JOIN_NAME_2; + private static Statement statementExasol; + + @BeforeAll + static void beforeAll() throws SQLException { + final Statement statementSnowflake = SETUP.getSnowflakeStatement(); + + statementSnowflake.execute("CREATE DATABASE " + SETUP.getDatabaseName()); + statementSnowflake.execute("CREATE SCHEMA " + SCHEMA_SNOWFLAKE); + statementSnowflake.execute("CREATE SCHEMA " + SCHEMA_SNOWFLAKE_UPPERCASE_TABLE); + + createSnowflakeTestTableSimple(statementSnowflake); + createSnowflakeTestTableAllDataTypes(statementSnowflake); + createTestTablesForJoinTests(SCHEMA_SNOWFLAKE); + statementExasol = SETUP.getExasolStatement(); + virtualSchemaSnowflake = SETUP.createVirtualSchema(SCHEMA_SNOWFLAKE, Map.of()); + + QUALIFIED_TABLE_JOIN_NAME_1 = virtualSchemaSnowflake.getName() + "." + TABLE_JOIN_1; + QUALIFIED_TABLE_JOIN_NAME_2 = virtualSchemaSnowflake.getName() + "." + TABLE_JOIN_2; + exasolSchema = SETUP.getExasolFactory().createSchema("EXASOL_TEST_SCHEMA"); + } + + @AfterAll + static void afterAll() throws SQLException { + final Statement statementSnowflake = SETUP.getSnowflakeStatement(); + statementSnowflake.execute("DROP DATABASE " + SETUP.getDatabaseName() + " CASCADE;"); + } + + private static void createSnowflakeTestTableSimple(final Statement statementSnowflake) throws SQLException { + final String qualifiedTableName = SCHEMA_SNOWFLAKE + "." + TABLE_SNOWFLAKE_SIMPLE; + statementSnowflake.execute("CREATE TABLE " + qualifiedTableName + " (x NUMBER(36,0))"); + statementSnowflake.execute("INSERT INTO " + qualifiedTableName + " VALUES (1)"); + } + + // https://docs.snowflake.com/en/sql-reference/intro-summary-data-types + private static void createSnowflakeTestTableAllDataTypes(final Statement statementSnowflake) throws SQLException { + final String qualifiedTableName = SCHEMA_SNOWFLAKE + "." + TABLE_SNOWFLAKE_ALL_DATA_TYPES; + final String createAllDatatypesTableStatement = "CREATE TABLE " + qualifiedTableName // + + " (" // + + "myBigint BIGINT, " // + + "myBoolean BOOLEAN, " // + + "myCharacter CHARACTER(1000), " // ALIAS FOR NVARCHAR IN SNOWFLAKE, SAME THING, NO PADDING + + "myCharacterVar CHARACTER, " // + + "myDate DATE, " // + + "myDouble DOUBLE PRECISION, " // + + "myInteger NUMBER(36,0), " // INT(EGER) has (38,0) precision and scale in snowflake, Exasol has (36,0) as a max. The integer datatype causes problems with the EXALOADER. + + "myNumeric NUMERIC(36, 10), " // same as NUMBER IN snowflake + + "myReal REAL, " // + + "mySmallint SMALLINT, " // + + "myText TEXT, " // + + "myTime TIME, " // + // TIME WITH TIME ZONE DOES NOT EXIST IN SNOWFLAKE + + "myTimestamp TIMESTAMP, " // + + "myTimestampWithTimeZone TIMESTAMP_TZ " // TIMESTAMP WITH TIME ZONE + + ")"; + statementSnowflake.execute(createAllDatatypesTableStatement); + final String fillAllDatabaseTypesStatement = ("INSERT INTO " + qualifiedTableName + " VALUES (" // + + "10000000000, " // myBigint + + "false, " // myBoolean + + "'hajksdf', " // myCharacter + + "'h', " // myCharacterVar // + "'192.168.100.128/25'::cidr, " // myCidr + + "'2010-01-01', " // myDate + + "192189234.1723854, " // myDouble + + "7189234, " // myInteger + + "24.23, " // myNumeric + + "10.12, " // myReal + + "100, " // mySmallint + + "'This cat is super cute', " // myText + + "'11:11:11', " // myTime + + "'2010-01-01 11:11:11', " // myTimestamp + + "'2010-01-01 11:11:11 +01:00' " // myTimestampwithtimezone + + ")"); + statementSnowflake.execute(fillAllDatabaseTypesStatement); + } + + private static void createTestTablesForJoinTests(final String schemaName) throws SQLException { + final Statement statement = SETUP.getSnowflakeStatement(); + statement.execute("CREATE TABLE " + schemaName + "." + TABLE_JOIN_1 + "(x NUMBER(36,0), y VARCHAR(100))"); + statement.execute("INSERT INTO " + schemaName + "." + TABLE_JOIN_1 + " VALUES (1,'aaa')"); + statement.execute("INSERT INTO " + schemaName + "." + TABLE_JOIN_1 + " VALUES (2,'bbb')"); + statement.execute("CREATE TABLE " + schemaName + "." + TABLE_JOIN_2 + "(x NUMBER(36,0), y VARCHAR(100))"); + statement.execute("INSERT INTO " + schemaName + "." + TABLE_JOIN_2 + " VALUES (2,'bbb')"); + statement.execute("INSERT INTO " + schemaName + "." + TABLE_JOIN_2 + " VALUES (3,'ccc')"); + } + + @Test + void testSelectSingleColumn() throws SQLException { + final ResultSet actualResultSet = statementExasol + .executeQuery("SELECT * FROM " + virtualSchemaSnowflake.getName() + "." + TABLE_SNOWFLAKE_SIMPLE); + assertThat(actualResultSet, table().row(1).matches(TypeMatchMode.NO_JAVA_TYPE_CHECK)); + } + + @Test + void testInnerJoin() throws SQLException { + final String query = "SELECT * FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + " a INNER JOIN " + + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON a.x=b.x"; + final ResultSet expected = getExpectedResultSet( + List.of("x DECIMAL(36,0)", "y VARCHAR(100)", "a DECIMAL(36,0)", "b VARCHAR(100)"), // + List.of("2,'bbb', 2,'bbb'")); + final ResultSet actualResultSet = getActualResultSet(query); + assertThat(actualResultSet, matchesResultSet(expected)); + } + + @Test + void testInnerJoinWithProjection() throws SQLException { + final String query = "SELECT b.y || " + QUALIFIED_TABLE_JOIN_NAME_1 + ".y FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + + " INNER JOIN " + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON " + QUALIFIED_TABLE_JOIN_NAME_1 + ".x=b.x"; + final ResultSet expected = getExpectedResultSet(List.of("y VARCHAR(100)"), // + List.of("'bbbbbb'")); + assertThat(getActualResultSet(query), matchesResultSet(expected)); + } + + @Test + void testLeftJoin() throws SQLException { + final String query = "SELECT * FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + " a LEFT OUTER JOIN " + + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON a.x=b.x ORDER BY a.x"; + final ResultSet expected = getExpectedResultSet( + List.of("x DECIMAL(36,0)", "y VARCHAR(100)", "a DECIMAL(36,0)", "b VARCHAR(100)"), // + List.of("1, 'aaa', null, null", // + "2, 'bbb', 2, 'bbb'")); + assertThat(getActualResultSet(query), matchesResultSet(expected)); + } + + @Test + void testRightJoin() throws SQLException { + final String query = "SELECT * FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + " a RIGHT OUTER JOIN " + + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON a.x=b.x ORDER BY a.x"; + final ResultSet expected = getExpectedResultSet( + List.of("x DECIMAL(36,0)", "y VARCHAR(100)", "a DECIMAL(36,0)", "b VARCHAR(100)"), // + List.of("2, 'bbb', 2, 'bbb'", // + "null, null, 3, 'ccc'")); + assertThat(getActualResultSet(query), matchesResultSet(expected)); + } + + @Test + void testFullOuterJoin() throws SQLException { + final String query = "SELECT * FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + " a FULL OUTER JOIN " + + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON a.x=b.x ORDER BY a.x"; + final ResultSet expected = getExpectedResultSet( + List.of("x DECIMAL(36,0)", "y VARCHAR(100)", "a DECIMAL(36,0)", "b VARCHAR(100)"), // + List.of("1, 'aaa', null, null", // + "2, 'bbb', 2, 'bbb'", // + "null, null, 3, 'ccc'")); + assertThat(getActualResultSet(query), matchesResultSet(expected)); + } + + @Test + void testRightJoinWithComplexCondition() throws SQLException { + final String query = "SELECT * FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + " a RIGHT OUTER JOIN " + + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON a.x||a.y=b.x||b.y ORDER BY a.x"; + final ResultSet expected = getExpectedResultSet( + List.of("x DECIMAL(36,0)", "y VARCHAR(100)", "a DECIMAL(36,0)", "b VARCHAR(100)"), // + List.of("2, 'bbb', 2, 'bbb'", // + "null, null, 3, 'ccc'")); + assertThat(getActualResultSet(query), matchesResultSet(expected)); + } + + @Test + void testFullOuterJoinWithComplexCondition() throws SQLException { + final String query = "SELECT * FROM " + QUALIFIED_TABLE_JOIN_NAME_1 + " a FULL OUTER JOIN " + + QUALIFIED_TABLE_JOIN_NAME_2 + " b ON a.x-b.x=0 ORDER BY a.x"; + final ResultSet expected = getExpectedResultSet( + List.of("x DECIMAL(36,0)", "y VARCHAR(100)", "a DECIMAL(36,0)", "b VARCHAR(100)"), // + List.of("1, 'aaa', null, null", // + "2, 'bbb', 2, 'bbb'", // + "null, null, 3, 'ccc'")); + assertThat(getActualResultSet(query), matchesResultSet(expected)); + } + + @Test + void testYearScalarFunctionFromTimeStamp() throws SQLException { + final String query = "SELECT year(\"MYTIMESTAMP\") FROM " + virtualSchemaSnowflake.getName() + "." + + TABLE_SNOWFLAKE_ALL_DATA_TYPES; + final ResultSet actualResultSet = getActualResultSet(query); + final Short yearShort = 2010; + assertThat(actualResultSet, table().row(yearShort).matches()); + } + + @Test + void testYearScalarFunctionFromDate() throws SQLException { + final String query = "SELECT year(\"MYDATE\") FROM " + virtualSchemaSnowflake.getName() + "." + + TABLE_SNOWFLAKE_ALL_DATA_TYPES; + final ResultSet actualResultSet = getActualResultSet(query); + final Short yearShort = 2010; + assertThat(actualResultSet, table().row(yearShort).matches()); + } + + // Check 'current_schema' functionality, re-enable tests after resolution + // currently a bug in the compiler, compiler always expects 'VARCHAR(1) ASCII' see + // https://github.com/exasol/snowflake-virtual-schema/issues/79 + // https://exasol.atlassian.net/browse/SPOT-19716 + @Disabled("Currently a bug in the compiler, compiler always expects 'VARCHAR(1) ASCII'") + @Test + void testCurrentSchemaScalarFunction() throws SQLException { + final String query = " SELECT current_schema FROM " + virtualSchemaSnowflake.getName() + "." + + TABLE_SNOWFLAKE_ALL_DATA_TYPES; + final ResultSet actualResultSet = getActualResultSet(query); + assertThat(actualResultSet, table().row(TABLE_SNOWFLAKE_ALL_DATA_TYPES).matches()); + } + + @Test + void testFloatDivFunction() throws SQLException { + final String query = " SELECT MYINTEGER / MYINTEGER FROM " + virtualSchemaSnowflake.getName() + "." + + TABLE_SNOWFLAKE_ALL_DATA_TYPES; + final ResultSet actualResultSet = getActualResultSet(query); + assertThat(actualResultSet, table("DOUBLE PRECISION").row(1.0).matches()); + } + + @Test + void testCountAll() throws SQLException { + final String qualifiedExpectedTableName = virtualSchemaSnowflake.getName() + "." + TABLE_SNOWFLAKE_SIMPLE; + final String query = "SELECT COUNT(*) FROM " + qualifiedExpectedTableName; + final ResultSet actualResultSet = getActualResultSet(query); + assertThat(actualResultSet, table("BIGINT").row(1L).matches()); + } + + @Test + void testDatatypeBigint() throws SQLException { + assertSingleValue("myBigint", "VARCHAR(2000000) UTF8", "Number precision not supported"); + } + + @Test + void testDatatypeBoolean() throws SQLException { + assertSingleValue("myBoolean", "BOOLEAN", false); + } + + @Test + void testDatatypeCharacter() throws SQLException { + final String expected = "hajksdf"; + assertSingleValue("myCharacter", "VARCHAR(1000) UTF8", expected); + } + + @Test + void testDatatypeCharacterVar() throws SQLException { + assertSingleValue("myCharactervar", "VARCHAR(1000) UTF8", "h"); + } + + @Test + void testDatatypeDate() throws SQLException, ParseException { + final Date expectedDate = new SimpleDateFormat("yyyy-MM-dd").parse("2010-01-01"); + assertSingleValue("myDate", "DATE", expectedDate); + } + + @Test + void testDatatypeDouble() throws SQLException { + assertSingleValue("myDouble", "DOUBLE", "192189234.1723854"); + } + + @Test + void testDatatypeInteger() throws SQLException { + assertSingleValue("myInteger", "DECIMAL(10,0)", "7189234"); + } + + @Test + void testDatatypeNumeric() throws SQLException { + assertSingleValue("myNumeric", "VARCHAR(2000000) UTF8", 24.2300000000); + } + + @Test + void testDatatypeReal() throws SQLException { + assertSingleValue("myReal", "DOUBLE", 10.12); + } + + @Test + void testDatatypeSmallInt() throws SQLException { + assertSingleValue("mySmallint", "VARCHAR(2000000) UTF8", "Number precision not supported"); + } + + @Test + void testDatatypeText() throws SQLException { + assertSingleValue("myText", "VARCHAR(2000000) UTF8", "This cat is super cute"); + } + + @Test + void testDatatypeTime() throws SQLException { + assertSingleValue("myTime", "VARCHAR(2000000) UTF8", "1970-01-01 11:11:11.0"); + } + + @Test + void testDatatypeTimestamp() throws SQLException, ParseException { + final Timestamp expectedDate = new Timestamp( + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2010-01-01 11:11:11").getTime()); + assertSingleValue("myTimestamp", "TIMESTAMP", expectedDate); + } + + @Test + void testDatatypeTimestampWithTimezone() throws SQLException, ParseException { + final Timestamp expectedDate = new Timestamp( + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2010-01-01 11:11:11").getTime()); + assertSingleValue("myTimestampwithtimezone", "TIMESTAMP", expectedDate); + } + + private void assertSingleValue(final String columnName, final String expectedColumnType, final Object expectedValue) + throws SQLException { + final String getActualValueQuery = "SELECT " + columnName + " FROM " + virtualSchemaSnowflake.getName() + "." + + TABLE_SNOWFLAKE_ALL_DATA_TYPES; + final ResultSet actualResultSet = statementExasol.executeQuery(getActualValueQuery); + MatcherAssert.assertThat(actualResultSet, table().row(expectedValue).matches(TypeMatchMode.NO_JAVA_TYPE_CHECK)); + } + + // TODO refactor to use table().row().matches() + private ResultSet getExpectedResultSet(final List expectedColumns, final List expectedRows) + throws SQLException { + final String expectedValues = expectedRows.stream().map(row -> "(" + row + ")") + .collect(Collectors.joining(",")); + final String qualifiedExpectedTableName = exasolSchema.getName() + ".EXPECTED"; + final String createTableStatement = "CREATE OR REPLACE TABLE " + qualifiedExpectedTableName + "(" + + String.join(", ", expectedColumns) + ");"; + statementExasol.execute(createTableStatement); + final String insertIntoTableStatement = "INSERT INTO " + qualifiedExpectedTableName + " VALUES " + + expectedValues + ";"; + statementExasol.execute(insertIntoTableStatement); + final String selectStatement = "SELECT * FROM " + qualifiedExpectedTableName + ";"; + return statementExasol.executeQuery(selectStatement); + } + + private ResultSet getActualResultSet(final String query) throws SQLException { + return statementExasol.executeQuery(query); + } + +} diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectTest.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectTest.java new file mode 100644 index 0000000..522f0f1 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlDialectTest.java @@ -0,0 +1,126 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.adapter.AdapterProperties.*; +import static com.exasol.adapter.capabilities.AggregateFunctionCapability.*; +import static com.exasol.adapter.capabilities.LiteralCapability.*; +import static com.exasol.adapter.capabilities.MainCapability.*; +import static com.exasol.adapter.capabilities.PredicateCapability.*; +import static com.exasol.adapter.dialects.snowflake.SnowflakeSqlDialect.DATABASE_NAME_PROPERTY; +import static com.exasol.adapter.dialects.snowflake.SnowflakeSqlDialect.ACCOUNT_NAME_PROPERTY; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.Map; + +import org.hamcrest.CoreMatchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.capabilities.Capabilities; +import com.exasol.adapter.dialects.SqlDialect; +import com.exasol.adapter.dialects.rewriting.ImportIntoTemporaryTableQueryRewriter; +import com.exasol.adapter.jdbc.ConnectionFactory; +import com.exasol.adapter.jdbc.RemoteMetadataReaderException; +import com.exasol.adapter.properties.PropertyValidationException; + +@ExtendWith(MockitoExtension.class) +class SnowflakeSqlDialectTest { + private SnowflakeSqlDialect dialect; + @Mock + private ConnectionFactory connectionFactoryMock; + + @BeforeEach + void beforeEach() { + this.dialect = new SnowflakeSqlDialect(this.connectionFactoryMock, AdapterProperties.emptyProperties()); + } + + @Test + void testCreateRemoteMetadataReader() { + assertThat(this.dialect.createRemoteMetadataReader(), instanceOf(SnowflakeMetadataReader.class)); + } + + @Test + void testCreateRemoteMetadataReaderConnectionFails(@Mock final Connection connectionMock) throws SQLException { + when(this.connectionFactoryMock.getConnection()).thenThrow(new SQLException()); + final RemoteMetadataReaderException exception = assertThrows(RemoteMetadataReaderException.class, + this.dialect::createRemoteMetadataReader); + assertThat(exception.getMessage(), containsString("E-VSSF-3")); + } + + @Test + void testCreateQueryRewriter() { + assertThat(this.dialect.createQueryRewriter(), instanceOf(ImportIntoTemporaryTableQueryRewriter.class)); + } + + @Test + void testGetCapabilities() { + final Capabilities capabilities = this.dialect.getCapabilities(); + assertAll( + () -> assertThat(capabilities.getMainCapabilities(), + containsInAnyOrder(SELECTLIST_PROJECTION, SELECTLIST_EXPRESSIONS, FILTER_EXPRESSIONS, + AGGREGATE_SINGLE_GROUP, AGGREGATE_GROUP_BY_COLUMN, AGGREGATE_GROUP_BY_EXPRESSION, + AGGREGATE_GROUP_BY_TUPLE, AGGREGATE_HAVING, ORDER_BY_COLUMN, ORDER_BY_EXPRESSION, LIMIT, + LIMIT_WITH_OFFSET, JOIN, JOIN_TYPE_INNER, JOIN_TYPE_LEFT_OUTER, JOIN_TYPE_RIGHT_OUTER, + JOIN_TYPE_FULL_OUTER, JOIN_CONDITION_EQUI)), + () -> assertThat(capabilities.getLiteralCapabilities(), + containsInAnyOrder(BOOL, NULL, DATE, TIMESTAMP, TIMESTAMP_UTC, DOUBLE, EXACTNUMERIC, STRING)), + () -> assertThat(capabilities.getPredicateCapabilities(), + containsInAnyOrder(AND, OR, NOT, EQUAL, NOTEQUAL, LESS, LESSEQUAL, LIKE, LIKE_ESCAPE, BETWEEN, + REGEXP_LIKE, IN_CONSTLIST, IS_NULL, IS_NOT_NULL)), + () -> assertThat(capabilities.getAggregateFunctionCapabilities(), + containsInAnyOrder(COUNT, COUNT_STAR, COUNT_DISTINCT, SUM, SUM_DISTINCT, MIN, MAX, AVG, + AVG_DISTINCT, MEDIAN, FIRST_VALUE, LAST_VALUE, STDDEV, STDDEV_DISTINCT, STDDEV_POP, + STDDEV_POP_DISTINCT, STDDEV_SAMP, STDDEV_SAMP_DISTINCT, VARIANCE, VARIANCE_DISTINCT, + VAR_POP, VAR_POP_DISTINCT, VAR_SAMP, VAR_SAMP_DISTINCT, GROUP_CONCAT)) // + ); + } + + @ValueSource(strings = {"ab:E'ab'", "a'b:E'a''b'", "a''b:E'a''''b'", "'ab':E'''ab'''", "a\\\\b:E'a\\\\\\\\b'", + "a\\'b:E'a\\\\''b'"}) + @ParameterizedTest + void testGetLiteralString(final String definition) { + assertThat(this.dialect.getStringLiteral(definition.substring(0, definition.indexOf(':'))), + equalTo(definition.substring(definition.indexOf(':') + 1))); + } + + @Test + void testGetLiteralStringNull() { + assertThat(this.dialect.getStringLiteral(null), CoreMatchers.equalTo("NULL")); + } + + @Test + void testValidateDatabaseProperty() throws PropertyValidationException { + final SqlDialect sqlDialect = new SnowflakeSqlDialect(null, new AdapterProperties(Map.of( // + CONNECTION_NAME_PROPERTY, "MY_CONN", // + CATALOG_NAME_PROPERTY, "TESTDB"))); + sqlDialect.validateProperties(); + } + + @Test + void testValidateAccountProperty() throws PropertyValidationException { + final SqlDialect sqlDialect = new SnowflakeSqlDialect(null, new AdapterProperties(Map.of( // + CONNECTION_NAME_PROPERTY, "MY_CONN", // + ACCOUNT_NAME_PROPERTY, "TESTDB"))); + sqlDialect.validateProperties(); + } + + @Test + void testValidateSchemaProperty() throws PropertyValidationException { + final SqlDialect sqlDialect = new SnowflakeSqlDialect(null, new AdapterProperties(Map.of( // + CONNECTION_NAME_PROPERTY, "MY_CONN", // + SCHEMA_NAME_PROPERTY, "MY_SCHEMA"))); + sqlDialect.validateProperties(); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlGenerationVisitorTest.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlGenerationVisitorTest.java new file mode 100644 index 0000000..e3e6d99 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeSqlGenerationVisitorTest.java @@ -0,0 +1,107 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.adapter.dialects.VisitorAssertions.assertSqlNodeConvertedToOne; +import static com.exasol.adapter.sql.ScalarFunction.POSIX_TIME; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.exasol.adapter.AdapterException; +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.DialectTestData; +import com.exasol.adapter.dialects.SqlDialect; +import com.exasol.adapter.dialects.rewriting.SqlGenerationContext; +import com.exasol.adapter.jdbc.ConnectionFactory; +import com.exasol.adapter.metadata.ColumnMetadata; +import com.exasol.adapter.metadata.DataType; +import com.exasol.adapter.sql.*; + +@ExtendWith(MockitoExtension.class) +class SnowflakeSqlGenerationVisitorTest { + private SnowflakeSqlGenerationVisitor visitor; + + @BeforeEach + void beforeEach(@Mock final ConnectionFactory connectionFactoryMock) { + final SqlDialect dialect = new SnowflakeSqlDialect(connectionFactoryMock, AdapterProperties.emptyProperties()); + final SqlGenerationContext context = new SqlGenerationContext("test_catalog", "test_schema", false); + this.visitor = new SnowflakeSqlGenerationVisitor(dialect, context); + } + + @CsvSource({"ADD_DAYS, days", // + "ADD_HOURS, hours", // + "ADD_MINUTES, mins", // + "ADD_SECONDS, secs", // + "ADD_YEARS, years", // + "ADD_WEEKS, weeks", // + "ADD_MONTHS, months"}) + @ParameterizedTest + void testVisitSqlFunctionScalarAddDate(final ScalarFunction scalarFunction, final String expected) + throws AdapterException { + final SqlFunctionScalar sqlFunctionScalar = createSqlFunctionScalarForDateTest(scalarFunction, 10); + assertThat(this.visitor.visit(sqlFunctionScalar), + equalTo("\"test_column\" + make_interval(" + expected + " => 10)")); + } + + private SqlFunctionScalar createSqlFunctionScalarForDateTest(final ScalarFunction scalarFunction, + final int numericValue) { + final List arguments = new ArrayList<>(); + arguments.add(new SqlColumn(1, + ColumnMetadata.builder().name("test_column") + .adapterNotes("{\"jdbcDataType\":93, " + "\"typeName\":\"TIMESTAMP\"}") + .type(DataType.createChar(20, DataType.ExaCharset.UTF8)).build())); + arguments.add(new SqlLiteralExactnumeric(new BigDecimal(numericValue))); + return new SqlFunctionScalar(scalarFunction, arguments); + } + + @CsvSource({"SECOND, SECOND, 2", // + "MINUTE, MINUTE, 2", // + "DAY, DAY, 2", // + "WEEK, WEEK, 2", // + "MONTH, MONTH, 2", // + "YEAR, YEAR, 4"}) + @ParameterizedTest + void testVisitSqlFunctionScalarDatetime(final ScalarFunction scalarFunction, final String expected, + final String decimalSize) throws AdapterException { + final SqlFunctionScalar sqlFunctionScalar = createSqlFunctionScalarForDateTest(scalarFunction, 0); + assertThat(this.visitor.visit(sqlFunctionScalar), + equalTo("CAST(DATE_PART('" + expected + "',\"test_column\") AS DECIMAL(" + decimalSize + ",0))")); + } + + @Test + void testVisitSqlFunctionScalarPosixTime() throws AdapterException { + final SqlFunctionScalar sqlFunctionScalar = createSqlFunctionScalarForDateTest(POSIX_TIME, 0); + assertThat(this.visitor.visit(sqlFunctionScalar), equalTo("EXTRACT(EPOCH FROM \"test_column\")")); + } + + @Test + void testVisitSqlSelectListAnyValue() throws AdapterException { + final SqlSelectList sqlSelectList = SqlSelectList.createAnyValueSelectList(); + assertSqlNodeConvertedToOne(sqlSelectList, this.visitor); + } + + @Test + void testVisitSqlFunctionAggregateGroupConcat() throws AdapterException { + final SqlLiteralString argument = new SqlLiteralString("test"); + final ColumnMetadata columnMetadata = ColumnMetadata.builder().name("test_column").type(DataType.createBool()) + .build(); + final ColumnMetadata columnMetadata2 = ColumnMetadata.builder().name("test_column2") + .type(DataType.createDouble()).build(); + final List orderByArguments = List.of(new SqlColumn(1, columnMetadata), + new SqlColumn(2, columnMetadata2)); + final SqlOrderBy orderBy = new SqlOrderBy(orderByArguments, List.of(false, true), List.of(false, true)); + final SqlFunctionAggregateGroupConcat sqlFunctionAggregateGroupConcat = SqlFunctionAggregateGroupConcat + .builder(argument).separator(new SqlLiteralString("'")).orderBy(orderBy).build(); + assertThat(this.visitor.visit(sqlFunctionAggregateGroupConcat), equalTo("STRING_AGG(E'test', E'''') ")); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeTableMetadataReaderTest.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeTableMetadataReaderTest.java new file mode 100644 index 0000000..32f3682 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeTableMetadataReaderTest.java @@ -0,0 +1,35 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.adapter.AdapterProperties.IGNORE_ERRORS_PROPERTY; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import com.exasol.adapter.AdapterProperties; +import com.exasol.adapter.dialects.BaseIdentifierConverter; +import com.exasol.adapter.jdbc.RemoteMetadataReaderException; + +class SnowflakeTableMetadataReaderTest { + private Map rawProperties; + private SnowflakeTableMetadataReader reader; + + @BeforeEach + void beforeEach() { + this.rawProperties = new HashMap<>(); + final AdapterProperties properties = new AdapterProperties(this.rawProperties); + this.reader = new SnowflakeTableMetadataReader(null, null, properties, + BaseIdentifierConverter.createDefault()); + } + + private void ignoreErrors(final String ignoreErrors) { + this.rawProperties.put(IGNORE_ERRORS_PROPERTY, ignoreErrors); + } +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeVirtualSchemaIntegrationTestSetup.java b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeVirtualSchemaIntegrationTestSetup.java new file mode 100644 index 0000000..64be266 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/SnowflakeVirtualSchemaIntegrationTestSetup.java @@ -0,0 +1,216 @@ +package com.exasol.adapter.dialects.snowflake; + +import static com.exasol.dbbuilder.dialects.exasol.AdapterScript.Language.JAVA; + +import java.io.Closeable; +import java.io.FileNotFoundException; +import java.nio.file.Path; +import java.sql.*; +import java.util.*; +import java.util.concurrent.TimeoutException; + +import com.exasol.bucketfs.Bucket; +import com.exasol.bucketfs.BucketAccessException; +import com.exasol.containers.ExasolContainer; +import com.exasol.containers.ExasolService; +import com.exasol.dbbuilder.dialects.exasol.*; +import com.exasol.drivers.JdbcDriver; +import com.exasol.errorreporting.ExaError; +import com.exasol.udfdebugging.UdfTestSetup; +import com.github.dockerjava.api.model.ContainerNetwork; + +/** + * This class contains the common integration test setup for all Snowflake virtual schemas. + */ +public class SnowflakeVirtualSchemaIntegrationTestSetup implements Closeable { + private static final String VIRTUAL_SCHEMAS_JAR_NAME_AND_VERSION = "virtual-schema-dist-12.0.0-snowflake-0.1.0.jar"; + private static final Path PATH_TO_VIRTUAL_SCHEMAS_JAR = Path.of("target", VIRTUAL_SCHEMAS_JAR_NAME_AND_VERSION); + private static final String SCHEMA_EXASOL = "SCHEMA_EXASOL"; + private static final String ADAPTER_SCRIPT_EXASOL = "ADAPTER_SCRIPT_EXASOL"; + private static final String EXASOL_DOCKER_IMAGE_REFERENCE = "8.31.0"; + + private static final String JDBC_DRIVER_NAME = "snowflake-jdbc.jar"; + private static final Path JDBC_DRIVER_PATH = Path.of("target/snowflake-driver/" + JDBC_DRIVER_NAME); + + private final Statement snowflakeStatement; + private final ExasolContainer> exasolContainer = new ExasolContainer<>( + EXASOL_DOCKER_IMAGE_REFERENCE).withRequiredServices(ExasolService.BUCKETFS, ExasolService.UDF) + .withReuse(true); + private final Connection exasolConnection; + private final Statement exasolStatement; + private final AdapterScript adapterScript; + private final ConnectionDefinition connectionDefinition; + private final ExasolObjectFactory exasolFactory; + private final Connection snowflakeConnection; + private int virtualSchemaCounter = 0; + private String userName; + private String password; + private String accountName; + private String databaseName; + + public String randomDbAddendum() { + final int leftLimit = 97; // letter 'a' + final int rightLimit = 122; // letter 'z' + final int targetStringLength = 4; + final Random random = new Random(); + + return random.ints(leftLimit, rightLimit + 1).limit(targetStringLength) + .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString(); + + + } + + public String getDatabaseName() { + return databaseName; + } + + SnowflakeVirtualSchemaIntegrationTestSetup() { + try { + this.databaseName = "TESTDB" + randomDbAddendum().toUpperCase(); + this.exasolContainer.start(); + final Bucket bucket = this.exasolContainer.getDefaultBucket(); + uploadDriverToBucket(this.exasolContainer); + uploadVsJarToBucket(bucket); + this.exasolConnection = this.exasolContainer.createConnection(""); + this.exasolStatement = this.exasolConnection.createStatement(); + getTestCredentials(); + this.snowflakeConnection = getSnowflakeConnection(userName, password, accountName); + this.snowflakeStatement = snowflakeConnection.createStatement(); + final String hostIpAddress = getTestHostIpFromInsideExasol(); + assert (hostIpAddress != null); + final UdfTestSetup udfTestSetup = new UdfTestSetup(hostIpAddress, this.exasolContainer.getDefaultBucket(), + this.exasolConnection); + this.exasolFactory = new ExasolObjectFactory(this.exasolContainer.createConnection(""), + ExasolObjectConfiguration.builder().withJvmOptions(udfTestSetup.getJvmOptions()).build()); + final ExasolSchema exasolSchema = this.exasolFactory.createSchema(SCHEMA_EXASOL); + this.adapterScript = createAdapterScript(exasolSchema); + final String connectionString = getSnowflakeConnectionString(accountName); + connectionDefinition = getSnowflakeConnectionDefinition(connectionString, userName, password); + } catch (final SQLException | BucketAccessException | TimeoutException | ClassNotFoundException exception ) { + throw new IllegalStateException("Failed to created snowflake test setup.", exception); + } catch (final InterruptedException exception) { + Thread.currentThread().interrupt(); + throw new IllegalStateException("Thread was interrupted"); + } + } + + private ConnectionDefinition getSnowflakeConnectionDefinition(final String connectionString, final String username, + final String password) { + final ConnectionDefinition connectionDefinition; + connectionDefinition = this.exasolFactory.createConnectionDefinition("SNOWFLAKE_CONNECTION", connectionString, + username, password); + return connectionDefinition; + } + + private String getSnowflakeConnectionString(final String accountname) { + final String connectionString = "jdbc:snowflake://" + accountname + ".snowflakecomputing.com"; + return connectionString; + } + + private Connection getSnowflakeConnection(final String username, final String password, final String accountname) + throws SQLException, ClassNotFoundException { + Class.forName("net.snowflake.client.jdbc.SnowflakeDriver"); + // build connection properties + final Properties properties = new Properties(); + properties.put("user", username); + properties.put("password", password); + properties.put("account", accountname); + properties.put("db", this.databaseName); + properties.put("schema", "TESTSCHEMA"); + + String connectStr = "jdbc:snowflake://" + accountname + ".snowflakecomputing.com"; // replace accountName with your account name + return DriverManager.getConnection(connectStr, properties); + } + + private void getTestCredentials() { + final TestConfig testConfig = TestConfig.read(); + this.userName = testConfig.getSnowflakeUsername(); + this.password = testConfig.getSnowflakePassword(); + this.accountName = testConfig.getSnowflakeAccountname(); + } + + private static void uploadDriverToBucket(final ExasolContainer> container) + throws InterruptedException, TimeoutException, BucketAccessException { + try { + container.getDriverManager().install( // + JdbcDriver.builder("SNOWFLAKE_JDBC_DRIVER") // + .enableSecurityManager(false) // + .mainClass("net.snowflake.client.jdbc.SnowflakeDriver") // + .prefix("jdbc:snowflake:") // + .sourceFile(JDBC_DRIVER_PATH) // + .build()); + + } catch (final Exception exception) { + throw new IllegalStateException( + ExaError.messageBuilder("F-VSSF-8") + .message("An error occurred while uploading the jdbc driver to the bucket.") + .mitigation("Make sure the {{JDBC_DRIVER_PATH}} file exists.") + .parameter("JDBC_DRIVER_PATH", JDBC_DRIVER_PATH) + .mitigation("You can generate it by executing the integration test with maven.").toString(), + exception); + } + } + + private static void uploadVsJarToBucket(final Bucket bucket) { + try { + bucket.uploadFile(PATH_TO_VIRTUAL_SCHEMAS_JAR, VIRTUAL_SCHEMAS_JAR_NAME_AND_VERSION); + } catch (FileNotFoundException | BucketAccessException | TimeoutException exception) { + throw new IllegalStateException("Failed to upload jar to bucket " + bucket, exception); + } + } + + private AdapterScript createAdapterScript(final ExasolSchema schema) { + final String content = "%scriptclass com.exasol.adapter.RequestDispatcher;\n" // + + "%jar /buckets/bfsdefault/default/" + VIRTUAL_SCHEMAS_JAR_NAME_AND_VERSION + ";\n"; + return schema.createAdapterScript(ADAPTER_SCRIPT_EXASOL, JAVA, content); + } + + public Statement getSnowflakeStatement() { + return this.snowflakeStatement; + } + + public Statement getExasolStatement() { + return this.exasolStatement; + } + + public ExasolContainer> getExasolContainer() { + return this.exasolContainer; + } + + public VirtualSchema createVirtualSchema(final String forSnowflakeSchema, + final Map additionalProperties) { + final Map properties = new HashMap<>(Map.of("CATALOG_NAME", databaseName, // + "SCHEMA_NAME", forSnowflakeSchema)); // + properties.putAll(additionalProperties); + return this.exasolFactory + .createVirtualSchemaBuilder("SNOWFLAKE_VIRTUAL_SCHEMA_" + (this.virtualSchemaCounter++)) + .adapterScript(this.adapterScript).connectionDefinition(this.connectionDefinition) + .properties(properties).build(); + } + + public ExasolObjectFactory getExasolFactory() { + return this.exasolFactory; + } + + @Override + public void close() { + try { + this.exasolStatement.close(); + this.exasolConnection.close(); + this.snowflakeStatement.close(); + this.snowflakeConnection.close(); + this.exasolContainer.stop(); + } catch (final SQLException exception) { + throw new IllegalStateException("Failed to stop test setup.", exception); + } + } + + private String getTestHostIpFromInsideExasol() { + final Map networks = this.exasolContainer.getContainerInfo().getNetworkSettings() + .getNetworks(); + if (networks.size() == 0) { + return null; + } + return networks.values().iterator().next().getGateway(); + } +} diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/TestConfig.java b/src/test/java/com/exasol/adapter/dialects/snowflake/TestConfig.java new file mode 100644 index 0000000..d791be5 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/TestConfig.java @@ -0,0 +1,57 @@ +package com.exasol.adapter.dialects.snowflake; + +import java.io.*; +import java.nio.file.*; +import java.util.Properties; +import java.util.logging.Logger; + +public class TestConfig { + private static final Logger LOGGER = Logger.getLogger(TestConfig.class.getName()); + private static final Path CONFIG_FILE = Paths.get("test.properties").toAbsolutePath(); + private final Properties properties; + + private TestConfig(final Properties properties) { + this.properties = properties; + } + + public static TestConfig read() { + final Path file = CONFIG_FILE; + if (!Files.exists(file)) { + throw new IllegalStateException("Config file " + file + " does not exist."); + } + return new TestConfig(loadProperties(file)); + } + + private static Properties loadProperties(final Path configFile) { + LOGGER.info(() -> "Reading config file " + configFile); + try (InputStream stream = Files.newInputStream(configFile)) { + final Properties props = new Properties(); + props.load(stream); + return props; + } catch (final IOException exception) { + throw new UncheckedIOException("Error reading config file " + configFile, exception); + } + } + + + private String getMandatoryValue(final String param) { + if (!properties.containsKey(param)) { + throw new IllegalStateException( + "Config file " + CONFIG_FILE + " does not contain parameter '" + param + "'"); + } + return this.properties.getProperty(param); + } + + public String getSnowflakeUsername() { + return getMandatoryValue("snowflake.username"); + } + + public String getSnowflakeAccountname() { + return getMandatoryValue("snowflake.accountname"); + } + + public String getSnowflakePassword() { + return getMandatoryValue("snowflake.password"); + } + +} \ No newline at end of file diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/docgeneration/CapabilitiesReport.java b/src/test/java/com/exasol/adapter/dialects/snowflake/docgeneration/CapabilitiesReport.java new file mode 100644 index 0000000..1a03311 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/docgeneration/CapabilitiesReport.java @@ -0,0 +1,95 @@ +package com.exasol.adapter.dialects.snowflake.docgeneration; + +import java.nio.file.Path; +import java.util.Set; + +import com.exasol.adapter.capabilities.*; +import com.exasol.adapter.dialects.SqlDialect; +import com.exasol.adapter.dialects.SqlDialectFactory; +import com.exasol.autogeneratedresourceverifier.AutogeneratedResource; + +import net.steppschuh.markdowngenerator.table.Table; + +public class CapabilitiesReport implements AutogeneratedResource { + private final SqlDialectFactory dialectFactory; + + public CapabilitiesReport(final SqlDialectFactory dialectFactory) { + this.dialectFactory = dialectFactory; + } + + @Override + public String generateContent() { + final LinedStringBuilder reportBuilder = new LinedStringBuilder(); + final SqlDialect sqlDialect = this.dialectFactory.createSqlDialect(null, null); + final Capabilities capabilities = sqlDialect.getCapabilities(); + reportBuilder.appendLine( + " "); + reportBuilder.appendLine(); + reportBuilder.appendLine("# Capabilities"); + reportBuilder.appendLine(); + reportBuilder.appendLine( + "Capabilities tell the Exasol which SQL features / keywords a Virtual Schema adapter supports. " + + "If the Virtual Schema does not support a certain capability, Exasol rewrites the query without that feature. " + + "In case a Virtual Schema adapter has no capabilities at all, Exasol will rewrite all queries to `SELECT * FROM table`. " + + "That means, that it will always load the whole remote table, even if only a single row is requested." + + "So, for optimizing your performance, make sure that at least all functions that you use in the `WHERE` clause of your queries are supported by the Virtual Schema adapter."); + reportBuilder.appendLine(); + reportCapabilities("Main Capabilities", "Capability", MainCapability.values(), + capabilities.getMainCapabilities(), reportBuilder); + reportCapabilities("Supported Literals", "Literal", LiteralCapability.values(), + capabilities.getLiteralCapabilities(), reportBuilder); + reportCapabilities("Supported Predicates", "Predicate", PredicateCapability.values(), + capabilities.getPredicateCapabilities(), reportBuilder); + reportCapabilities("Supported Aggregate Functions", "Aggregate Function", AggregateFunctionCapability.values(), + capabilities.getAggregateFunctionCapabilities(), reportBuilder); + reportCapabilities("Supported Scalar Functions", "Scalar Function", ScalarFunctionCapability.values(), + capabilities.getScalarFunctionCapabilities(), reportBuilder); + return reportBuilder.toString(); + } + + @Override + public Path getPathOfGeneratedFile() { + return Path.of("doc", "generated", "capabilities.md"); + } + + private void reportCapabilities(final String headline, final String tableHeader, final T[] all, + final Set enabled, final LinedStringBuilder reportBuilder) { + reportBuilder.appendLine("## " + headline); + reportBuilder.appendLine(); + final Table.Builder tableBuilder = new Table.Builder().withAlignments(Table.ALIGN_LEFT, Table.ALIGN_CENTER) + .addRow(tableHeader, "Supported"); + for (final T function : all) { + tableBuilder.addRow(function, getEnabledText(enabled.contains(function))); + } + reportBuilder.appendLine(tableBuilder.build().toString()); + reportBuilder.appendLine(); + } + + private String getEnabledText(final boolean enabled) { + if (enabled) { + return "✓"; + } else { + return ""; + } + } + + private static class LinedStringBuilder { + private static final String LINE_SEPARATOR = System.lineSeparator(); + StringBuilder stringBuilder = new StringBuilder(); + + public LinedStringBuilder appendLine(final String line) { + this.stringBuilder.append(line).append(LINE_SEPARATOR); + return this; + } + + public LinedStringBuilder appendLine() { + this.stringBuilder.append(LINE_SEPARATOR); + return this; + } + + @Override + public String toString() { + return this.stringBuilder.toString(); + } + } +} diff --git a/src/test/java/com/exasol/adapter/dialects/snowflake/docgeneration/SnowflakeAutogeneratedResourceVerifier.java b/src/test/java/com/exasol/adapter/dialects/snowflake/docgeneration/SnowflakeAutogeneratedResourceVerifier.java new file mode 100644 index 0000000..b9e1574 --- /dev/null +++ b/src/test/java/com/exasol/adapter/dialects/snowflake/docgeneration/SnowflakeAutogeneratedResourceVerifier.java @@ -0,0 +1,11 @@ +package com.exasol.adapter.dialects.snowflake.docgeneration; + +import com.exasol.adapter.dialects.snowflake.SnowflakeSqlDialectFactory; +import com.exasol.autogeneratedresourceverifier.AutogeneratedResourceVerifier; + +public class SnowflakeAutogeneratedResourceVerifier { + + public static void main(final String[] args) { + new AutogeneratedResourceVerifier().verifyResource(new CapabilitiesReport(new SnowflakeSqlDialectFactory())); + } +} diff --git a/src/test/java/com/exasol/closeafterall/CloseAfterAll.java b/src/test/java/com/exasol/closeafterall/CloseAfterAll.java new file mode 100644 index 0000000..5548f6b --- /dev/null +++ b/src/test/java/com/exasol/closeafterall/CloseAfterAll.java @@ -0,0 +1,14 @@ +package com.exasol.closeafterall; + +import java.lang.annotation.*; + +/** + * This annotation marks a resource that should be closed after all tests were executed. + *

+ * In order to make this work you need to add the {@link CloseAfterAllExtension} to your test class. + *

+ */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface CloseAfterAll { +} diff --git a/src/test/java/com/exasol/closeafterall/CloseAfterAllExtension.java b/src/test/java/com/exasol/closeafterall/CloseAfterAllExtension.java new file mode 100644 index 0000000..2026ce4 --- /dev/null +++ b/src/test/java/com/exasol/closeafterall/CloseAfterAllExtension.java @@ -0,0 +1,48 @@ +package com.exasol.closeafterall; + +import java.io.Closeable; +import java.io.IOException; +import java.lang.reflect.Field; + +import org.junit.jupiter.api.extension.AfterAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +import com.exasol.errorreporting.ExaError; + +/** + * This JUnit extension closes resources in static fields that are annotated with {@code @CloseAfterAll}. You can use it + * by annotating your class with {@code @ExtendWith({ CloseAfterAllExtension.class })}. + */ +public class CloseAfterAllExtension implements AfterAllCallback { + + @Override + public void afterAll(final ExtensionContext extensionContext) { + final Class testClass = extensionContext.getRequiredTestClass(); + final Field[] fields = testClass.getClass().getDeclaredFields(); + for (final Field field : fields) { + closeField(testClass, field); + } + } + + private void closeField(final Class testClass, final Field field) { + if (field.isAnnotationPresent(CloseAfterAll.class)) { + field.setAccessible(true); + try { + final Object annotatedObject = field.get(null); + closeObject(field, annotatedObject); + } catch (final IllegalAccessException | IOException e) { + throw new IllegalStateException("Failed to close " + field.getName()); + } + } + } + + private void closeObject(final Field field, final Object annotatedObject) throws IOException { + if (annotatedObject instanceof Closeable) { + ((Closeable) annotatedObject).close(); + } else { + throw new IllegalStateException(ExaError.messageBuilder("E-VSSF-9").message( + "Could not close the field {{field}} annotated with @CloseAfterAll since it does not implement Closable.") + .parameter("field", field.getName()).toString()); + } + } +} diff --git a/src/test/resources/integration/scalarFunctionsParameterCache.yml b/src/test/resources/integration/scalarFunctionsParameterCache.yml new file mode 100644 index 0000000..cfeb94b --- /dev/null +++ b/src/test/resources/integration/scalarFunctionsParameterCache.yml @@ -0,0 +1,1517 @@ +abs: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +acos: ['"DOUBLE_PRECISION_C0"'] +add_hours: ['"DATE_C5", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1"'] +add_minutes: ['"DATE_C5", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1"'] +add_seconds: ['"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1"', '"DATE_C5", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2"'] +ascii: ['"VARCHAR2_C4"'] +asin: ['"DOUBLE_PRECISION_C0"'] +atan: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +atan2: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2"'] +bit_Length: ['"VARCHAR2_C4"'] +bit_length: ['"VARCHAR2_C4"'] +ceil: ['"DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2"'] +ceiling: ['"DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2"'] +char: ['"INTEGER_C1"'] +char_Length: ['"VARCHAR2_C4"'] +char_length: ['"VARCHAR2_C4"'] +character_Length: ['"VARCHAR2_C4"'] +character_length: ['"VARCHAR2_C4"'] +chr: ['"INTEGER_C1"'] +concat: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"', + '"VARCHAR2_C4"', '"DATE_C5"', '"TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "DATE_C5"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", + "BOOLEAN_C3"', '"INTEGER_C1", "VARCHAR2_C4"', '"INTEGER_C1", "DATE_C5"', '"INTEGER_C1", + "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3"', + '"DECIMAL18__3_C2", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", + "VARCHAR2_C4"', '"BOOLEAN_C3", "DATE_C5"', '"BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", "DATE_C5"', + '"VARCHAR2_C4", "TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3"', '"DATE_C5", + "VARCHAR2_C4"', '"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DATE_C5"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DATE_C5"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "VARCHAR2_C4", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "DATE_C5"', + '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "DATE_C5", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DATE_C5", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DATE_C5", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DATE_C5", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DATE_C5", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "DATE_C5", "DATE_C5"', '"DOUBLE_PRECISION_C0", "DATE_C5", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "DATE_C5"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", + "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", + "INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', + '"INTEGER_C1", "INTEGER_C1", "VARCHAR2_C4"', '"INTEGER_C1", "INTEGER_C1", "DATE_C5"', + '"INTEGER_C1", "INTEGER_C1", "TIMESTAMP_C6"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', '"INTEGER_C1", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"INTEGER_C1", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DATE_C5"', '"INTEGER_C1", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', + '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', + '"INTEGER_C1", "BOOLEAN_C3", "VARCHAR2_C4"', '"INTEGER_C1", "BOOLEAN_C3", "DATE_C5"', + '"INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', '"INTEGER_C1", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "VARCHAR2_C4", "INTEGER_C1"', '"INTEGER_C1", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"INTEGER_C1", "VARCHAR2_C4", "BOOLEAN_C3"', '"INTEGER_C1", "VARCHAR2_C4", "VARCHAR2_C4"', + '"INTEGER_C1", "VARCHAR2_C4", "DATE_C5"', '"INTEGER_C1", "VARCHAR2_C4", "TIMESTAMP_C6"', + '"INTEGER_C1", "DATE_C5", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DATE_C5", "INTEGER_C1"', + '"INTEGER_C1", "DATE_C5", "DECIMAL18__3_C2"', '"INTEGER_C1", "DATE_C5", "BOOLEAN_C3"', + '"INTEGER_C1", "DATE_C5", "VARCHAR2_C4"', '"INTEGER_C1", "DATE_C5", "DATE_C5"', + '"INTEGER_C1", "DATE_C5", "TIMESTAMP_C6"', '"INTEGER_C1", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "TIMESTAMP_C6", "INTEGER_C1"', '"INTEGER_C1", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"INTEGER_C1", "TIMESTAMP_C6", "BOOLEAN_C3"', '"INTEGER_C1", "TIMESTAMP_C6", "VARCHAR2_C4"', + '"INTEGER_C1", "TIMESTAMP_C6", "DATE_C5"', '"INTEGER_C1", "TIMESTAMP_C6", "TIMESTAMP_C6"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DATE_C5"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', + '"DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "VARCHAR2_C4"', '"DECIMAL18__3_C2", + "INTEGER_C1", "DATE_C5"', '"DECIMAL18__3_C2", "INTEGER_C1", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "VARCHAR2_C4"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DATE_C5"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "VARCHAR2_C4", "INTEGER_C1"', '"DECIMAL18__3_C2", "VARCHAR2_C4", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "VARCHAR2_C4", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "DATE_C5"', + '"DECIMAL18__3_C2", "VARCHAR2_C4", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DATE_C5", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DATE_C5", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DATE_C5", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DATE_C5", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DATE_C5", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DATE_C5", "DATE_C5"', '"DECIMAL18__3_C2", + "DATE_C5", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "TIMESTAMP_C6", "INTEGER_C1"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "TIMESTAMP_C6", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "DATE_C5"', + '"DECIMAL18__3_C2", "TIMESTAMP_C6", "TIMESTAMP_C6"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DATE_C5"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', + '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1", + "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', '"BOOLEAN_C3", + "INTEGER_C1", "DATE_C5"', '"BOOLEAN_C3", "INTEGER_C1", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "DATE_C5"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "TIMESTAMP_C6"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1"', '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "BOOLEAN_C3", "VARCHAR2_C4"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DATE_C5"', '"BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "VARCHAR2_C4", "INTEGER_C1"', + '"BOOLEAN_C3", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "VARCHAR2_C4", + "BOOLEAN_C3"', '"BOOLEAN_C3", "VARCHAR2_C4", "VARCHAR2_C4"', '"BOOLEAN_C3", "VARCHAR2_C4", + "DATE_C5"', '"BOOLEAN_C3", "VARCHAR2_C4", "TIMESTAMP_C6"', '"BOOLEAN_C3", "DATE_C5", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DATE_C5", "INTEGER_C1"', '"BOOLEAN_C3", + "DATE_C5", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DATE_C5", "BOOLEAN_C3"', '"BOOLEAN_C3", + "DATE_C5", "VARCHAR2_C4"', '"BOOLEAN_C3", "DATE_C5", "DATE_C5"', '"BOOLEAN_C3", + "DATE_C5", "TIMESTAMP_C6"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "INTEGER_C1"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "BOOLEAN_C3"', '"BOOLEAN_C3", "TIMESTAMP_C6", "VARCHAR2_C4"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "DATE_C5"', '"BOOLEAN_C3", "TIMESTAMP_C6", "TIMESTAMP_C6"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DATE_C5"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "TIMESTAMP_C6"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", "VARCHAR2_C4"', + '"VARCHAR2_C4", "INTEGER_C1", "DATE_C5"', '"VARCHAR2_C4", "INTEGER_C1", "TIMESTAMP_C6"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "DATE_C5"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "BOOLEAN_C3", "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "BOOLEAN_C3", "VARCHAR2_C4"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DATE_C5"', '"VARCHAR2_C4", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"VARCHAR2_C4", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "VARCHAR2_C4", + "INTEGER_C1"', '"VARCHAR2_C4", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", + "VARCHAR2_C4", "DATE_C5"', '"VARCHAR2_C4", "VARCHAR2_C4", "TIMESTAMP_C6"', '"VARCHAR2_C4", + "DATE_C5", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DATE_C5", "INTEGER_C1"', '"VARCHAR2_C4", + "DATE_C5", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DATE_C5", "BOOLEAN_C3"', '"VARCHAR2_C4", + "DATE_C5", "VARCHAR2_C4"', '"VARCHAR2_C4", "DATE_C5", "DATE_C5"', '"VARCHAR2_C4", + "DATE_C5", "TIMESTAMP_C6"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "INTEGER_C1"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "BOOLEAN_C3"', '"VARCHAR2_C4", "TIMESTAMP_C6", "VARCHAR2_C4"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "DATE_C5"', '"VARCHAR2_C4", "TIMESTAMP_C6", "TIMESTAMP_C6"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"DATE_C5", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "TIMESTAMP_C6"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "INTEGER_C1", "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", + "INTEGER_C1", "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "VARCHAR2_C4"', '"DATE_C5", + "INTEGER_C1", "DATE_C5"', '"DATE_C5", "INTEGER_C1", "TIMESTAMP_C6"', '"DATE_C5", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DATE_C5", "DECIMAL18__3_C2", "INTEGER_C1"', + '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DATE_C5", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DATE_C5", "DECIMAL18__3_C2", + "DATE_C5"', '"DATE_C5", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DATE_C5", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", + "VARCHAR2_C4"', '"DATE_C5", "BOOLEAN_C3", "DATE_C5"', '"DATE_C5", "BOOLEAN_C3", + "TIMESTAMP_C6"', '"DATE_C5", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "VARCHAR2_C4", "INTEGER_C1"', '"DATE_C5", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DATE_C5", + "VARCHAR2_C4", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4", "VARCHAR2_C4"', '"DATE_C5", + "VARCHAR2_C4", "DATE_C5"', '"DATE_C5", "VARCHAR2_C4", "TIMESTAMP_C6"', '"DATE_C5", + "DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", "DATE_C5", "INTEGER_C1"', '"DATE_C5", + "DATE_C5", "DECIMAL18__3_C2"', '"DATE_C5", "DATE_C5", "BOOLEAN_C3"', '"DATE_C5", + "DATE_C5", "VARCHAR2_C4"', '"DATE_C5", "DATE_C5", "DATE_C5"', '"DATE_C5", "DATE_C5", + "TIMESTAMP_C6"', '"DATE_C5", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "TIMESTAMP_C6", "INTEGER_C1"', '"DATE_C5", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"DATE_C5", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DATE_C5", "TIMESTAMP_C6", "VARCHAR2_C4"', + '"DATE_C5", "TIMESTAMP_C6", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6", "TIMESTAMP_C6"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DATE_C5"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1", "INTEGER_C1"', + '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "INTEGER_C1", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "INTEGER_C1", "DATE_C5"', '"TIMESTAMP_C6", "INTEGER_C1", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DATE_C5"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "BOOLEAN_C3", "VARCHAR2_C4"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DATE_C5"', '"TIMESTAMP_C6", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "VARCHAR2_C4", + "INTEGER_C1"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "VARCHAR2_C4", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4", "VARCHAR2_C4"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "DATE_C5"', '"TIMESTAMP_C6", "VARCHAR2_C4", "TIMESTAMP_C6"', + '"TIMESTAMP_C6", "DATE_C5", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DATE_C5", + "INTEGER_C1"', '"TIMESTAMP_C6", "DATE_C5", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "DATE_C5", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DATE_C5", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "DATE_C5", "DATE_C5"', '"TIMESTAMP_C6", "DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "INTEGER_C1"', + '"TIMESTAMP_C6", "TIMESTAMP_C6", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "TIMESTAMP_C6", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "TIMESTAMP_C6", "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "TIMESTAMP_C6"'] +cos: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +cosh: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +cot: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +curdate: [''] +current_schema_id: [''] +day: ['"DATE_C5"', '"TIMESTAMP_C6"'] +days_between: ['"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"'] +degrees: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +div: ['"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2"'] +dump: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"', + '"VARCHAR2_C4"', '"DATE_C5"', '"TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"INTEGER_C1", + "INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', + '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"INTEGER_C1", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "INTEGER_C1", + "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3", "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2"'] +exp: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +floor: ['"DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2"'] +from_posix_time: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"'] +hour: ['"DATE_C5"', '"TIMESTAMP_C6"'] +hours_between: ['"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"'] +insert: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "DATE_C5"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1", "TIMESTAMP_C6"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1", "DATE_C5"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "INTEGER_C1", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DECIMAL18__3_C2", "DATE_C5"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3", + "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3", "DATE_C5"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "INTEGER_C1", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "INTEGER_C1", "DATE_C5"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "INTEGER_C1", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DECIMAL18__3_C2", "DATE_C5"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3", + "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3", "DATE_C5"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "VARCHAR2_C4"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1", "VARCHAR2_C4"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DATE_C5"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DATE_C5"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "VARCHAR2_C4"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', '"INTEGER_C1", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"INTEGER_C1", "INTEGER_C1", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"INTEGER_C1", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', '"INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1", + "INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1", "VARCHAR2_C4"', + '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1", "DATE_C5"', '"INTEGER_C1", "INTEGER_C1", + "INTEGER_C1", "TIMESTAMP_C6"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', + '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"INTEGER_C1", + "INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2", + "VARCHAR2_C4"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2", "DATE_C5"', '"INTEGER_C1", + "INTEGER_C1", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"INTEGER_C1", "INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3", + "INTEGER_C1"', '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', '"INTEGER_C1", "INTEGER_C1", + "BOOLEAN_C3", "VARCHAR2_C4"', '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3", "DATE_C5"', + '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"INTEGER_C1", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DATE_C5"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", + "DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", "DECIMAL18__3_C2", + "INTEGER_C1", "VARCHAR2_C4"', '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1", + "DATE_C5"', '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1", "TIMESTAMP_C6"', '"INTEGER_C1", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"INTEGER_C1", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DATE_C5"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', + '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"INTEGER_C1", + "DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"INTEGER_C1", "DECIMAL18__3_C2", + "BOOLEAN_C3", "VARCHAR2_C4"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3", + "DATE_C5"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3", "TIMESTAMP_C6"', '"INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DATE_C5"', '"INTEGER_C1", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3", + "INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', + '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1", "DATE_C5"', '"INTEGER_C1", "BOOLEAN_C3", + "INTEGER_C1", "TIMESTAMP_C6"', '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', + '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"INTEGER_C1", + "BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2", + "VARCHAR2_C4"', '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2", "DATE_C5"', '"INTEGER_C1", + "BOOLEAN_C3", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"INTEGER_C1", "BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1"', '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', '"INTEGER_C1", "BOOLEAN_C3", + "BOOLEAN_C3", "VARCHAR2_C4"', '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3", "DATE_C5"', + '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1", "DATE_C5"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DECIMAL18__3_C2", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1", + "VARCHAR2_C4"', '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1", "DATE_C5"', '"DECIMAL18__3_C2", + "INTEGER_C1", "INTEGER_C1", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "INTEGER_C1", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", + "INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3", "DATE_C5"', '"DECIMAL18__3_C2", + "INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1", "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "INTEGER_C1", "VARCHAR2_C4"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "INTEGER_C1", "DATE_C5"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3", + "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3", "DATE_C5"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1", + "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "INTEGER_C1", "DATE_C5"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1", "TIMESTAMP_C6"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "BOOLEAN_C3", "BOOLEAN_C3", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "BOOLEAN_C3", "DATE_C5"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DATE_C5"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "BOOLEAN_C3"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1", "VARCHAR2_C4"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1", "DATE_C5"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "TIMESTAMP_C6"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DATE_C5"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "VARCHAR2_C4"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', + '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"BOOLEAN_C3", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', '"BOOLEAN_C3", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "INTEGER_C1", + "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1", "VARCHAR2_C4"', + '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1", "DATE_C5"', '"BOOLEAN_C3", "INTEGER_C1", + "INTEGER_C1", "TIMESTAMP_C6"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', + '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2", + "VARCHAR2_C4"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2", "DATE_C5"', '"BOOLEAN_C3", + "INTEGER_C1", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"BOOLEAN_C3", "INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3", + "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", + "BOOLEAN_C3", "VARCHAR2_C4"', '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3", "DATE_C5"', + '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DATE_C5"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "INTEGER_C1", "VARCHAR2_C4"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1", + "DATE_C5"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DATE_C5"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "BOOLEAN_C3", "VARCHAR2_C4"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3", + "DATE_C5"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DATE_C5"', '"BOOLEAN_C3", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', + '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', + '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1", "DATE_C5"', '"BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1", "TIMESTAMP_C6"', '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2", + "VARCHAR2_C4"', '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2", "DATE_C5"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"BOOLEAN_C3", "BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "BOOLEAN_C3", + "BOOLEAN_C3", "VARCHAR2_C4"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3", "DATE_C5"', + '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1", "VARCHAR2_C4"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DATE_C5"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "TIMESTAMP_C6"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DATE_C5"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "VARCHAR2_C4"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"VARCHAR2_C4", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', '"VARCHAR2_C4", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1", + "VARCHAR2_C4"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1", "DATE_C5"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1", "TIMESTAMP_C6"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', + '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", + "DECIMAL18__3_C2", "VARCHAR2_C4"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2", + "DATE_C5"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2", "TIMESTAMP_C6"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3", "VARCHAR2_C4"', '"VARCHAR2_C4", "INTEGER_C1", + "BOOLEAN_C3", "DATE_C5"', '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DATE_C5"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "INTEGER_C1", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1", + "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1", "VARCHAR2_C4"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1", "DATE_C5"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "INTEGER_C1", "TIMESTAMP_C6"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DATE_C5"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3", + "VARCHAR2_C4"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3", "DATE_C5"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"VARCHAR2_C4", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"VARCHAR2_C4", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DATE_C5"', '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "TIMESTAMP_C6"', '"VARCHAR2_C4", "BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", + "INTEGER_C1", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "BOOLEAN_C3", "INTEGER_C1", + "BOOLEAN_C3"', '"VARCHAR2_C4", "BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', '"VARCHAR2_C4", + "BOOLEAN_C3", "INTEGER_C1", "DATE_C5"', '"VARCHAR2_C4", "BOOLEAN_C3", "INTEGER_C1", + "TIMESTAMP_C6"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"VARCHAR2_C4", + "BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "BOOLEAN_C3", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2", + "VARCHAR2_C4"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2", "DATE_C5"', '"VARCHAR2_C4", + "BOOLEAN_C3", "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"VARCHAR2_C4", "BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "BOOLEAN_C3", "BOOLEAN_C3", + "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "BOOLEAN_C3", + "BOOLEAN_C3", "VARCHAR2_C4"', '"VARCHAR2_C4", "BOOLEAN_C3", "BOOLEAN_C3", "DATE_C5"', + '"VARCHAR2_C4", "BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DATE_C5", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "INTEGER_C1"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "VARCHAR2_C4"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "DATE_C5"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1", "TIMESTAMP_C6"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DATE_C5", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DATE_C5"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', + '"DATE_C5", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "VARCHAR2_C4"', '"DATE_C5", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DATE_C5"', '"DATE_C5", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DATE_C5", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DATE_C5", "INTEGER_C1", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"DATE_C5", "INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", + "INTEGER_C1", "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "INTEGER_C1", "VARCHAR2_C4"', + '"DATE_C5", "INTEGER_C1", "INTEGER_C1", "DATE_C5"', '"DATE_C5", "INTEGER_C1", "INTEGER_C1", + "TIMESTAMP_C6"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DATE_C5", + "INTEGER_C1", "DECIMAL18__3_C2", "DATE_C5"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DATE_C5", "INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', + '"DATE_C5", "INTEGER_C1", "BOOLEAN_C3", "VARCHAR2_C4"', '"DATE_C5", "INTEGER_C1", + "BOOLEAN_C3", "DATE_C5"', '"DATE_C5", "INTEGER_C1", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DATE_C5", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DATE_C5", "DECIMAL18__3_C2", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', + '"DATE_C5", "DECIMAL18__3_C2", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "DECIMAL18__3_C2", + "INTEGER_C1", "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "INTEGER_C1", "VARCHAR2_C4"', + '"DATE_C5", "DECIMAL18__3_C2", "INTEGER_C1", "DATE_C5"', '"DATE_C5", "DECIMAL18__3_C2", + "INTEGER_C1", "TIMESTAMP_C6"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "INTEGER_C1"', + '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DATE_C5", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DATE_C5"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "TIMESTAMP_C6"', + '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3", "VARCHAR2_C4"', '"DATE_C5", + "DECIMAL18__3_C2", "BOOLEAN_C3", "DATE_C5"', '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3", + "TIMESTAMP_C6"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DATE_C5"', '"DATE_C5", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', + '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3", + "INTEGER_C1", "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1", "VARCHAR2_C4"', + '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1", "DATE_C5"', '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1", + "TIMESTAMP_C6"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2", + "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"DATE_C5", + "BOOLEAN_C3", "DECIMAL18__3_C2", "DATE_C5"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', + '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3", "VARCHAR2_C4"', '"DATE_C5", "BOOLEAN_C3", + "BOOLEAN_C3", "DATE_C5"', '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3", "TIMESTAMP_C6"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DATE_C5"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "INTEGER_C1", "DATE_C5"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "INTEGER_C1", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DATE_C5"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "VARCHAR2_C4"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DATE_C5"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "BOOLEAN_C3", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0", "DATE_C5"', '"TIMESTAMP_C6", + "INTEGER_C1", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "INTEGER_C1", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1", "INTEGER_C1", + "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", + "INTEGER_C1", "VARCHAR2_C4"', '"TIMESTAMP_C6", "INTEGER_C1", "INTEGER_C1", "DATE_C5"', + '"TIMESTAMP_C6", "INTEGER_C1", "INTEGER_C1", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "INTEGER_C1", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2", + "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "INTEGER_C1", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"TIMESTAMP_C6", "INTEGER_C1", + "DECIMAL18__3_C2", "DATE_C5"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "INTEGER_C1", "BOOLEAN_C3", "DATE_C5"', '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DATE_C5"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "INTEGER_C1", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1", "VARCHAR2_C4"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1", "DATE_C5"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "INTEGER_C1", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DATE_C5"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3", + "VARCHAR2_C4"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3", "DATE_C5"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DATE_C5"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "BOOLEAN_C3", "INTEGER_C1", + "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "INTEGER_C1", "VARCHAR2_C4"', '"TIMESTAMP_C6", "BOOLEAN_C3", "INTEGER_C1", "DATE_C5"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "INTEGER_C1", "TIMESTAMP_C6"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2", + "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "DECIMAL18__3_C2", "VARCHAR2_C4"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "DECIMAL18__3_C2", "DATE_C5"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "BOOLEAN_C3", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "BOOLEAN_C3", "BOOLEAN_C3", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "BOOLEAN_C3", "BOOLEAN_C3", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "BOOLEAN_C3", "DATE_C5"', '"TIMESTAMP_C6", "BOOLEAN_C3", "BOOLEAN_C3", + "TIMESTAMP_C6"'] +instr: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", + "VARCHAR2_C4"', '"INTEGER_C1", "DATE_C5"', '"INTEGER_C1", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "VARCHAR2_C4"', '"BOOLEAN_C3", "DATE_C5"', + '"BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "BOOLEAN_C3"', + '"VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", "DATE_C5"', '"VARCHAR2_C4", "TIMESTAMP_C6"', + '"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2"', + '"DATE_C5", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4"', '"DATE_C5", "DATE_C5"', '"DATE_C5", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "VARCHAR2_C4"', '"TIMESTAMP_C6", "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "VARCHAR2_C4", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "DATE_C5", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DATE_C5", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DATE_C5", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6", "BOOLEAN_C3"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"INTEGER_C1", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', + '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", + "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"INTEGER_C1", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', '"INTEGER_C1", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "VARCHAR2_C4", "INTEGER_C1"', '"INTEGER_C1", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"INTEGER_C1", "VARCHAR2_C4", "BOOLEAN_C3"', '"INTEGER_C1", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DATE_C5", "INTEGER_C1"', '"INTEGER_C1", "DATE_C5", "DECIMAL18__3_C2"', + '"INTEGER_C1", "DATE_C5", "BOOLEAN_C3"', '"INTEGER_C1", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "TIMESTAMP_C6", "INTEGER_C1"', '"INTEGER_C1", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"INTEGER_C1", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "INTEGER_C1"', + '"DECIMAL18__3_C2", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "VARCHAR2_C4", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DATE_C5", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DATE_C5", "INTEGER_C1"', '"DECIMAL18__3_C2", "DATE_C5", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DATE_C5", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "TIMESTAMP_C6", "INTEGER_C1"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "BOOLEAN_C3"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', + '"BOOLEAN_C3", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "VARCHAR2_C4", + "INTEGER_C1"', '"BOOLEAN_C3", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "VARCHAR2_C4", "BOOLEAN_C3"', '"BOOLEAN_C3", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DATE_C5", "INTEGER_C1"', '"BOOLEAN_C3", "DATE_C5", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "DATE_C5", "BOOLEAN_C3"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "INTEGER_C1"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "BOOLEAN_C3", + "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DATE_C5", "INTEGER_C1"', '"VARCHAR2_C4", "DATE_C5", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "DATE_C5", "BOOLEAN_C3"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "INTEGER_C1"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1", + "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "VARCHAR2_C4", "INTEGER_C1"', '"DATE_C5", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"DATE_C5", "VARCHAR2_C4", "BOOLEAN_C3"', '"DATE_C5", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "DATE_C5", "INTEGER_C1"', '"DATE_C5", "DATE_C5", "DECIMAL18__3_C2"', + '"DATE_C5", "DATE_C5", "BOOLEAN_C3"', '"DATE_C5", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "TIMESTAMP_C6", "INTEGER_C1"', '"DATE_C5", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"DATE_C5", "TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "INTEGER_C1", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "INTEGER_C1"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DATE_C5", "INTEGER_C1"', '"TIMESTAMP_C6", "DATE_C5", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "DATE_C5", "BOOLEAN_C3"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "BOOLEAN_C3"'] +iproc: [''] +is_number: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"VARCHAR2_C4"'] +lcase: ['"VARCHAR2_C4"'] +left: ['"VARCHAR2_C4", "INTEGER_C1"'] +length: ['"VARCHAR2_C4"'] +ln: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +locate: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", "DATE_C5"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", + "VARCHAR2_C4"', '"INTEGER_C1", "DATE_C5"', '"INTEGER_C1", "TIMESTAMP_C6"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "VARCHAR2_C4"', + '"DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", "TIMESTAMP_C6"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", "VARCHAR2_C4"', '"BOOLEAN_C3", "DATE_C5"', + '"BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "BOOLEAN_C3"', + '"VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", "DATE_C5"', '"VARCHAR2_C4", "TIMESTAMP_C6"', + '"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2"', + '"DATE_C5", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4"', '"DATE_C5", "DATE_C5"', '"DATE_C5", + "TIMESTAMP_C6"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1"', + '"TIMESTAMP_C6", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "VARCHAR2_C4"', '"TIMESTAMP_C6", "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "VARCHAR2_C4", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "DATE_C5", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DATE_C5", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DATE_C5", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "TIMESTAMP_C6", "BOOLEAN_C3"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"INTEGER_C1", + "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', + '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DECIMAL18__3_C2", + "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"INTEGER_C1", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', '"INTEGER_C1", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "VARCHAR2_C4", "INTEGER_C1"', '"INTEGER_C1", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"INTEGER_C1", "VARCHAR2_C4", "BOOLEAN_C3"', '"INTEGER_C1", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DATE_C5", "INTEGER_C1"', '"INTEGER_C1", "DATE_C5", "DECIMAL18__3_C2"', + '"INTEGER_C1", "DATE_C5", "BOOLEAN_C3"', '"INTEGER_C1", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "TIMESTAMP_C6", "INTEGER_C1"', '"INTEGER_C1", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"INTEGER_C1", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "INTEGER_C1"', + '"DECIMAL18__3_C2", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "VARCHAR2_C4", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DATE_C5", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DATE_C5", "INTEGER_C1"', '"DECIMAL18__3_C2", "DATE_C5", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DATE_C5", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "TIMESTAMP_C6", "INTEGER_C1"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "BOOLEAN_C3"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', + '"BOOLEAN_C3", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "VARCHAR2_C4", + "INTEGER_C1"', '"BOOLEAN_C3", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "VARCHAR2_C4", "BOOLEAN_C3"', '"BOOLEAN_C3", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DATE_C5", "INTEGER_C1"', '"BOOLEAN_C3", "DATE_C5", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "DATE_C5", "BOOLEAN_C3"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "INTEGER_C1"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "BOOLEAN_C3", + "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DATE_C5", "INTEGER_C1"', '"VARCHAR2_C4", "DATE_C5", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "DATE_C5", "BOOLEAN_C3"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "INTEGER_C1"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1", + "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "VARCHAR2_C4", "INTEGER_C1"', '"DATE_C5", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"DATE_C5", "VARCHAR2_C4", "BOOLEAN_C3"', '"DATE_C5", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "DATE_C5", "INTEGER_C1"', '"DATE_C5", "DATE_C5", "DECIMAL18__3_C2"', + '"DATE_C5", "DATE_C5", "BOOLEAN_C3"', '"DATE_C5", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "TIMESTAMP_C6", "INTEGER_C1"', '"DATE_C5", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"DATE_C5", "TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "INTEGER_C1", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "INTEGER_C1"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DATE_C5", "INTEGER_C1"', '"TIMESTAMP_C6", "DATE_C5", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "DATE_C5", "BOOLEAN_C3"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "BOOLEAN_C3"'] +log: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"INTEGER_C1", + "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1"', + '"DECIMAL18__3_C2", "DECIMAL18__3_C2"'] +log10: ['"INTEGER_C1"', '"DECIMAL18__3_C2"'] +log2: ['"INTEGER_C1"', '"DECIMAL18__3_C2"'] +lower: ['"VARCHAR2_C4"'] +lpad: ['"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "VARCHAR2_C4"'] +ltrim: ['"VARCHAR2_C4"', '"VARCHAR2_C4", "VARCHAR2_C4"'] +mid: ['"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1"'] +minute: ['"DATE_C5"', '"TIMESTAMP_C6"'] +minutes_between: ['"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"'] +mod: ['"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2"'] +month: ['"DATE_C5"', '"TIMESTAMP_C6"'] +months_between: ['"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"'] +nproc: [''] +octet_Length: ['"VARCHAR2_C4"'] +octet_length: ['"VARCHAR2_C4"'] +pi: [''] +power: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2"'] +radians: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +regexp_instr: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "DATE_C5"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", + "BOOLEAN_C3"', '"INTEGER_C1", "VARCHAR2_C4"', '"INTEGER_C1", "DATE_C5"', '"INTEGER_C1", + "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3"', + '"DECIMAL18__3_C2", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", + "VARCHAR2_C4"', '"BOOLEAN_C3", "DATE_C5"', '"BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", "DATE_C5"', + '"VARCHAR2_C4", "TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3"', '"DATE_C5", + "VARCHAR2_C4"', '"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "DATE_C5", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DATE_C5", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DATE_C5", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DATE_C5", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "BOOLEAN_C3"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"INTEGER_C1", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', + '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', + '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', + '"INTEGER_C1", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "VARCHAR2_C4", + "INTEGER_C1"', '"INTEGER_C1", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"INTEGER_C1", + "VARCHAR2_C4", "BOOLEAN_C3"', '"INTEGER_C1", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DATE_C5", "INTEGER_C1"', '"INTEGER_C1", "DATE_C5", "DECIMAL18__3_C2"', + '"INTEGER_C1", "DATE_C5", "BOOLEAN_C3"', '"INTEGER_C1", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "TIMESTAMP_C6", "INTEGER_C1"', '"INTEGER_C1", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"INTEGER_C1", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "INTEGER_C1"', + '"DECIMAL18__3_C2", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "VARCHAR2_C4", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DATE_C5", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DATE_C5", "INTEGER_C1"', '"DECIMAL18__3_C2", "DATE_C5", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DATE_C5", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "TIMESTAMP_C6", "INTEGER_C1"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "BOOLEAN_C3"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', + '"BOOLEAN_C3", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "VARCHAR2_C4", + "INTEGER_C1"', '"BOOLEAN_C3", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "VARCHAR2_C4", "BOOLEAN_C3"', '"BOOLEAN_C3", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DATE_C5", "INTEGER_C1"', '"BOOLEAN_C3", "DATE_C5", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "DATE_C5", "BOOLEAN_C3"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "INTEGER_C1"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "BOOLEAN_C3", + "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DATE_C5", "INTEGER_C1"', '"VARCHAR2_C4", "DATE_C5", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "DATE_C5", "BOOLEAN_C3"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "INTEGER_C1"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1", + "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "VARCHAR2_C4", "INTEGER_C1"', '"DATE_C5", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"DATE_C5", "VARCHAR2_C4", "BOOLEAN_C3"', '"DATE_C5", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "DATE_C5", "INTEGER_C1"', '"DATE_C5", "DATE_C5", "DECIMAL18__3_C2"', + '"DATE_C5", "DATE_C5", "BOOLEAN_C3"', '"DATE_C5", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "TIMESTAMP_C6", "INTEGER_C1"', '"DATE_C5", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"DATE_C5", "TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "INTEGER_C1", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "INTEGER_C1"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DATE_C5", "INTEGER_C1"', '"TIMESTAMP_C6", "DATE_C5", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "DATE_C5", "BOOLEAN_C3"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "BOOLEAN_C3"'] +regexp_replace: ['"VARCHAR2_C4", "VARCHAR2_C4", "VARCHAR2_C4"'] +regexp_substr: ['"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4"', '"DOUBLE_PRECISION_C0", + "DATE_C5"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", + "BOOLEAN_C3"', '"INTEGER_C1", "VARCHAR2_C4"', '"INTEGER_C1", "DATE_C5"', '"INTEGER_C1", + "TIMESTAMP_C6"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3"', + '"DECIMAL18__3_C2", "VARCHAR2_C4"', '"DECIMAL18__3_C2", "DATE_C5"', '"DECIMAL18__3_C2", + "TIMESTAMP_C6"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3"', '"BOOLEAN_C3", + "VARCHAR2_C4"', '"BOOLEAN_C3", "DATE_C5"', '"BOOLEAN_C3", "TIMESTAMP_C6"', '"VARCHAR2_C4", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", "DATE_C5"', + '"VARCHAR2_C4", "TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3"', '"DATE_C5", + "VARCHAR2_C4"', '"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "INTEGER_C1", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "INTEGER_C1", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4", "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", + "DATE_C5", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", "DATE_C5", "INTEGER_C1"', + '"DOUBLE_PRECISION_C0", "DATE_C5", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "DATE_C5", + "BOOLEAN_C3"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "TIMESTAMP_C6", "BOOLEAN_C3"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"INTEGER_C1", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"INTEGER_C1", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"INTEGER_C1", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "INTEGER_C1", "INTEGER_C1"', '"INTEGER_C1", "INTEGER_C1", "DECIMAL18__3_C2"', + '"INTEGER_C1", "INTEGER_C1", "BOOLEAN_C3"', '"INTEGER_C1", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DECIMAL18__3_C2", "INTEGER_C1"', '"INTEGER_C1", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"INTEGER_C1", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"INTEGER_C1", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "BOOLEAN_C3", "INTEGER_C1"', + '"INTEGER_C1", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3", "BOOLEAN_C3"', + '"INTEGER_C1", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "VARCHAR2_C4", + "INTEGER_C1"', '"INTEGER_C1", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"INTEGER_C1", + "VARCHAR2_C4", "BOOLEAN_C3"', '"INTEGER_C1", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "DATE_C5", "INTEGER_C1"', '"INTEGER_C1", "DATE_C5", "DECIMAL18__3_C2"', + '"INTEGER_C1", "DATE_C5", "BOOLEAN_C3"', '"INTEGER_C1", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"INTEGER_C1", "TIMESTAMP_C6", "INTEGER_C1"', '"INTEGER_C1", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"INTEGER_C1", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"DECIMAL18__3_C2", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "INTEGER_C1", "INTEGER_C1"', '"DECIMAL18__3_C2", "INTEGER_C1", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", + "INTEGER_C1"', '"DECIMAL18__3_C2", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "BOOLEAN_C3", "INTEGER_C1"', '"DECIMAL18__3_C2", "BOOLEAN_C3", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "VARCHAR2_C4", "INTEGER_C1"', + '"DECIMAL18__3_C2", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "VARCHAR2_C4", + "BOOLEAN_C3"', '"DECIMAL18__3_C2", "DATE_C5", "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", + "DATE_C5", "INTEGER_C1"', '"DECIMAL18__3_C2", "DATE_C5", "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", + "DATE_C5", "BOOLEAN_C3"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DECIMAL18__3_C2", "TIMESTAMP_C6", "INTEGER_C1"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "TIMESTAMP_C6", "BOOLEAN_C3"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"BOOLEAN_C3", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "DOUBLE_PRECISION_C0", "BOOLEAN_C3"', '"BOOLEAN_C3", "INTEGER_C1", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "INTEGER_C1", "INTEGER_C1"', '"BOOLEAN_C3", "INTEGER_C1", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "INTEGER_C1", "BOOLEAN_C3"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DECIMAL18__3_C2", "INTEGER_C1"', '"BOOLEAN_C3", "DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"BOOLEAN_C3", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"BOOLEAN_C3", + "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "BOOLEAN_C3", "INTEGER_C1"', + '"BOOLEAN_C3", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"BOOLEAN_C3", "BOOLEAN_C3", "BOOLEAN_C3"', + '"BOOLEAN_C3", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', '"BOOLEAN_C3", "VARCHAR2_C4", + "INTEGER_C1"', '"BOOLEAN_C3", "VARCHAR2_C4", "DECIMAL18__3_C2"', '"BOOLEAN_C3", + "VARCHAR2_C4", "BOOLEAN_C3"', '"BOOLEAN_C3", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "DATE_C5", "INTEGER_C1"', '"BOOLEAN_C3", "DATE_C5", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "DATE_C5", "BOOLEAN_C3"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "INTEGER_C1"', '"BOOLEAN_C3", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"BOOLEAN_C3", "TIMESTAMP_C6", "BOOLEAN_C3"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"VARCHAR2_C4", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", + "INTEGER_C1", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "INTEGER_C1", "BOOLEAN_C3"', '"VARCHAR2_C4", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "INTEGER_C1"', '"VARCHAR2_C4", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"VARCHAR2_C4", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"VARCHAR2_C4", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"VARCHAR2_C4", "BOOLEAN_C3", + "INTEGER_C1"', '"VARCHAR2_C4", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"VARCHAR2_C4", + "BOOLEAN_C3", "BOOLEAN_C3"', '"VARCHAR2_C4", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "VARCHAR2_C4", "BOOLEAN_C3"', '"VARCHAR2_C4", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "DATE_C5", "INTEGER_C1"', '"VARCHAR2_C4", "DATE_C5", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "DATE_C5", "BOOLEAN_C3"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "INTEGER_C1"', '"VARCHAR2_C4", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"VARCHAR2_C4", "TIMESTAMP_C6", "BOOLEAN_C3"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"DATE_C5", "DOUBLE_PRECISION_C0", "INTEGER_C1"', '"DATE_C5", + "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DATE_C5", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"DATE_C5", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"DATE_C5", "INTEGER_C1", + "INTEGER_C1"', '"DATE_C5", "INTEGER_C1", "DECIMAL18__3_C2"', '"DATE_C5", "INTEGER_C1", + "BOOLEAN_C3"', '"DATE_C5", "DECIMAL18__3_C2", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "DECIMAL18__3_C2", "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2", "DECIMAL18__3_C2"', + '"DATE_C5", "DECIMAL18__3_C2", "BOOLEAN_C3"', '"DATE_C5", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "BOOLEAN_C3", "INTEGER_C1"', '"DATE_C5", "BOOLEAN_C3", "DECIMAL18__3_C2"', + '"DATE_C5", "BOOLEAN_C3", "BOOLEAN_C3"', '"DATE_C5", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "VARCHAR2_C4", "INTEGER_C1"', '"DATE_C5", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"DATE_C5", "VARCHAR2_C4", "BOOLEAN_C3"', '"DATE_C5", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "DATE_C5", "INTEGER_C1"', '"DATE_C5", "DATE_C5", "DECIMAL18__3_C2"', + '"DATE_C5", "DATE_C5", "BOOLEAN_C3"', '"DATE_C5", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"DATE_C5", "TIMESTAMP_C6", "INTEGER_C1"', '"DATE_C5", "TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"DATE_C5", "TIMESTAMP_C6", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "INTEGER_C1"', + '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"TIMESTAMP_C6", "INTEGER_C1", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", + "INTEGER_C1", "INTEGER_C1"', '"TIMESTAMP_C6", "INTEGER_C1", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "INTEGER_C1", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "INTEGER_C1"', '"TIMESTAMP_C6", + "DECIMAL18__3_C2", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "DECIMAL18__3_C2", "BOOLEAN_C3"', + '"TIMESTAMP_C6", "BOOLEAN_C3", "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "BOOLEAN_C3", + "INTEGER_C1"', '"TIMESTAMP_C6", "BOOLEAN_C3", "DECIMAL18__3_C2"', '"TIMESTAMP_C6", + "BOOLEAN_C3", "BOOLEAN_C3"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "INTEGER_C1"', '"TIMESTAMP_C6", "VARCHAR2_C4", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "VARCHAR2_C4", "BOOLEAN_C3"', '"TIMESTAMP_C6", "DATE_C5", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "DATE_C5", "INTEGER_C1"', '"TIMESTAMP_C6", "DATE_C5", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "DATE_C5", "BOOLEAN_C3"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "DOUBLE_PRECISION_C0"', + '"TIMESTAMP_C6", "TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "TIMESTAMP_C6", + "DECIMAL18__3_C2"', '"TIMESTAMP_C6", "TIMESTAMP_C6", "BOOLEAN_C3"'] +repeat: ['"VARCHAR2_C4", "INTEGER_C1"'] +replace: ['"VARCHAR2_C4", "VARCHAR2_C4"', '"VARCHAR2_C4", "VARCHAR2_C4", "VARCHAR2_C4"'] +reverse: ['"VARCHAR2_C4"'] +right: ['"VARCHAR2_C4", "INTEGER_C1"'] +round: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"DATE_C5"', + '"TIMESTAMP_C6"', '"DOUBLE_PRECISION_C0", "DOUBLE_PRECISION_C0"', '"DOUBLE_PRECISION_C0", + "INTEGER_C1"', '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", + "BOOLEAN_C3"', '"INTEGER_C1", "DOUBLE_PRECISION_C0"', '"INTEGER_C1", "INTEGER_C1"', + '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "BOOLEAN_C3"', '"DECIMAL18__3_C2", + "DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2", "INTEGER_C1"', '"DECIMAL18__3_C2", + "DECIMAL18__3_C2"', '"DECIMAL18__3_C2", "BOOLEAN_C3"'] +rpad: ['"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "VARCHAR2_C4"'] +rtrim: ['"VARCHAR2_C4"', '"VARCHAR2_C4", "VARCHAR2_C4"'] +second: ['"DATE_C5"', '"TIMESTAMP_C6"', '"DATE_C5", "DOUBLE_PRECISION_C0"', '"DATE_C5", + "INTEGER_C1"', '"DATE_C5", "DECIMAL18__3_C2"', '"DATE_C5", "BOOLEAN_C3"', '"TIMESTAMP_C6", + "DOUBLE_PRECISION_C0"', '"TIMESTAMP_C6", "INTEGER_C1"', '"TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "BOOLEAN_C3"'] +seconds_between: ['"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"'] +sign: ['"DECIMAL18__3_C2"'] +sin: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +sinh: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +soundex: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"', + '"VARCHAR2_C4"', '"DATE_C5"', '"TIMESTAMP_C6"'] +space: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"'] +sqrt: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +substr: ['"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1"'] +substring: ['"VARCHAR2_C4", "INTEGER_C1"', '"VARCHAR2_C4", "INTEGER_C1", "INTEGER_C1"'] +tan: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +tanh: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"'] +to_char: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"', + '"VARCHAR2_C4"', '"DATE_C5"', '"TIMESTAMP_C6"'] +to_date: ['"DATE_C5"', '"TIMESTAMP_C6"', '"DATE_C5", "DECIMAL18__3_C2"', '"DATE_C5", + "VARCHAR2_C4"'] +to_number: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"', + '"DOUBLE_PRECISION_C0", "DECIMAL18__3_C2"', '"DOUBLE_PRECISION_C0", "VARCHAR2_C4"', + '"INTEGER_C1", "DECIMAL18__3_C2"', '"INTEGER_C1", "VARCHAR2_C4"'] +to_timestamp: ['"DATE_C5"', '"TIMESTAMP_C6"', '"TIMESTAMP_C6", "DECIMAL18__3_C2"', + '"TIMESTAMP_C6", "VARCHAR2_C4"'] +translate: ['"VARCHAR2_C4", "VARCHAR2_C4", "VARCHAR2_C4"'] +trim: ['"VARCHAR2_C4"', '"VARCHAR2_C4", "VARCHAR2_C4"'] +trunc: ['"DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1"', + '"DECIMAL18__3_C2", "INTEGER_C1"'] +truncate: ['"DOUBLE_PRECISION_C0"', '"DECIMAL18__3_C2"', '"INTEGER_C1", "INTEGER_C1"', + '"DECIMAL18__3_C2", "INTEGER_C1"'] +ucase: ['"VARCHAR2_C4"'] +unicode: ['"VARCHAR2_C4"'] +unicodechr: ['"DOUBLE_PRECISION_C0"', '"INTEGER_C1"', '"DECIMAL18__3_C2"', '"BOOLEAN_C3"'] +upper: ['"VARCHAR2_C4"'] +user: [''] +week: ['"DATE_C5"', '"TIMESTAMP_C6"'] +year: ['"DATE_C5"', '"TIMESTAMP_C6"'] +years_between: ['"DATE_C5", "DATE_C5"', '"DATE_C5", "TIMESTAMP_C6"', '"TIMESTAMP_C6", + "DATE_C5"', '"TIMESTAMP_C6", "TIMESTAMP_C6"'] diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties new file mode 100644 index 0000000..8c97abe --- /dev/null +++ b/src/test/resources/logging.properties @@ -0,0 +1,6 @@ +handlers=java.util.logging.ConsoleHandler +.level=INFO +java.util.logging.ConsoleHandler.level=ALL +java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter +java.util.logging.SimpleFormatter.format=%1$tF %1$tT.%1$tL [%4$-7s] %5$s %n +com.exasol.level=ALL diff --git a/versionsMavenPluginRules.xml b/versionsMavenPluginRules.xml new file mode 100644 index 0000000..35bd03d --- /dev/null +++ b/versionsMavenPluginRules.xml @@ -0,0 +1,18 @@ + + + + + (?i).*Alpha(?:-?[\d.]+)? + (?i).*a(?:-?[\d.]+)? + (?i).*Beta(?:-?[\d.]+)? + (?i).*-B(?:-?[\d.]+)? + (?i).*-b(?:-?[\d.]+)? + (?i).*RC(?:-?[\d.]+)? + (?i).*CR(?:-?[\d.]+)? + (?i).*M(?:-?[\d.]+)? + + + + \ No newline at end of file