diff --git a/.github/obfarm/Dockerfile b/.github/obfarm/Dockerfile
new file mode 100644
index 0000000000..6ad501fc29
--- /dev/null
+++ b/.github/obfarm/Dockerfile
@@ -0,0 +1,9 @@
+# Container image that runs your code
+FROM python:3.6
+
+RUN pip3 install requests -i https://mirrors.aliyun.com/pypi/simple/
+# Copies your code file from your action repository to the filesystem path `/` of the container
+COPY obfarm.py /obfarm.py
+
+# Code file to execute when the docker container starts up (`entrypoint.sh`)
+ENTRYPOINT ["python3", "-u", "/obfarm.py"]
diff --git a/.github/obfarm/action.yaml b/.github/obfarm/action.yaml
new file mode 100644
index 0000000000..ef699cc8fb
--- /dev/null
+++ b/.github/obfarm/action.yaml
@@ -0,0 +1,26 @@
+# action.yml
+name: 'call OB Farm to run task'
+description: ''
+inputs:
+ pipeline_id:
+ description: 'pipeline_id'
+ required: true
+ project:
+ description: 'project'
+ required: true
+ timeout:
+ description: 'timeout'
+ required: false
+ default: '3600'
+outputs:
+ success:
+ description: 'the status for the task'
+runs:
+ using: 'docker'
+ image: 'Dockerfile'
+ args:
+ - ${{ inputs.pipeline_id }}
+ - ${{ inputs.project }}
+ - ${{ inputs.timeout }}
+
+
diff --git a/.github/obfarm/obfarm.py b/.github/obfarm/obfarm.py
new file mode 100644
index 0000000000..836625f42c
--- /dev/null
+++ b/.github/obfarm/obfarm.py
@@ -0,0 +1,233 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 OceanBase.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy
+import os
+import sys
+import traceback
+import time
+
+import json
+import requests
+from enum import Enum
+from http import HTTPStatus
+
+OUTPUT = {}
+RESULT_FILE_KEY = "farm/results/"
+TASK_QUEUE_FILE_KEY = "farm/jobs/{}.json"
+
+
+def _range(start, last):
+ def to_str(pos):
+ if pos is None:
+ return ''
+ else:
+ return str(pos)
+
+ return to_str(start) + '-' + to_str(last)
+
+
+def _make_range_string(range):
+ if range is None:
+ return ''
+
+ start = range[0]
+ last = range[1]
+
+ if start is None and last is None:
+ return ''
+
+ return 'bytes=' + _range(start, last)
+
+
+class OssProxy:
+
+ def __init__(self, endpoint=""):
+ self.endpoint = endpoint
+
+ def get_object(self, key, _range=None):
+ url = "{}/{}".format(self.endpoint, key)
+ headers = {}
+ if _range is not None:
+ _range = (_range, None)
+ headers.update({"range": _make_range_string(_range)})
+ res = requests.get(url, headers=headers)
+ if res.status_code < 400:
+ result = res.content.decode()
+ return result
+ return ""
+
+ def get_object_meta(self, key):
+ url = "{}/{}".format(self.endpoint, key)
+ headers = {}
+ res = requests.head(url, headers=headers)
+ return res.headers
+
+ def exists_object(self, key):
+ ...
+
+
+class GithubProxy:
+
+ def __init__(self, host="api.github.com"):
+ self.host = host
+
+ def get_job_by_id(self, project, pipeline_id):
+ url = "https://{}/repos/{}/actions/runs/{}".format(
+ self.host, project, pipeline_id
+ )
+ try:
+ res = requests.get(
+ url, headers={
+ "Accept": "application/vnd.github+json"
+ }
+ )
+ status_code = res.status_code
+ if status_code == HTTPStatus.NOT_FOUND:
+ return {}
+ return res.json()
+ except:
+ traceback.print_exc()
+ return {}
+
+
+class TaskStatusEnum(Enum):
+ submitting = 0
+ pending = 1
+ running = 2
+ stopping = 3
+ success = 4
+ fail = -1
+ kill = -2
+ timeout = -3
+ submit_task_fail = -4
+
+
+def request(method, url, params=None, payload=None, timeout=10, data=None, without_check_status=False):
+ params = params or {}
+ try:
+ response = requests.request(
+ method,
+ url,
+ params=params,
+ json=payload,
+ data=data,
+ timeout=timeout
+ )
+ if not without_check_status and response.status_code >= 300:
+ try:
+ msg = response.json()["msg"]
+ except:
+ msg = response.text
+ print("[ERROR] 错误信息:{}".format(msg))
+ exit(1)
+ return response
+ except Exception:
+ import traceback
+ traceback.print_exc()
+ print("请求失败,出现异常,请联系管理人员处理")
+ if not without_check_status:
+ exit(1)
+
+
+def monitor_tasks(oss_proxy: OssProxy, github_pipeline_id, timeout):
+ end_time = time.time() + int(timeout)
+ end = 0
+ end_task = False
+ print("{}OUTPUT{}".format("-" * 20, "-" * 20))
+ while time.time() <= end_time:
+ # 每次刷新20
+ if end_task is True:
+ pass
+ task_data = get_task_res(oss_proxy, github_pipeline_id)
+ if task_data:
+ end_task = True
+ output = get_task_stage_output(oss_proxy, github_pipeline_id, end)
+ if output is None:
+ continue
+ end += len(output)
+ need_print_output = output
+ if need_print_output and need_print_output.strip():
+ print(need_print_output, end="")
+
+ time.sleep(1)
+ if task_data is not None:
+ task_status = int(task_data["status"])
+ if task_status <= TaskStatusEnum.fail.value:
+ print(TaskStatusEnum._value2member_map_[task_status])
+ OUTPUT.update({"success": -1})
+ return False
+ elif task_status >= TaskStatusEnum.success.value:
+ print(TaskStatusEnum._value2member_map_[task_status])
+ OUTPUT.update({"success": 1})
+ return True
+
+ time.sleep(5)
+ else:
+ ...
+
+
+def get_task_res(oss_proxy: OssProxy, github_pipeline_id):
+ try:
+ result_key = RESULT_FILE_KEY + "{}.json".format(github_pipeline_id)
+ origin_task_data = oss_proxy.get_object(result_key)
+ return json.loads(origin_task_data)
+ except:
+ return
+
+
+def get_task_stage_output(oss_proxy: OssProxy, github_pipeline_id, start):
+ output_key = RESULT_FILE_KEY + "{}.output".format(github_pipeline_id)
+ if start:
+ output_meta = oss_proxy.get_object_meta(output_key)
+ filesize = int(output_meta["Content-Length"])
+ if start >= filesize:
+ start = filesize - 1
+ try:
+ return oss_proxy.get_object(output_key, _range=start)
+ except:
+ return ""
+
+
+def main(pipeline_id, project, timeout):
+ print("create a new task")
+ print("working....")
+ oss_proxy = OssProxy("https://farm-ce.oss-cn-heyuan.aliyuncs.com")
+ github_proxy = GithubProxy()
+ job_info = github_proxy.get_job_by_id(project, pipeline_id)
+ attempt_number = job_info["run_attempt"]
+ run_pipeline_id = "{}-{}".format(pipeline_id, attempt_number)
+ result = monitor_tasks(oss_proxy, run_pipeline_id, timeout)
+ set_output(OUTPUT)
+ if not result:
+ exit(1)
+
+
+def set_output(output):
+ values = ";".join(["{}={}".format(key, value) for key, value in output.items()])
+ os.system(
+ 'echo "{}" >> $GITHUB_OUTPUT'.format(values)
+ )
+
+
+
+if __name__ == "__main__":
+ print(sys.argv)
+ if len(sys.argv) < 4:
+ print("缺失相关参数")
+ OUTPUT.update({"success": -1})
+ sys.exit(1)
+ main(sys.argv[1], sys.argv[2], sys.argv[3])
diff --git a/.github/workflows/build_artifact.yaml b/.github/workflows/build_artifact.yaml
index e1c1a4f741..d876151d27 100644
--- a/.github/workflows/build_artifact.yaml
+++ b/.github/workflows/build_artifact.yaml
@@ -136,15 +136,6 @@ jobs:
echo "RPM's version is "${new_version}
mvn versions:set -DnewVersion="${new_version}"
mvn versions:commit
- - name: Install db-browser
- if: ${{ github.event.inputs.install_db_browser == 'true'}}
- run: |
- echo "Start install db-browser"
- pushd libs/db-browser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install db-browser success"
- popd
- name: Install ob-sql-parser
if: ${{ github.event.inputs.install_ob_sql_parser == 'true'}}
run: |
@@ -154,6 +145,15 @@ jobs:
mvn clean install -Dmaven.test.skip=true
echo "Install ob-sql-parser success"
popd
+ - name: Install db-browser
+ if: ${{ github.event.inputs.install_db_browser == 'true'}}
+ run: |
+ echo "Start install db-browser"
+ pushd libs/db-browser
+ echo "Current dir is "`pwd`
+ mvn clean install -Dmaven.test.skip=true
+ echo "Install db-browser success"
+ popd
- name: Build jar
run: |
echo "Start build jar packages"
@@ -202,15 +202,15 @@ jobs:
sed -e "s/DATE_CHANGE/$(date)/" -i distribution/docker/odc/Dockerfile
echo "odc_docker_image_tag=${odc_docker_image_tag}"
pushd distribution/docker
- docker build -t docker.io/oceanbase/odc-server:${odc_docker_image_tag} -f odc/Dockerfile .
- docker save -o resources/odc-server-${odc_docker_image_tag}.tar.gz docker.io/oceanbase/odc-server:${odc_docker_image_tag}
+ docker build -t docker.io/oceanbase/odc:${odc_docker_image_tag} -f odc/Dockerfile .
+ docker save -o resources/odc-${odc_docker_image_tag}.tar.gz docker.io/oceanbase/odc:${odc_docker_image_tag}
popd
- name: Upload docker image (x86_64)
if: ${{ github.event.inputs.build_docker == 'true' }}
uses: actions/upload-artifact@v3
with:
- name: odc-server-${{ env.odc_docker_image_tag }}.tar.gz
- path: distribution/docker/resources/odc-server-*.tar.gz
+ name: odc-${{ env.odc_docker_image_tag }}.tar.gz
+ path: distribution/docker/resources/odc-*.tar.gz
build-client:
name: Build Client Artifact
diff --git a/.github/workflows/build_daily.yaml b/.github/workflows/build_daily.yaml
index f276533cfe..d29b45fc78 100644
--- a/.github/workflows/build_daily.yaml
+++ b/.github/workflows/build_daily.yaml
@@ -6,10 +6,9 @@
# Jobs:
# 1. Check Code Format
# 2. PMD Scan
-# 3. Unit Test (TODO)
-# 4. Calculate Version Number
-# 5. Build Web Artifact (include front resource and only x86_64 platform for now)
-# 6. Build Client Artifact
+# 3. Calculate Version Number
+# 4. Build Web Artifact (include front resource and only x86_64 platform for now)
+# 5. Build Client Artifact
###
name: Build Daily
@@ -64,14 +63,6 @@ jobs:
java-version: "8"
distribution: "temurin"
cache: maven
- - name: Install db-browser
- run: |
- echo "Start install db-browser"
- pushd libs/db-browser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install db-browser success"
- popd
- name: Install ob-sql-parser
run: |
echo "Start install ob-sql-parser"
@@ -80,24 +71,6 @@ jobs:
mvn clean install -Dmaven.test.skip=true
echo "Install ob-sql-parser success"
popd
- - name: Build project
- run: mvn clean install -Dmaven.test.skip=true
- - name: Run PMD scan
- run: mvn pmd:check
-
- unit-test:
- name: Unit Test (Skip for now)
- needs: [ check-format, pmd-scan ]
- runs-on: ubuntu-latest
- steps:
- - name: Checkout workspace
- uses: actions/checkout@v3
- - name: Setup JDK 8
- uses: actions/setup-java@v3
- with:
- java-version: "8"
- distribution: "temurin"
- cache: maven
- name: Install db-browser
run: |
echo "Start install db-browser"
@@ -106,20 +79,14 @@ jobs:
mvn clean install -Dmaven.test.skip=true
echo "Install db-browser success"
popd
- - name: Install ob-sql-parser
- run: |
- echo "Start install ob-sql-parser"
- pushd libs/ob-sql-parser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install ob-sql-parser success"
- popd
- - name: Run unit test
- run: echo "Skip for now 🤪"
+ - name: Build project
+ run: mvn clean install -Dmaven.test.skip=true
+ - name: Run PMD scan
+ run: mvn pmd:check
calculate-version:
name: Calculate Version Number
- needs: [ unit-test ]
+ needs: [ check-format, pmd-scan ]
runs-on: ubuntu-latest
outputs:
odc_rpm_release_number: ${{ steps.calculate_version.outputs.odc_rpm_release_number }}
@@ -194,14 +161,6 @@ jobs:
echo "RPM's version is "${new_version}
mvn versions:set -DnewVersion="${new_version}"
mvn versions:commit
- - name: Install db-browser
- run: |
- echo "Start install db-browser"
- pushd libs/db-browser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install db-browser success"
- popd
- name: Install ob-sql-parser
run: |
echo "Start install ob-sql-parser"
@@ -210,6 +169,14 @@ jobs:
mvn clean install -Dmaven.test.skip=true
echo "Install ob-sql-parser success"
popd
+ - name: Install db-browser
+ run: |
+ echo "Start install db-browser"
+ pushd libs/db-browser
+ echo "Current dir is "`pwd`
+ mvn clean install -Dmaven.test.skip=true
+ echo "Install db-browser success"
+ popd
- name: Build jar & rpm (x86_64)
run: |
echo "Start prepare oceanbase-client"
@@ -249,14 +216,14 @@ jobs:
sed -e "s/DATE_CHANGE/$(date)/" -i distribution/docker/odc/Dockerfile
echo "odc_docker_image_tag=${odc_docker_image_tag}"
pushd distribution/docker
- docker build -t docker.io/oceanbase/odc-server:${odc_docker_image_tag} -f odc/Dockerfile .
- docker save -o resources/odc-server-${odc_docker_image_tag}.tar.gz docker.io/oceanbase/odc-server:${odc_docker_image_tag}
+ docker build -t docker.io/oceanbase/odc:${odc_docker_image_tag} -f odc/Dockerfile .
+ docker save -o resources/odc-${odc_docker_image_tag}.tar.gz docker.io/oceanbase/odc:${odc_docker_image_tag}
popd
- name: Upload docker image (x86_64)
uses: actions/upload-artifact@v3
with:
- name: odc-server-${{ env.odc_docker_image_tag }}.tar.gz
- path: distribution/docker/resources/odc-server-*.tar.gz
+ name: odc-${{ env.odc_docker_image_tag }}.tar.gz
+ path: distribution/docker/resources/odc-*.tar.gz
build-client:
name: Build Client Artifact
diff --git a/.github/workflows/build_dev.yaml b/.github/workflows/build_dev.yaml
index 30cf0591b0..eb98cbbc51 100644
--- a/.github/workflows/build_dev.yaml
+++ b/.github/workflows/build_dev.yaml
@@ -6,10 +6,10 @@
# Jobs:
# 1. Check Code Format
# 2. PMD Scan
-# 3. Unit Test (TODO)
+# 3. Unit Test
# 4. Calculate Version Number
# 5. Build RPM (exclude front resources and only x86_64 platform for now)
-# (Job 4 and 5 are executed only when Pull-Request)
+# (Job 3 to 5 are executed only when Pull-Request)
###
name: Build Dev
@@ -53,14 +53,6 @@ jobs:
java-version: "8"
distribution: "temurin"
cache: maven
- - name: Install db-browser
- run: |
- echo "Start install db-browser"
- pushd libs/db-browser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install db-browser success"
- popd
- name: Install ob-sql-parser
run: |
echo "Start install ob-sql-parser"
@@ -69,46 +61,36 @@ jobs:
mvn clean install -Dmaven.test.skip=true
echo "Install ob-sql-parser success"
popd
+ - name: Install db-browser
+ run: |
+ echo "Start install db-browser"
+ pushd libs/db-browser
+ echo "Current dir is "`pwd`
+ mvn clean install -Dmaven.test.skip=true
+ echo "Install db-browser success"
+ popd
- name: Build project
run: mvn clean install -Dmaven.test.skip=true
- name: Run PMD scan
run: mvn pmd:check
- unit-test:
- name: Unit Test (Skip for now)
- needs: [ check-format, pmd-scan ]
+ unit-test-odc:
+ name: Unit Test (ODC)
+ if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- name: Checkout workspace
uses: actions/checkout@v3
- - name: Setup JDK 8
- uses: actions/setup-java@v3
+ - name: action by obfarm++odc_ut++COMMIT=${{ github.event.pull_request.head.sha }}
+ uses: ./.github/obfarm/
+ id: odc_ut
with:
- java-version: "8"
- distribution: "temurin"
- cache: maven
- - name: Install db-browser
- run: |
- echo "Start install db-browser"
- pushd libs/db-browser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install db-browser success"
- popd
- - name: Install ob-sql-parser
- run: |
- echo "Start install ob-sql-parser"
- pushd libs/ob-sql-parser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install ob-sql-parser success"
- popd
- - name: Run unit test
- run: echo "Skip for now 🤪"
+ pipeline_id: ${{ github.run_id }}
+ project: ${{ github.repository }}
calculate-version:
name: Calculate Version Number
- needs: [ unit-test ]
+ needs: [ check-format, pmd-scan, unit-test-odc ]
if: ${{ github.event_name == 'pull_request' }}
runs-on: ubuntu-latest
outputs:
@@ -153,14 +135,6 @@ jobs:
echo "RPM's version is "${new_version}
mvn versions:set -DnewVersion="${new_version}"
mvn versions:commit
- - name: Install db-browser
- run: |
- echo "Start install db-browser"
- pushd libs/db-browser
- echo "Current dir is "`pwd`
- mvn clean install -Dmaven.test.skip=true
- echo "Install db-browser success"
- popd
- name: Install ob-sql-parser
run: |
echo "Start install ob-sql-parser"
@@ -169,6 +143,14 @@ jobs:
mvn clean install -Dmaven.test.skip=true
echo "Install ob-sql-parser success"
popd
+ - name: Install db-browser
+ run: |
+ echo "Start install db-browser"
+ pushd libs/db-browser
+ echo "Current dir is "`pwd`
+ mvn clean install -Dmaven.test.skip=true
+ echo "Install db-browser success"
+ popd
- name: Build jar & rpm (x86_64)
run: |
echo "Start prepare oceanbase-client"
diff --git a/.github/workflows/build_release.yaml b/.github/workflows/build_release.yaml
index 71efbaffe9..e7587b40a6 100644
--- a/.github/workflows/build_release.yaml
+++ b/.github/workflows/build_release.yaml
@@ -5,12 +5,11 @@
# Jobs:
# 1. Check Code Format
# 2. PMD Scan
-# 3. Unit Test (TODO)
-# 4. Calculate Version Number
-# 5. Build Web Artifact (include front resource and only x86_64 platform for now)
-# 6. Build Client Artifact
-# 7. Release (TODO)
-# 8. Tag (TODO)
+# 3. Calculate Version Number
+# 4. Build Web Artifact (include front resource and only x86_64 platform for now)
+# 5. Build Client Artifact
+# 6. Release (TODO)
+# 7. Tag (TODO)
###
name: Build Release
@@ -69,25 +68,9 @@ jobs:
- name: Run PMD scan
run: mvn pmd:check
- unit-test:
- name: Unit Test (Skip for now)
- needs: [ check-format, pmd-scan ]
- runs-on: ubuntu-latest
- steps:
- - name: Checkout workspace
- uses: actions/checkout@v3
- - name: Setup JDK 8
- uses: actions/setup-java@v3
- with:
- java-version: "8"
- distribution: "temurin"
- cache: maven
- - name: Run unit test
- run: echo "Skip for now 🤪"
-
calculate-version:
name: Calculate Version Number
- needs: [ unit-test ]
+ needs: [ check-format, pmd-scan ]
runs-on: ubuntu-latest
outputs:
odc_rpm_release_number: ${{ steps.calculate_version.outputs.odc_rpm_release_number }}
@@ -104,7 +87,7 @@ jobs:
echo "odc_rpm_release_number=${odc_rpm_release_number}"
branch_match_regex="^(((dev/)?[0-9]\\.[0-9]\\.([0-9]{1,2}|x))|(release\\S*))$"
tag_prefix=`[[ "${{ env.ODC_CURRENT_BRANCH }}" =~ ${branch_match_regex} ]] && echo "" || echo "test-"`
- odc_docker_image_tag="${tag_prefix}$(cat distribution/odc-server-VER.txt)-${odc_rpm_release_number}"
+ odc_docker_image_tag="${tag_prefix}$(cat distribution/odc-server-VER.txt)"
if [[ -n "${{ inputs.image_tag }}" ]]; then odc_docker_image_tag="${{ inputs.image_tag }}"; fi
echo "odc_docker_image_tag=${odc_docker_image_tag}" >> $GITHUB_OUTPUT
echo "odc_docker_image_tag=${odc_docker_image_tag}"
@@ -201,14 +184,14 @@ jobs:
sed -e "s/DATE_CHANGE/$(date)/" -i distribution/docker/odc/Dockerfile
echo "odc_docker_image_tag=${odc_docker_image_tag}"
pushd distribution/docker
- docker build -t docker.io/oceanbase/odc-server:${odc_docker_image_tag} -f odc/Dockerfile .
- docker save -o resources/odc-server-${odc_docker_image_tag}.tar.gz docker.io/oceanbase/odc-server:${odc_docker_image_tag}
+ docker build -t docker.io/oceanbase/odc:${odc_docker_image_tag} -f odc/Dockerfile .
+ docker save -o resources/odc-${odc_docker_image_tag}.tar.gz docker.io/oceanbase/odc:${odc_docker_image_tag}
popd
- name: Upload docker image (x86_64)
uses: actions/upload-artifact@v3
with:
- name: odc-server-${{ env.odc_docker_image_tag }}.tar.gz
- path: distribution/docker/resources/odc-server-*.tar.gz
+ name: odc-${{ env.odc_docker_image_tag }}.tar.gz
+ path: distribution/docker/resources/odc-*.tar.gz
build-client:
name: Build Client Artifact
diff --git a/.gitignore b/.gitignore
index 1cea7d58a8..a8d2a23b2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,8 @@ build-resource/
target
_build/
conf/
+/plugins
+/starters
server/odc-server/src/main/resources/static/
server/odc-common/src/test/resources/generate-input.properties
server/integration-test/oss_temp_dir/
diff --git a/.gitmodules b/.gitmodules
index 7dbd0982a1..47d8d9ed24 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
[submodule "client"]
path = client
url = https://github.com/oceanbase/odc-client.git
- branch = dev-4.2.1
+ branch = dev-4.2.2
diff --git a/CHANGELOG-zh-CN.md b/CHANGELOG-zh-CN.md
index 3860708c06..9f78e63a6e 100644
--- a/CHANGELOG-zh-CN.md
+++ b/CHANGELOG-zh-CN.md
@@ -1,5 +1,90 @@
# OceanBase Developer Center (ODC) CHANGELOG
+## 4.2.2 (2023-11-07)
+
+### 功能变化
+
+数据源
+
+- 支持 MySQL 数据源
+- 适配 OceanBase 4.2.0/4.2.1
+- 数据源增加初始化脚本以及自定义 JDBC 连接参数设置
+
+数据脱敏
+
+- 支持视图脱敏
+
+数据归档
+
+- 支持 OceanBase 4.x 版本
+- 支持 MySQL 到 OceanBase 链路
+- 支持白屏限流配置
+- 支持断点恢复
+
+导入导出
+
+- 支持类型对象的导入导出
+
+### 改进
+
+- 优化了大规模表列场景下的对象管理性能,通过 ob-sql-parser 解析索引/约束的元数据
+- 优化了数据库对象树交互,项目和数据源的选择交互区域折叠到顶部,数据库列表展示更清晰
+- 优化了 SQL 窗口新建和 SQL 窗口切换数据库的交互,切换数据库更快速了,SQL 窗口增加复制操作
+- 优化了数据脱敏配置交互,选择敏感列更方便
+- 优化了存在大量数据源场景下获取数据源列表缓慢以及获取数据源状态缓慢的问题
+- 优化以错误参数运行 PL 时的报错文案
+
+### 缺陷修复
+
+PL 调试
+
+- 调试过程中无法跳入程序包中定义的子存储过程/函数
+
+SQL 执行
+
+- 执行 SQL 过程中持续执行 "DROP PACKAGE" 语句导致大量报错
+- 连接 OceanBase MySQL 租户时自动调用 "obodc_procedure_feature_test" 存储过程导致报错或进入连接缓慢
+- SQL 执行耗时统计各子项耗时之和不等于父项
+- SQL 执行耗时统计中, "SQL 预检查"及"SQL 后置检查"缺乏详细子项耗时统计
+
+SQL-Check
+
+- OceanBase Oracle 租户下创建 type 时,如果子存储过程/函数无参数列表,SQL Check 报语法错误
+- 无法关闭"语法错误"规则
+
+数据脱敏
+
+- SELECT 语句中含有多表 JOIN 的场景下脱敏失败
+- 大小写敏感的 OceanBase MySQL 模式下无法识别到敏感列导致脱敏失效
+
+数据库对象管理
+
+- 没有 show create view 权限用户查看视图详情时报错
+- 查看表对象时所有字符类型的长度无法显示
+
+数据库变更
+
+- 数据库变更任务超时时间设置无效
+- 个人空间下查看定时执行的带有自动回滚节点的数据库变更任务详情失败
+
+导入导出
+
+- Oracle 模式下导出程序包不包含包体
+- 无法将含有制表符的结果集导出为 Excel
+
+操作审计
+
+- 没有将"SQL 检查规范"以及"SQL 窗口规范"改变纳入操作审计范围
+
+### 依赖库升级
+
+- 升级 ob-loader-dumper 版本到 4.2.5-RELEASE
+- 升级 oceanbase-client 版本到 2.4.5
+
+### 安全加固
+
+- 前后端敏感字段传输使用非对称加密
+
## 4.2.1 (2023-09-25)
### 缺陷修复
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa78001e33..3474a3ccc6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,90 @@
# OceanBase Developer Center (ODC) CHANGELOG
+## 4.2.2 (2023-11-07)
+
+### Feature
+
+Data Source
+
+- Support MySQL data source
+- Adapted to OceanBase 4.2.0/4.2.1
+- Data sources add initialization scripts and customized JDBC connection parameter settings
+
+Data Desensitization
+
+- Support view desensitization
+
+DLM
+
+- Support OceanBase 4.x version
+- Support MySQL to OceanBase link
+- Support white screen current limiting configuration
+- Support breakpoint recovery
+
+Import and Export
+
+- Supports import and export of type objects
+
+### Improve
+
+- Optimized object management performance in large-scale table scenarios, and used ob-sql-parser to parse index/constraint metadata
+- Optimized database object tree interaction, the project and data source selection interaction area is folded to the top, and the database list is displayed more clearly
+- Optimized the interaction between creating a new SQL window and switching databases in the SQL window. Switching databases is faster, and the SQL window adds a copy operation.
+- Optimized the data desensitization configuration interaction, making it more convenient to select sensitive columns
+- Optimized the problem of slow retrieval of data source list and slow retrieval of data source status in scenarios where there are a large number of data sources.
+- Optimize the error text when running PL with wrong parameters
+
+### Fix
+
+PL Debugging
+
+- Unable to jump into sub-stored procedures/functions defined in the package during debugging
+
+SQL Execution
+
+- Continuous execution of "DROP PACKAGE" statements during SQL execution resulted in a large number of error reports
+- When connecting to the OceanBase MySQL tenant, the "obodc_procedure_feature_test" stored procedure is automatically called, resulting in an error or slow connection.
+- The sum of the time consumption of each sub-item in SQL execution time-consuming statistics is not equal to the parent item
+- In the SQL execution time-consuming statistics, "SQL pre-check" and "SQL post-check" lack detailed sub-item time-consuming statistics
+
+SQL-Check
+
+- When creating type under the OceanBase Oracle tenant, if the sub-stored procedure/function has no parameter list, SQL Check will report a syntax error.
+- Unable to turn off "Syntax Error" rule
+
+Data Desensitization
+
+- Desensitization fails when the SELECT statement contains multiple table JOINs
+- Sensitive columns cannot be recognized in the case-sensitive OceanBase MySQL mode, causing desensitization to fail.
+
+Database Object Management
+
+- Users without the show create view permission will receive an error when viewing view details.
+- The length of all character types cannot be displayed when viewing table objects
+- Failed to view details of scheduled database change tasks with automatic rollback nodes in personal space
+
+Database Changes
+
+- The database change task timeout setting is invalid
+
+Import and Export
+
+- The exported package in Oracle mode does not contain the package body
+- Unable to export result set containing tab characters to Excel
+
+Operational audit
+
+- Changes to "SQL Check Specification" and "SQL Window Specification" are not included in the operational audit scope
+
+### Dependency library upgrade
+
+- Upgrade ob-loader-dumper version to 4.2.5-RELEASE
+- Upgrade oceanbase-client version to 2.4.5
+
+### Security reinforcement
+
+- Transmission of sensitive fields on the front and back ends uses asymmetric encryption
+
## 4.2.1 (2023-09-25)
### Fix
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index ca1cba4513..1535807d53 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -3,12 +3,116 @@
New
~~~
+- Feat(dlm):support breakpoint recovery (#635) [guowl3]
+- Feat(dlm):support configuring limiter (#626) [guowl3]
+- Feat(data-security): add data type unit into response (#629)
+ [XiaoYang]
+- Feat(dlm): data archive supports MySQL to OB (#544) [guowl3]
+- Feat: add timeout settings for pl-debug (#576) [IL MARE]
+- Feat: make odc adapt to OceanBase 4.2 (#541) [IL MARE]
+- Feat(ob-sql-parser): make ob-sql-parser adapt to OceanBase 4.2 (#441)
+ [IL MARE]
+- Feat(connection): add initialization configuration capabilities for
+ data sources (#488) [IL MARE]
+- Feat(data-transfer): upgrade ob-loader-dumper to 4.2.5-RELEASE (#494)
+ [LuckyLeo]
+- Feat(integration): support retrieve xml format response (#338)
+ [XiaoYang]
+- Feat(data-security): data masking support columns in view (#97)
+ [XiaoYang]
+- Feat(encryption): support asymmetric encryption (#99) [XiaoYang]
+- Feat(schema-plugin): schema-plugin access service layer (#88)
+ [zhangxiao]
+
+Changes
+~~~~~~~
+- Refactor(unit-test): cherry-pick unit-test commits from 4.2.x to 4.2.2
+ (#474) [XiaoYang]
+- Refactor(submodule): update submodule (#470) [IL MARE]
+- Refactor(unit-test): refact unit test cases (#139) (#142) [IL MARE]
+- Refactor(ob-sql-parser): add several new syntaxes which added in
+ OceanBase 4.1.0 (#132) [IL MARE]
+- Refactor(unit-test): refact unit test cases (#139) (#141) [IL MARE]
+
+Fix
+~~~
+- Fix(dlm): submit task got condition not supported error while
+ condition contains subquery (#668) [guowl3]
+- Fix(database-change): failed to view a scheduled database change task
+ with rollback plan in personal space (#669) [zhangxiao]
+- Fix(pl-debug): enable dbms_output first (#677) [IL MARE]
+- Fix(database): use datasource's environment as database's environment
+ to prevent data inconsistency (#659) [pynzzZ]
+- Fix: dirty meta data (#663) [XiaoYang]
+- Fix(sql-execute): fix failed to get time consuming (#658) [IL MARE]
+- Fix(migration): rule metadata migration will be triggered every time
+ the ODC server starts up (#649) [pynzzZ]
+- Fix(sql-check): fix syntax error check rule can not be disabled (#652)
+ [IL MARE]
+- Fix: fix can not get plan (#660) [IL MARE]
+- Fix(data-transfer): no package body (#653) [LuckyLeo]
+- Fix(web): editor.worker.js static resource 404 not found (#656)
+ [pynzzZ]
+- Fix(data-transfer): fix wrong data objects and schema objects (#620)
+ [LuckyLeo]
+- Fix(datasource): the data source list refreshes very slowly and cannot
+ obtain the connect status while there are a huge amount of data
+ sources (#599) [pynzzZ, yh263208]
+- Fix: fix failed to query data and sql rules changing is not recorded
+ by audit event (#608) [IL MARE]
+- Fix(connection): fix failed to set setConnectionAttrs (#601) [IL MARE]
+- Fix(db-browser): cannot get table charset in native mysql mode (#592)
+ [zhangxiao]
+- Fix(result-export): failed to convert CSV file into Excel file (#586)
+ [LuckyLeo]
+- Fix(diagnose): optimize log information when explain failed (#589)
+ [LuckyLeo]
+- Fix(pl): fix wrong parameter check error message (#583) [IL MARE]
+- Fix(schema-plugin): cannot display constraint name for ob oralce 4.2.1
+ (#533) [zhangxiao]
+- Fix(pl-debug): fix failed to step in a subprocedure or subfunction
+ defined in package (#566) [IL MARE]
+- Fix(integration): recover bastion integration (#559) [yizhou]
+- Fix(databasechange): fix task costs too much time to start up (#551)
+ [IL MARE]
+- Fix: remove pl delete code (#548) [IL MARE]
+- Fix(ob-sql-parser): fix failed to parse member proc without parameters
+ (#546) [IL MARE]
+- Fix(osc): fix get cloud main account id throw exception when
+ environment is not cloud (#529) [krihy]
+- Fix(data-security): exist sensitive is not filtered and view
+ desensitization data failed (#509) [XiaoYang]
+- Fix(unit-test): unit test logs expose sensitive information (#498)
+ (#516) [XiaoYang]
+- Fix(view): fix get view failed without show view permission (#507)
+ [zhangxiao]
+- Fix: masking failed (#485) [XiaoYang]
+- Fix(osc): execute pre and post interceptor in retry rename table
+ (#486) [krihy]
+- Fix(unit-test): fix failed unit test cases (#476) [XiaoYang, yh263208]
+- Fix(data-security): error metadata of built-in sensitive algorithm
+ (#458) [XiaoYang]
+- Fix: database change failed (#455) [XiaoYang]
+- Fix: scan sensitive columns (#444) [XiaoYang]
+- Fix(mvc): api response content type converts to xml (#377) [XiaoYang]
+- Fix: extract column from SQL with multiple join clauses (#327)
+ [XiaoYang]
+
+
+v4.2.1 (2023-10-09)
+-------------------
+
+New
+~~~
+- Feat(db-browser): upgrade db-browser's version to 1.0.2 (#402) [IL
+ MARE]
- Feat(data-transfer): support saving export objects (#73) [LuckyLeo]
- Feat(workflow): add checkbox for installing db-browser and ob-sql-
parser (#75) [IL MARE]
Changes
~~~~~~~
+- Refactor(submodule): update submodule (#436) [IL MARE]
- Refactor(migration): extract data migration interface (#290) [pynzzZ]
- Refactor(migrates): add some abstract methods for migrates (#275) [IL
MARE]
@@ -24,6 +128,8 @@ Changes
Fix
~~~
+- Fix(dlm): validate condition by sql explain. (#440) [guowl3]
+- Fix(datasource): optimize datasource synchronization (#391) [pynzzZ]
- Fix(osc): osc support ob ce add type ob mysql ce (#390) [krihy]
- Fix: masking enabled (#383) [XiaoYang]
- Fix(clientMode): fail to start for lack of Service annotations (#371)
diff --git a/client b/client
index 73d4604617..1f5f2e47df 160000
--- a/client
+++ b/client
@@ -1 +1 @@
-Subproject commit 73d46046178c1fb3717393c122c080a5aafe6458
+Subproject commit 1f5f2e47dfbe486c82ba7413d8a79dce6c54ea5f
diff --git a/distribution/docker/build.sh b/distribution/docker/build.sh
index 4c9e957027..6ecb2915b1 100755
--- a/distribution/docker/build.sh
+++ b/distribution/docker/build.sh
@@ -8,9 +8,9 @@ main() {
local register="docker.io"
local namespace="oceanbase"
- local app_name=odc-server
+ local app_name=odc
local image_name=${register}/${namespace}/${app_name}
- local image_tag=${2:-"UNKNOWN"}
+ local image_tag=${2:-"latest"}
case $1 in
build-odc)
diff --git a/distribution/odc-server-VER.txt b/distribution/odc-server-VER.txt
index fae6e3d04b..af8c8ec7c1 100644
--- a/distribution/odc-server-VER.txt
+++ b/distribution/odc-server-VER.txt
@@ -1 +1 @@
-4.2.1
+4.2.2
diff --git a/docs/en-US/DEVELOPER_GUIDE.md b/docs/en-US/DEVELOPER_GUIDE.md
index e7902d7465..347c176d7a 100644
--- a/docs/en-US/DEVELOPER_GUIDE.md
+++ b/docs/en-US/DEVELOPER_GUIDE.md
@@ -199,6 +199,21 @@ The following is a schematic diagram of IDEA Code Style configuration.
Some of ODC's unit test cases rely on real database services, and the database account and password are encrypted and stored in the configuration file.
+During local development, the environment configuration information required for unit testing can be maintained in the `local-unit-test.properties` file located in the root directory of the repository.
+
+> To prevent the leakage of database information in the testing environment, the `local-unit-test.properties` file in the repository has been added to the `.gitignore` file.
+
+Sample configuration
+
+```properties
+# Unit test OB cluster environment configuration.
+# Sensitive value auto encrypt by com.oceanbase.odc.test.tool.EncryptableConfigurations.
+# While change value, just input plain text and the value will be replaced to encrypted one while first time loaded
+odc.ob.default.oracle.commandline=your_ob_oracle_test_tenant_obclient_cli_commandline
+odc.ob.default.mysql.commandline=your_ob_mysql_test_tenant_obclient_cli_commandline
+odc.mysql.default.commandline=your_mysql_test_server_mysql_cli_commandline
+```
+
Unit tests may be executed locally and on the Github CI pipeline.
The ODC unit test execution process reads the decryption key of the encrypted information through environment variables or a `.env` configuration file.
@@ -340,7 +355,7 @@ Instead, it will download the latest iteration of the `index.html` file correspo
Static resource files URL template `http://static-resource-server/oceanbase/odc/{branchName}/xxx` .
here `{branchName}` mean git branch name of frontend repository.
-e.g. version `spring-4.2.0`, The `index.html` refer URL is `http://static-resource-server/oceanbase/odc/sprint-4.2.0/index.html` 。
+e.g. branch `dev-4.2.2`, The `index.html` refer URL is `http://static-resource-server/dev-4.2.2/index.html` .
### 4.1.3 Automate refresh frontend resource
@@ -351,7 +366,7 @@ When starting the odc-server, you can configure the environment variable `ODC_IN
An example configuration is shown below.
```shell
-export ODC_INDEX_PAGE_URI=http://static-resource-server/oceanbase/odc/sprint-4.2.0/index.html
+export ODC_INDEX_PAGE_URI=http://static-resource-server/dev-4.2.2/index.html
```
## 4.3 TraceId based log analysis
diff --git a/docs/zh-CN/DEVELOPER_GUIDE.md b/docs/zh-CN/DEVELOPER_GUIDE.md
index 2307a6e690..1e980db608 100644
--- a/docs/zh-CN/DEVELOPER_GUIDE.md
+++ b/docs/zh-CN/DEVELOPER_GUIDE.md
@@ -173,6 +173,20 @@ IDEA Code Style 配置示意图
ODC 的部分单元测试用例依赖真实的数据库服务,数据库帐密是加密存储在配置文件里的。
+本地开发时,单元测试依赖的环境配置信息可以维护在仓库根目录的 `local-unit-test.properties` 文件。
+> 为了避免测试环境的数据库信息泄露,仓库里的 `local-unit-test.properties` 文件已经加入 `.gitignore` 。
+
+配置样例如下。
+
+```properties
+# Unit test OB cluster environment configuration.
+# Sensitive value auto encrypt by com.oceanbase.odc.test.tool.EncryptableConfigurations.
+# While change value, just input plain text and the value will be replaced to encrypted one while first time loaded
+odc.ob.default.oracle.commandline=your_ob_oracle_test_tenant_obclient_cli_commandline
+odc.ob.default.mysql.commandline=your_ob_mysql_test_tenant_obclient_cli_commandline
+odc.mysql.default.commandline=your_mysql_test_server_mysql_cli_commandline
+```
+
单元测试可能在本地和 Github CI 流水线执行,ODC 单元测试执行过程通过环境变量或者 `.env` 配置文件读取加密信息的解密密钥。
- Github CI 流水线读取的环境变量通过 GitHub Actions Variable 维护
@@ -305,10 +319,10 @@ index.html 文件。 这个 `index.html`文件引用静态资源服务器资源
![image.png](../en-US/images/concept-isolated-debug.png)
-静态资源 URL 地址规则 `http://static-resource-server/oceanbase/odc/{branchName}/xxx` .
+静态资源 URL 地址规则 `http://static-resource-server/{branchName}/xxx` .
其中 `{branchName}` 表示前端分支名称。
-如 spring-4.2.0 分支,后端引用的 `index.html` URL 为 `http://static-resource-server/oceanbase/odc/sprint-4.2.0/index.html` 。
+如 dev-4.2.2 分支,后端引用的 `index.html` URL 为 `http://static-resource-server/dev-4.2.2/index.html` 。
### 4.1.3 设置自动更新静态资源
@@ -318,7 +332,7 @@ index.html 文件。 这个 `index.html`文件引用静态资源服务器资源
设置样例如下。
```shell
-export ODC_INDEX_PAGE_URI=http://static-resource-server/oceanbase/odc/sprint-4.2.0/index.html
+export ODC_INDEX_PAGE_URI=http://static-resource-server/dev-4.2.2/index.html
```
## 4.3 基于 traceId 的日志排查
diff --git a/libs/db-browser/pom.xml b/libs/db-browser/pom.xml
index d675d4ea71..d09f661453 100644
--- a/libs/db-browser/pom.xml
+++ b/libs/db-browser/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.oceanbase
db-browser
- 1.0.2
+ 1.0.3
db-browser
https://github.com/oceanbase/odc/tree/main/libs/db-browser
@@ -83,9 +83,9 @@
4.4
2.18.0
1.2.83
- 1.1.1
+ 1.1.3
1.4
- 2.4.3
+ 2.4.5
${project.basedir}
build/eclipse-java-oceanbase-style.xml
2.11.0
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditor.java
index 3dbea990af..82ca3c9ac2 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditor.java
@@ -32,7 +32,6 @@
import com.oceanbase.tools.dbbrowser.model.DBConstraintType;
import com.oceanbase.tools.dbbrowser.model.DBIndexType;
import com.oceanbase.tools.dbbrowser.model.DBTable;
-import com.oceanbase.tools.dbbrowser.model.DBTable.DBTableOptions;
import com.oceanbase.tools.dbbrowser.model.DBTableColumn;
import com.oceanbase.tools.dbbrowser.model.DBTableConstraint;
import com.oceanbase.tools.dbbrowser.model.DBTableIndex;
@@ -125,23 +124,7 @@ public String generateCreateObjectDDL(@NotNull DBTable table) {
protected abstract boolean createIndexWhenCreatingTable();
- protected void appendTableOptions(DBTable table, SqlBuilder sqlBuilder) {
- if (Objects.isNull(table.getTableOptions())) {
- return;
- }
- DBTableOptions options = table.getTableOptions();
-
- if (Objects.nonNull(options.getReplicaNum())) {
- sqlBuilder.append("REPLICA_NUM = ").append(String.valueOf(options.getReplicaNum())).space();
- }
-
- if (Objects.nonNull(options.getUseBloomFilter())) {
- sqlBuilder.append("USE_BLOOM_FILTER = ").append(options.getUseBloomFilter() ? "TRUE" : "FALSE").space();
- }
- if (Objects.nonNull(options.getTabletSize())) {
- sqlBuilder.append("TABLET_SIZE = ").append(String.valueOf(options.getTabletSize())).space();
- }
- }
+ protected abstract void appendTableOptions(DBTable table, SqlBuilder sqlBuilder);
@Override
public String generateCreateDefinitionDDL(@NotNull DBTable table) {
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/MySQLTableEditor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/MySQLTableEditor.java
index ab535cdcdc..87cc576509 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/MySQLTableEditor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/MySQLTableEditor.java
@@ -76,12 +76,14 @@ protected void appendTableOptions(DBTable table, SqlBuilder sqlBuilder) {
if (StringUtils.isNotBlank(options.getCompressionOption())) {
sqlBuilder.append("COMPRESSION = ").append(options.getCompressionOption()).space();
}
- super.appendTableOptions(table, sqlBuilder);
+ appendMoreTableOptions(table, sqlBuilder);
if (StringUtils.isNotEmpty(options.getComment())) {
sqlBuilder.append("COMMENT = ").value(options.getComment()).space();
}
}
+ protected void appendMoreTableOptions(DBTable table, SqlBuilder sqlBuilder) {}
+
@Override
protected void generateUpdateTableOptionDDL(@NonNull DBTable oldTable, @NonNull DBTable newTable,
@NonNull SqlBuilder sqlBuilder) {
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/OBMySQLTableEditor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/OBMySQLTableEditor.java
new file mode 100644
index 0000000000..ab11b9e9b4
--- /dev/null
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/mysql/OBMySQLTableEditor.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2023 OceanBase.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.oceanbase.tools.dbbrowser.editor.mysql;
+
+import java.util.Objects;
+
+import com.oceanbase.tools.dbbrowser.editor.DBObjectEditor;
+import com.oceanbase.tools.dbbrowser.model.DBTable;
+import com.oceanbase.tools.dbbrowser.model.DBTable.DBTableOptions;
+import com.oceanbase.tools.dbbrowser.model.DBTableColumn;
+import com.oceanbase.tools.dbbrowser.model.DBTableConstraint;
+import com.oceanbase.tools.dbbrowser.model.DBTableIndex;
+import com.oceanbase.tools.dbbrowser.model.DBTablePartition;
+import com.oceanbase.tools.dbbrowser.util.SqlBuilder;
+
+/**
+ * @author jingtian
+ * @date 2023/9/25
+ * @since ODC_release_4.2.2
+ */
+public class OBMySQLTableEditor extends MySQLTableEditor {
+ public OBMySQLTableEditor(DBObjectEditor indexEditor,
+ DBObjectEditor columnEditor,
+ DBObjectEditor constraintEditor,
+ DBObjectEditor partitionEditor) {
+ super(indexEditor, columnEditor, constraintEditor, partitionEditor);
+ }
+
+ @Override
+ protected void appendMoreTableOptions(DBTable table, SqlBuilder sqlBuilder) {
+ if (Objects.isNull(table.getTableOptions())) {
+ return;
+ }
+
+ DBTableOptions options = table.getTableOptions();
+ if (Objects.nonNull(options.getReplicaNum())) {
+ sqlBuilder.append("REPLICA_NUM = ").append(String.valueOf(options.getReplicaNum())).space();
+ }
+ if (Objects.nonNull(options.getUseBloomFilter())) {
+ sqlBuilder.append("USE_BLOOM_FILTER = ").append(options.getUseBloomFilter() ? "TRUE" : "FALSE").space();
+ }
+ if (Objects.nonNull(options.getTabletSize())) {
+ sqlBuilder.append("TABLET_SIZE = ").append(String.valueOf(options.getTabletSize())).space();
+ }
+ }
+}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/oracle/OracleTableEditor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/oracle/OracleTableEditor.java
index 963ffbc31f..cd36965a36 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/oracle/OracleTableEditor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/editor/oracle/OracleTableEditor.java
@@ -61,7 +61,15 @@ protected void appendTableOptions(DBTable table, SqlBuilder sqlBuilder) {
if (StringUtils.isNotBlank(options.getCompressionOption())) {
sqlBuilder.append("COMPRESS ").append(options.getCompressionOption()).space();
}
- super.appendTableOptions(table, sqlBuilder);
+ if (Objects.nonNull(options.getReplicaNum())) {
+ sqlBuilder.append("REPLICA_NUM = ").append(String.valueOf(options.getReplicaNum())).space();
+ }
+ if (Objects.nonNull(options.getUseBloomFilter())) {
+ sqlBuilder.append("USE_BLOOM_FILTER = ").append(options.getUseBloomFilter() ? "TRUE" : "FALSE").space();
+ }
+ if (Objects.nonNull(options.getTabletSize())) {
+ sqlBuilder.append("TABLET_SIZE = ").append(String.valueOf(options.getTabletSize())).space();
+ }
}
@Override
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableIndex.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableIndex.java
index f21e0cbdb5..668959197f 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableIndex.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableIndex.java
@@ -69,6 +69,10 @@ public class DBTableIndex implements DBObject, DBObjectWarningDescriptor {
private boolean nonUnique;
private Long cardinality;
+ /**
+ * 是否可用,索引创建成功后是可用状态,否则不可用
+ */
+ private Boolean available;
@JsonProperty(access = Access.READ_ONLY)
private Timestamp createTime;
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableStats.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableStats.java
index 3760013b77..0e2844add4 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableStats.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableStats.java
@@ -34,4 +34,5 @@ public class DBTableStats {
private Long rowCount;
@JsonIgnore
private Long dataSizeInBytes;
+ private String tableSize;
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/OracleConstants.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/OracleConstants.java
index 9da61db389..30b3d97fed 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/OracleConstants.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/OracleConstants.java
@@ -39,6 +39,7 @@ public class OracleConstants {
public static final String INDEX_TYPE = "INDEX_TYPE";
public static final String INDEX_UNIQUENESS = "UNIQUENESS";
public static final String INDEX_NAME = "INDEX_NAME";
+ public static final String INDEX_STATUS = "STATUS";
public static final String INDEX_COMPRESSION = "COMPRESSION";
public static final String CONS_NAME = "CONSTRAINT_NAME";
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessor.java
index 7d8e807c42..07aedcf4e4 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessor.java
@@ -139,6 +139,11 @@ default List showTables(String schemaName) {
*/
List listPackages(String schemaName);
+ /**
+ * Show all package body list in the specified schema
+ */
+ List listPackageBodies(String schemaName);
+
/**
* Show all trigger list in the specified schema
*/
@@ -164,12 +169,31 @@ default List showTables(String schemaName) {
*/
Map> listTableColumns(String schemaName);
+ /**
+ * Get all table columns in the specified schema and table
+ */
List listTableColumns(String schemeName, String tableName);
+ /**
+ * Get all table columns(hold only basic info) in the specified schema
+ */
Map> listBasicTableColumns(String schemaName);
+ /**
+ * Get all table columns(hold only basic info) in the specified schema and table
+ */
List listBasicTableColumns(String schemaName, String tableName);
+ /**
+ * Get all view columns(hold only basic info) in the specified schema
+ */
+ Map> listBasicViewColumns(String schemaName);
+
+ /**
+ * Get all view columns(hold only basic info) in the specified schema and view
+ */
+ List listBasicViewColumns(String schemaName, String viewName);
+
/**
* Get all table indexs in the specified schema
*/
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/Statements.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/Statements.java
index 3f8c770c26..408cd92735 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/Statements.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/Statements.java
@@ -22,7 +22,9 @@
*/
public final class Statements {
public static final String LIST_BASIC_TABLE_COLUMNS = "list-basic-table-columns";
- public static final String LIST_BASIC_SCHEMA_COLUMNS = "list-basic-schema-columns";
+ public static final String LIST_BASIC_SCHEMA_TABLE_COLUMNS = "list-basic-schema-table-columns";
+ public static final String LIST_BASIC_VIEW_COLUMNS = "list-basic-view-columns";
+ public static final String LIST_BASIC_SCHEMA_VIEW_COLUMNS = "list-basic-schema-view-columns";
public static final String LIST_TABLE_COLUMNS = "list-table-columns";
public static final String LIST_SCHEMA_COLUMNS = "list-schema-columns";
public static final String LIST_TABLE_INDEXES = "list-table-indexes";
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoGreaterThan5740SchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoGreaterThan5740SchemaAccessor.java
index 5b838905cd..77d7c74913 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoGreaterThan5740SchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoGreaterThan5740SchemaAccessor.java
@@ -19,6 +19,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
+import java.io.StringReader;
import java.io.StringWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@@ -89,6 +90,10 @@
import com.oceanbase.tools.dbbrowser.util.MySQLSqlBuilder;
import com.oceanbase.tools.dbbrowser.util.SqlBuilder;
import com.oceanbase.tools.dbbrowser.util.StringUtils;
+import com.oceanbase.tools.sqlparser.OBMySQLParser;
+import com.oceanbase.tools.sqlparser.SQLParser;
+import com.oceanbase.tools.sqlparser.statement.createtable.CreateTable;
+import com.oceanbase.tools.sqlparser.statement.createtable.TableOptions;
import lombok.extern.slf4j.Slf4j;
@@ -382,6 +387,11 @@ public List listPackages(String schemaName) {
throw new UnsupportedOperationException("Not supported yet");
}
+ @Override
+ public List listPackageBodies(String schemaName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
@Override
public List listTriggers(String schemaName) {
throw new UnsupportedOperationException("Not supported yet");
@@ -413,8 +423,8 @@ public Map> listTableColumns(String schemaName) {
@Override
public Map> listBasicTableColumns(String schemaName) {
- String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_COLUMNS);
- List tableColumns = jdbcOperations.query(sql, new Object[] {schemaName},
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_TABLE_COLUMNS);
+ List tableColumns = jdbcOperations.query(sql, new Object[] {schemaName, schemaName},
listBasicTableColumnRowMapper());
return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
}
@@ -425,6 +435,20 @@ public List listBasicTableColumns(String schemaName, String table
return jdbcOperations.query(sql, new Object[] {schemaName, tableName}, listBasicTableColumnRowMapper());
}
+ @Override
+ public Map> listBasicViewColumns(String schemaName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_VIEW_COLUMNS);
+ List tableColumns = jdbcOperations.query(sql, new Object[] {schemaName, schemaName},
+ listBasicTableColumnRowMapper());
+ return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public List listBasicViewColumns(String schemaName, String viewName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_VIEW_COLUMNS);
+ return jdbcOperations.query(sql, new Object[] {schemaName, viewName}, listBasicTableColumnRowMapper());
+ }
+
protected String getListTableColumnsSql(String schemaName) {
MySQLSqlBuilder sb = new MySQLSqlBuilder();
sb.append(
@@ -944,6 +968,7 @@ public List listTableIndexes(String schemaName, String tableName)
columnNames.add(rs.getString(MySQLConstants.IDX_COLUMN_NAME));
index.setColumnNames(columnNames);
index.setGlobal(true);
+ handleIndexAvailability(index, rs.getString(MySQLConstants.IDX_COL_COMMENT));
indexName2Index.put(indexName, index);
} else {
indexName2Index.get(indexName).getColumnNames().add(rs.getString(MySQLConstants.IDX_COLUMN_NAME));
@@ -953,6 +978,14 @@ public List listTableIndexes(String schemaName, String tableName)
return new ArrayList<>(indexName2Index.values());
}
+ protected void handleIndexAvailability(DBTableIndex index, String availability) {
+ if (StringUtils.isBlank(availability)) {
+ index.setAvailable(true);
+ } else if ("disabled".equals(availability)) {
+ index.setAvailable(false);
+ }
+ }
+
@Override
public String getTableDDL(String schemaName, String tableName) {
MySQLSqlBuilder sb = new MySQLSqlBuilder();
@@ -977,7 +1010,11 @@ public DBTableOptions getTableOptions(String schemaName, String tableName) {
public DBTableOptions getTableOptions(String schemaName, String tableName, @lombok.NonNull String ddl) {
DBTableOptions dbTableOptions = new DBTableOptions();
obtainOptionsByQuery(schemaName, tableName, dbTableOptions);
- DBSchemaAccessorUtil.obtainOptionsByParse(dbTableOptions, ddl);
+ try {
+ obtainOptionsByParser(dbTableOptions, ddl);
+ } catch (Exception e) {
+ log.warn("Failed to get table options by parse table ddl, message={}", e.getMessage());
+ }
return dbTableOptions;
}
@@ -992,6 +1029,23 @@ private void obtainOptionsByQuery(String schemaName, String tableName, DBTableOp
});
}
+ private void obtainOptionsByParser(DBTableOptions dbTableOptions, String ddl) {
+ SQLParser sqlParser = new OBMySQLParser();
+ CreateTable stmt = (CreateTable) sqlParser.parse(new StringReader(ddl));
+ TableOptions options = stmt.getTableOptions();
+ if (Objects.nonNull(options)) {
+ dbTableOptions.setCharsetName(options.getCharset());
+ dbTableOptions.setRowFormat(options.getRowFormat());
+ dbTableOptions.setCompressionOption(options.getCompression());
+ dbTableOptions.setReplicaNum(options.getReplicaNum());
+ dbTableOptions.setBlockSize(options.getBlockSize());
+ dbTableOptions.setUseBloomFilter(options.getUseBloomFilter());
+ dbTableOptions
+ .setTabletSize(
+ Objects.nonNull(options.getTabletSize()) ? options.getTabletSize().longValue() : null);
+ }
+ }
+
@Override
public DBView getView(String schemaName, String viewName) {
MySQLSqlBuilder sb = new MySQLSqlBuilder();
@@ -1009,7 +1063,7 @@ public DBView getView(String schemaName, String viewName) {
view.setDefiner(rs.getString(7));
});
MySQLSqlBuilder getDDL = new MySQLSqlBuilder();
- getDDL.append("show create view ");
+ getDDL.append("show create table ");
getDDL.identifier(schemaName);
getDDL.append(".");
getDDL.identifier(viewName);
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween2277And3XSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween2277And3XSchemaAccessor.java
index 839f255efb..7e8ce67aaf 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween2277And3XSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween2277And3XSchemaAccessor.java
@@ -18,6 +18,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.lang.NonNull;
@@ -217,4 +219,54 @@ public List listTableColumns(String schemaName, String tableName)
}
return super.listTableColumns(schemaName, tableName);
}
+
+ @Override
+ public Map> listBasicTableColumns(String schemaName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_TABLE_COLUMNS);
+ List tableColumns = jdbcOperations.query(sql, new Object[] {schemaName},
+ listBasicTableColumnRowMapper());
+ return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public Map> listBasicViewColumns(String schemaName) {
+ MySQLSqlBuilder sb = new MySQLSqlBuilder();
+ sb.append("select table_name from information_schema.views where table_schema=");
+ sb.value(schemaName);
+ List viewNames = jdbcOperations.query(sb.toString(), (rs, rowNum) -> rs.getString("table_name"));
+ List columns = new ArrayList<>();
+ for (String viewName : viewNames) {
+ columns.addAll(fillViewColumnInfoByDesc(schemaName, viewName));
+ }
+ return columns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public List listBasicViewColumns(String schemaName, String viewName) {
+ return fillViewColumnInfoByDesc(schemaName, viewName);
+ }
+
+ protected List fillViewColumnInfoByDesc(String schemaName, String viewName) {
+ List columns = new ArrayList<>();
+ try {
+ MySQLSqlBuilder sb = new MySQLSqlBuilder();
+ sb.append("desc ");
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.identifier(schemaName).append(".");
+ }
+ sb.identifier(viewName);
+ columns = jdbcOperations.query(sb.toString(), (rs, rowNum) -> {
+ DBTableColumn column = new DBTableColumn();
+ column.setSchemaName(schemaName);
+ column.setTableName(viewName);
+ column.setName(rs.getString(1));
+ column.setTypeName(rs.getString(2).split("\\(")[0]);
+ return column;
+ });
+ } catch (Exception e) {
+ log.warn("fail to get view column info, message={}", e.getMessage());
+ }
+ return columns;
+ }
+
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLSchemaAccessor.java
index 51a20259e8..1868f83254 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLSchemaAccessor.java
@@ -192,6 +192,15 @@ public List listTableIndexes(String schemaName, String tableName)
return indexList;
}
+ @Override
+ protected void handleIndexAvailability(DBTableIndex index, String availability) {
+ if ("available".equals(availability)) {
+ index.setAvailable(true);
+ } else if ("unavailable".equals(availability)) {
+ index.setAvailable(false);
+ }
+ }
+
@Override
public Map> listTableIndexes(String schemaName) {
Map> tableName2Indexes = super.listTableIndexes(schemaName);
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/ODPOBMySQLSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/ODPOBMySQLSchemaAccessor.java
index d20c54bcce..6e5c5016e8 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/ODPOBMySQLSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/ODPOBMySQLSchemaAccessor.java
@@ -75,13 +75,18 @@ public List showTables(String schemaName) {
@Override
public List listTables(String schemaName, String tableNameLike) {
+ String sql = "select database()";
+ String currentSchema = jdbcOperations.queryForObject(sql, (rs, rowNum) -> rs.getString(1));
List results = new ArrayList<>();
MySQLSqlBuilder builder = new MySQLSqlBuilder();
- builder.append("show full tables from ")
- .identifier(schemaName)
- .append(" where Table_type='BASE TABLE'");
+ builder.append("show full tables");
+ if (StringUtils.isNotBlank(schemaName)) {
+ builder.append(" from ").identifier(schemaName);
+ }
+ builder.append(" where Table_type='BASE TABLE'");
List tables = jdbcOperations.query(builder.toString(), (rs, rowNum) -> rs.getString(1));
- tables.forEach(name -> results.add(DBObjectIdentity.of(schemaName, DBObjectType.TABLE, name)));
+ tables.forEach(name -> results.add(DBObjectIdentity
+ .of(StringUtils.isBlank(schemaName) ? currentSchema : schemaName, DBObjectType.TABLE, name)));
return results;
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleLessThan400SchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleLessThan400SchemaAccessor.java
index 5a459cdbd9..f5e9d53583 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleLessThan400SchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleLessThan400SchemaAccessor.java
@@ -18,6 +18,8 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcOperations;
@@ -25,6 +27,7 @@
import com.oceanbase.tools.dbbrowser.model.DBObjectIdentity;
import com.oceanbase.tools.dbbrowser.model.DBSynonymType;
import com.oceanbase.tools.dbbrowser.model.DBTable.DBTableOptions;
+import com.oceanbase.tools.dbbrowser.model.DBTableColumn;
import com.oceanbase.tools.dbbrowser.model.DBTablePartition;
import com.oceanbase.tools.dbbrowser.model.DBTablePartitionDefinition;
import com.oceanbase.tools.dbbrowser.model.DBTablePartitionOption;
@@ -141,4 +144,53 @@ protected String getSynonymOwnerSymbol(DBSynonymType synonymType, String schemaN
throw new UnsupportedOperationException("Not supported Synonym type");
}
}
+
+ @Override
+ public Map> listBasicTableColumns(String schemaName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_TABLE_COLUMNS);
+ List tableColumns =
+ jdbcOperations.query(sql, new Object[] {schemaName}, listBasicColumnsRowMapper());
+ return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public Map> listBasicViewColumns(String schemaName) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("select view_name from all_views where owner = ").value(schemaName);
+ List viewNames = jdbcOperations.query(sb.toString(), (rs, rowNum) -> rs.getString("view_name"));
+ List columns = new ArrayList<>();
+ for (String viewName : viewNames) {
+ columns.addAll(fillViewColumnInfoByDesc(schemaName, viewName));
+ }
+ return columns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public List listBasicViewColumns(String schemaName, String viewName) {
+ return fillViewColumnInfoByDesc(schemaName, viewName);
+ }
+
+ protected List fillViewColumnInfoByDesc(String schemaName, String viewName) {
+ List columns = new ArrayList<>();
+ try {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("desc ");
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.identifier(schemaName).append(".");
+ }
+ sb.identifier(viewName);
+ columns = jdbcOperations.query(sb.toString(), (rs, rowNum) -> {
+ DBTableColumn column = new DBTableColumn();
+ column.setSchemaName(schemaName);
+ column.setTableName(viewName);
+ column.setName(rs.getString(1));
+ column.setTypeName(rs.getString(2).split("\\(")[0]);
+ return column;
+ });
+ } catch (Exception e) {
+ log.warn("fail to get view column info, message={}", e.getMessage());
+ }
+ return columns;
+ }
+
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OracleSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OracleSchemaAccessor.java
index 29ce81f85c..231b4ebe7c 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OracleSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OracleSchemaAccessor.java
@@ -325,6 +325,26 @@ public List listPackages(String schemaName) {
});
}
+ @Override
+ public List listPackageBodies(String schemaName) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+
+ sb.append("select object_name as name, object_type as type, owner, status from ");
+ sb.append(dataDictTableNames.OBJECTS());
+ sb.append(" where object_type = 'PACKAGE BODY' and owner=");
+ sb.value(schemaName);
+ sb.append(" order by name asc");
+
+ return jdbcOperations.query(sb.toString(), (rs, rowNum) -> {
+ DBPLObjectIdentity dbPackage = new DBPLObjectIdentity();
+ dbPackage.setName(rs.getString("name"));
+ dbPackage.setStatus(rs.getString("status"));
+ dbPackage.setSchemaName(rs.getString("owner"));
+ dbPackage.setType(DBObjectType.getEnumByName(rs.getString("type")));
+ return dbPackage;
+ });
+ }
+
@Override
public List listTriggers(String schemaName) {
OracleSqlBuilder sb = new OracleSqlBuilder();
@@ -407,9 +427,9 @@ public Map> listTableColumns(String schemaName) {
@Override
public Map> listBasicTableColumns(String schemaName) {
- String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_COLUMNS);
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_TABLE_COLUMNS);
List tableColumns =
- jdbcOperations.query(sql, new Object[] {schemaName}, listBasicColumnsRowMapper());
+ jdbcOperations.query(sql, new Object[] {schemaName, schemaName}, listBasicColumnsRowMapper());
return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
}
@@ -419,6 +439,20 @@ public List listBasicTableColumns(String schemaName, String table
return jdbcOperations.query(sql, new Object[] {schemaName, tableName}, listBasicColumnsRowMapper());
}
+ @Override
+ public Map> listBasicViewColumns(String schemaName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_VIEW_COLUMNS);
+ List tableColumns =
+ jdbcOperations.query(sql, new Object[] {schemaName, schemaName}, listBasicColumnsRowMapper());
+ return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public List listBasicViewColumns(String schemaName, String viewName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_VIEW_COLUMNS);
+ return jdbcOperations.query(sql, new Object[] {schemaName, viewName}, listBasicColumnsRowMapper());
+ }
+
@Override
public Map> listTableIndexes(String schemaName) {
throw new UnsupportedOperationException("Not supported yet");
@@ -738,6 +772,7 @@ protected List obtainBasicIndexInfo(String schemaName, String tabl
index.setAlgorithm(DBIndexAlgorithm.fromString(rs.getString(OracleConstants.INDEX_TYPE)));
index.setCompressInfo(rs.getString(OracleConstants.INDEX_COMPRESSION));
index.setColumnNames(new ArrayList<>());
+ index.setAvailable("VALID".equals(rs.getString(OracleConstants.INDEX_STATUS)));
indexName2Index.putIfAbsent(index.getName(), index);
return index;
});
diff --git a/libs/db-browser/src/main/resources/schema/sql/mysql/mysql_5_7_40.yaml b/libs/db-browser/src/main/resources/schema/sql/mysql/mysql_5_7_40.yaml
index ae03cbb759..6b6c7fb7f3 100644
--- a/libs/db-browser/src/main/resources/schema/sql/mysql/mysql_5_7_40.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/mysql/mysql_5_7_40.yaml
@@ -1,5 +1,18 @@
sqls:
- list-basic-schema-columns: |-
+ list-basic-table-columns: |-
+ SELECT
+ TABLE_SCHEMA,
+ TABLE_NAME,
+ COLUMN_NAME,
+ DATA_TYPE,
+ COLUMN_COMMENT
+ FROM
+ information_schema.columns
+ WHERE
+ TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ ORDER BY
+ ORDINAL_POSITION ASC
+ list-basic-schema-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -10,10 +23,18 @@ sqls:
information_schema.columns
WHERE
TABLE_SCHEMA = ?
+ AND TABLE_NAME IN (
+ SELECT
+ TABLE_NAME
+ FROM
+ information_schema.tables
+ WHERE
+ TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE'
+ )
ORDER BY
TABLE_NAME ASC,
ORDINAL_POSITION ASC
- list-basic-table-columns: |-
+ list-basic-view-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -26,6 +47,28 @@ sqls:
TABLE_SCHEMA = ? AND TABLE_NAME = ?
ORDER BY
ORDINAL_POSITION ASC
+ list-basic-schema-view-columns: |-
+ SELECT
+ TABLE_SCHEMA,
+ TABLE_NAME,
+ COLUMN_NAME,
+ DATA_TYPE,
+ COLUMN_COMMENT
+ FROM
+ information_schema.columns
+ WHERE
+ TABLE_SCHEMA = ?
+ AND TABLE_NAME IN (
+ SELECT
+ TABLE_NAME
+ FROM
+ information_schema.tables
+ WHERE
+ TABLE_SCHEMA = ? AND TABLE_TYPE = 'VIEW'
+ )
+ ORDER BY
+ TABLE_NAME ASC,
+ ORDINAL_POSITION ASC
list-table-columns: |-
SELECT
TABLE_NAME,
diff --git a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_1_4_79.yaml b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_1_4_79.yaml
index a00b459630..482c4ab2f3 100644
--- a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_1_4_79.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_1_4_79.yaml
@@ -1,5 +1,5 @@
sqls:
- list-basic-schema-columns: |-
+ list-basic-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -9,11 +9,10 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ?
+ TABLE_SCHEMA = ? AND TABLE_NAME = ?
ORDER BY
- TABLE_NAME ASC,
ORDINAL_POSITION ASC
- list-basic-table-columns: |-
+ list-basic-schema-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -23,8 +22,9 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ TABLE_SCHEMA = ?
ORDER BY
+ TABLE_NAME ASC,
ORDINAL_POSITION ASC
list-table-columns: |-
SELECT
diff --git a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_5x.yaml b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_5x.yaml
index 7bc57b3d2c..e9133be2dd 100644
--- a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_5x.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_5x.yaml
@@ -1,5 +1,5 @@
sqls:
- list-basic-schema-columns: |-
+ list-basic-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -9,11 +9,10 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ?
+ TABLE_SCHEMA = ? AND TABLE_NAME = ?
ORDER BY
- TABLE_NAME ASC,
ORDINAL_POSITION ASC
- list-basic-table-columns: |-
+ list-basic-schema-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -23,8 +22,9 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ TABLE_SCHEMA = ?
ORDER BY
+ TABLE_NAME ASC,
ORDINAL_POSITION ASC
list-table-columns: |-
SELECT
diff --git a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_76.yaml b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_76.yaml
index d02abae26c..3b4132a889 100644
--- a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_76.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_2_2_76.yaml
@@ -1,5 +1,5 @@
sqls:
- list-basic-schema-columns: |-
+ list-basic-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -9,11 +9,10 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ?
+ TABLE_SCHEMA = ? AND TABLE_NAME = ?
ORDER BY
- TABLE_NAME ASC,
ORDINAL_POSITION ASC
- list-basic-table-columns: |-
+ list-basic-schema-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -23,8 +22,9 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ TABLE_SCHEMA = ?
ORDER BY
+ TABLE_NAME ASC,
ORDINAL_POSITION ASC
list-table-columns: |-
SELECT
diff --git a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_3_x.yaml b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_3_x.yaml
index 2d12dbdbc4..39a05f3e56 100644
--- a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_3_x.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_3_x.yaml
@@ -1,5 +1,5 @@
sqls:
- list-basic-schema-columns: |-
+ list-basic-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -9,11 +9,10 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ?
+ TABLE_SCHEMA = ? AND TABLE_NAME = ?
ORDER BY
- TABLE_NAME ASC,
ORDINAL_POSITION ASC
- list-basic-table-columns: |-
+ list-basic-schema-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -23,8 +22,9 @@ sqls:
FROM
information_schema.columns
WHERE
- TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ TABLE_SCHEMA = ?
ORDER BY
+ TABLE_NAME ASC,
ORDINAL_POSITION ASC
list-table-columns: |-
SELECT
diff --git a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_4_0_x.yaml b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_4_0_x.yaml
index 58ac152e79..a65009ff6c 100644
--- a/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_4_0_x.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_4_0_x.yaml
@@ -1,5 +1,18 @@
sqls:
- list-basic-schema-columns: |-
+ list-basic-table-columns: |-
+ SELECT
+ TABLE_SCHEMA,
+ TABLE_NAME,
+ COLUMN_NAME,
+ DATA_TYPE,
+ COLUMN_COMMENT
+ FROM
+ information_schema.columns
+ WHERE
+ TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ ORDER BY
+ ORDINAL_POSITION ASC
+ list-basic-schema-table-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -10,10 +23,18 @@ sqls:
information_schema.columns
WHERE
TABLE_SCHEMA = ?
+ AND TABLE_NAME IN (
+ SELECT
+ TABLE_NAME
+ FROM
+ information_schema.tables
+ WHERE
+ TABLE_SCHEMA = ? AND TABLE_TYPE = 'BASE TABLE'
+ )
ORDER BY
TABLE_NAME ASC,
ORDINAL_POSITION ASC
- list-basic-table-columns: |-
+ list-basic-view-columns: |-
SELECT
TABLE_SCHEMA,
TABLE_NAME,
@@ -26,6 +47,28 @@ sqls:
TABLE_SCHEMA = ? AND TABLE_NAME = ?
ORDER BY
ORDINAL_POSITION ASC
+ list-basic-schema-view-columns: |-
+ SELECT
+ TABLE_SCHEMA,
+ TABLE_NAME,
+ COLUMN_NAME,
+ DATA_TYPE,
+ COLUMN_COMMENT
+ FROM
+ information_schema.columns
+ WHERE
+ TABLE_SCHEMA = ?
+ AND TABLE_NAME IN (
+ SELECT
+ TABLE_NAME
+ FROM
+ information_schema.tables
+ WHERE
+ TABLE_SCHEMA = ? AND TABLE_TYPE = 'VIEW'
+ )
+ ORDER BY
+ TABLE_NAME ASC,
+ ORDINAL_POSITION ASC
list-table-columns: |-
SELECT
TABLE_NAME,
diff --git a/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_3_x.yaml b/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_3_x.yaml
index e95c3d2344..cd0bbb4234 100644
--- a/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_3_x.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_3_x.yaml
@@ -7,12 +7,12 @@ sqls:
DATA_TYPE,
COMMENTS
FROM
- ALL_TAB_COLS NATURAL JOIN ALL_COL_COMMENTS
+ SYS.ALL_TAB_COLS NATURAL JOIN SYS.ALL_COL_COMMENTS
WHERE
OWNER = ? AND TABLE_NAME = ?
ORDER BY
COLUMN_ID ASC
- list-basic-schema-columns: |-
+ list-basic-schema-table-columns: |-
SELECT
OWNER,
TABLE_NAME,
@@ -20,11 +20,11 @@ sqls:
DATA_TYPE,
COMMENTS
FROM
- ALL_TAB_COLS NATURAL JOIN ALL_COL_COMMENTS
+ SYS.ALL_TAB_COLS NATURAL JOIN SYS.ALL_COL_COMMENTS
WHERE
OWNER = ?
ORDER BY
- TABLE_NAME ASC,
+ TABLE_NAME ASC,
COLUMN_ID ASC
list-table-columns: |-
SELECT
@@ -81,7 +81,8 @@ sqls:
TABLE_NAME,
UNIQUENESS,
COMPRESSION,
- VISIBILITY
+ VISIBILITY,
+ STATUS
FROM
ALL_INDEXES
WHERE
diff --git a/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_0_x.yaml b/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_0_x.yaml
index 26253aa7f7..6955eda625 100644
--- a/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_0_x.yaml
+++ b/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_0_x.yaml
@@ -7,12 +7,12 @@ sqls:
DATA_TYPE,
COMMENTS
FROM
- ALL_TAB_COLS NATURAL JOIN ALL_COL_COMMENTS
+ SYS.ALL_TAB_COLS NATURAL JOIN SYS.ALL_COL_COMMENTS
WHERE
OWNER = ? AND TABLE_NAME = ?
ORDER BY
COLUMN_ID ASC
- list-basic-schema-columns: |-
+ list-basic-schema-table-columns: |-
SELECT
OWNER,
TABLE_NAME,
@@ -20,11 +20,54 @@ sqls:
DATA_TYPE,
COMMENTS
FROM
- ALL_TAB_COLS NATURAL JOIN ALL_COL_COMMENTS
+ SYS.ALL_TAB_COLS NATURAL JOIN SYS.ALL_COL_COMMENTS
WHERE
OWNER = ?
+ AND TABLE_NAME IN (
+ SELECT
+ TABLE_NAME
+ FROM
+ SYS.ALL_TABLES
+ WHERE
+ OWNER = ?
+ )
ORDER BY
- TABLE_NAME ASC,
+ TABLE_NAME ASC,
+ COLUMN_ID ASC
+ list-basic-view-columns: |-
+ SELECT
+ OWNER,
+ TABLE_NAME,
+ COLUMN_NAME,
+ DATA_TYPE,
+ COMMENTS
+ FROM
+ SYS.ALL_TAB_COLS NATURAL JOIN SYS.ALL_COL_COMMENTS
+ WHERE
+ OWNER = ? AND TABLE_NAME = ?
+ ORDER BY
+ COLUMN_ID ASC
+ list-basic-schema-view-columns: |-
+ SELECT
+ OWNER,
+ TABLE_NAME,
+ COLUMN_NAME,
+ DATA_TYPE,
+ COMMENTS
+ FROM
+ SYS.ALL_TAB_COLS NATURAL JOIN SYS.ALL_COL_COMMENTS
+ WHERE
+ OWNER = ?
+ AND TABLE_NAME IN (
+ SELECT
+ VIEW_NAME
+ FROM
+ SYS.ALL_VIEWS
+ WHERE
+ OWNER = ?
+ )
+ ORDER BY
+ TABLE_NAME ASC,
COLUMN_ID ASC
list-table-columns: |-
SELECT
@@ -81,7 +124,8 @@ sqls:
TABLE_NAME,
UNIQUENESS,
COMPRESSION,
- VISIBILITY
+ VISIBILITY,
+ STATUS
FROM
ALL_INDEXES
WHERE
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditorTest.java
index 55573521f4..e7d2dd571b 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/DBTableEditorTest.java
@@ -24,8 +24,8 @@
import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLColumnEditor;
import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLConstraintEditor;
import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLDBTablePartitionEditor;
-import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLTableEditor;
import com.oceanbase.tools.dbbrowser.editor.mysql.OBMySQLIndexEditor;
+import com.oceanbase.tools.dbbrowser.editor.mysql.OBMySQLTableEditor;
import com.oceanbase.tools.dbbrowser.editor.util.DBObjectTestUtils;
import com.oceanbase.tools.dbbrowser.model.DBTable;
import com.oceanbase.tools.dbbrowser.model.DBTableConstraint;
@@ -37,7 +37,7 @@ public class DBTableEditorTest {
@BeforeClass
public static void setUp() {
- tableEditor = new MySQLTableEditor(new OBMySQLIndexEditor(), new MySQLColumnEditor(),
+ tableEditor = new OBMySQLTableEditor(new OBMySQLIndexEditor(), new MySQLColumnEditor(),
new MySQLConstraintEditor(), new MySQLDBTablePartitionEditor());
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/MySQLTableEditorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/MySQLTableEditorTest.java
index ff3be9eac2..a946f53b39 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/MySQLTableEditorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/editor/MySQLTableEditorTest.java
@@ -22,8 +22,8 @@
import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLColumnEditor;
import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLConstraintEditor;
import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLDBTablePartitionEditor;
-import com.oceanbase.tools.dbbrowser.editor.mysql.MySQLTableEditor;
import com.oceanbase.tools.dbbrowser.editor.mysql.OBMySQLIndexEditor;
+import com.oceanbase.tools.dbbrowser.editor.mysql.OBMySQLTableEditor;
public class MySQLTableEditorTest {
@@ -31,7 +31,7 @@ public class MySQLTableEditorTest {
@Before
public void setUp() {
- tableEditor = new MySQLTableEditor(new OBMySQLIndexEditor(), new MySQLColumnEditor(),
+ tableEditor = new OBMySQLTableEditor(new OBMySQLIndexEditor(), new MySQLColumnEditor(),
new MySQLConstraintEditor(), new MySQLDBTablePartitionEditor());
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BasePropertiesEnv.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BasePropertiesEnv.java
index 1f5960828b..fbcb2859ed 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BasePropertiesEnv.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BasePropertiesEnv.java
@@ -22,8 +22,6 @@
import java.util.Arrays;
import java.util.Base64;
import java.util.Properties;
-import java.util.Set;
-import java.util.stream.Collectors;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
@@ -38,7 +36,7 @@
/**
* {@link BasePropertiesEnv}
- *
+ *
* @author yh263208
* @date 2023-02-21 14:08
* @since db-browser_1.0.0-SNAPSHOT
@@ -49,10 +47,14 @@ public abstract class BasePropertiesEnv {
private static final String TEST_CONFIG_FILE = "../../local-unit-test.properties";
private static final String ENCRYPTED_PREFIX = "ENC@";
private static final Properties PROPERTIES = new Properties();
+ private static final SecretKey SECRET_KEY = new SecretKey();
static {
try {
- PROPERTIES.load(new StringReader(readFromFile(new File(TEST_CONFIG_FILE))));
+ File file = new File(TEST_CONFIG_FILE);
+ if (file.exists()) {
+ PROPERTIES.load(new StringReader(readFromFile(file)));
+ }
} catch (IOException e) {
log.warn("Failed to read content");
throw new IllegalStateException(e);
@@ -61,11 +63,17 @@ public abstract class BasePropertiesEnv {
}
public static String get(@NonNull String key) {
- return PROPERTIES.getProperty(key);
- }
-
- public static Set getKeys() {
- return PROPERTIES.keySet().stream().map(Object::toString).collect(Collectors.toSet());
+ String property = PROPERTIES.getProperty(key);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ // Get from environment variable
+ key = StringUtils.replace(key, ".", "_").toUpperCase();
+ property = PropertiesUtil.getSystemProperty(key);
+ if (StringUtils.isNotBlank(property)) {
+ return decryptIfRequired(property);
+ }
+ return null;
}
private static String readFromFile(File file) throws IOException {
@@ -80,17 +88,17 @@ private static String readFromFile(File file) throws IOException {
}
private static void decryptIfRequired() {
- SecretKey secretKey = new SecretKey();
- for (Object key : PROPERTIES.keySet()) {
- String value = PROPERTIES.get(key).toString();
- if (!StringUtils.startsWith(value, ENCRYPTED_PREFIX)) {
- continue;
- }
- value = value.substring(ENCRYPTED_PREFIX.length());
- byte[] encrypted = Base64.getDecoder().decode(value.getBytes());
- byte[] decrypted = decrypt(encrypted, secretKey.getSecretKey().getBytes());
- PROPERTIES.put(key, new String(decrypted));
+ PROPERTIES.replaceAll((k, v) -> decryptIfRequired(PROPERTIES.get(k).toString()));
+ }
+
+ private static String decryptIfRequired(String value) {
+ if (!StringUtils.startsWith(value, ENCRYPTED_PREFIX)) {
+ return value;
}
+ value = value.substring(ENCRYPTED_PREFIX.length());
+ byte[] encrypted = Base64.getDecoder().decode(value.getBytes());
+ byte[] decrypted = decrypt(encrypted, SECRET_KEY.getSecretKey().getBytes());
+ return new String(decrypted);
}
public static byte[] decrypt(byte[] encrypted, byte[] password) {
@@ -121,28 +129,46 @@ private static byte[] zeroUnpad(byte[] decrypted) {
private static class SecretKey {
- private static final String ENV_FILE = "../../.env";
private static final String SECRET_ENV_KEY = "ODC_CONFIG_SECRET";
- private static final String SECRET_ENV_ACI_KEY = "ACI_VAR_ODC_CONFIG_SECRET";
- private final Properties envProperties;
- public SecretKey() {
- envProperties = getEnvProperties();
- }
+ public SecretKey() {}
public String getSecretKey() {
- String secretKey = getSystemProperty(SECRET_ENV_KEY);
- if (org.apache.commons.lang3.StringUtils.isNotBlank(secretKey)) {
- return secretKey;
- }
- secretKey = getSystemProperty(SECRET_ENV_ACI_KEY);
- if (org.apache.commons.lang3.StringUtils.isNotBlank(secretKey)) {
+ String secretKey = PropertiesUtil.getSystemProperty(SECRET_ENV_KEY);
+ if (StringUtils.isNotBlank(secretKey)) {
return secretKey;
}
throw new RuntimeException("environment variable 'ODC_CONFIG_SECRET' is not set");
}
- private Properties getEnvProperties() {
+ }
+
+ private static class PropertiesUtil {
+
+ private static final String ENV_FILE = "../../.env";
+ private static final Properties ENV_PROPERTIES;
+
+ static {
+ ENV_PROPERTIES = getEnvProperties();
+ }
+
+ public static String getSystemProperty(String key) {
+ String property = System.getProperty(key);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ property = System.getenv(key);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ property = ENV_PROPERTIES.getProperty(key);
+ if (StringUtils.isNotBlank(property)) {
+ return property;
+ }
+ return null;
+ }
+
+ private static Properties getEnvProperties() {
Properties properties = new Properties();
File file = new File(ENV_FILE);
if (file.exists()) {
@@ -157,21 +183,6 @@ private Properties getEnvProperties() {
return properties;
}
- private String getSystemProperty(String key) {
- String property = System.getProperty(key);
- if (org.apache.commons.lang3.StringUtils.isNoneBlank(property)) {
- return property;
- }
- property = System.getenv(key);
- if (org.apache.commons.lang3.StringUtils.isNotBlank(property)) {
- return property;
- }
- property = envProperties.getProperty(key);
- if (org.apache.commons.lang3.StringUtils.isNotBlank(property)) {
- return property;
- }
- return null;
- }
}
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BaseTestEnv.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BaseTestEnv.java
index f12188c087..58575058aa 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BaseTestEnv.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/env/BaseTestEnv.java
@@ -37,8 +37,8 @@
*
* @author yh263208
* @date 2023-02-21 15:06
- * @since db-browser_1.0.0-SNAPSHOT
* @see BasePropertiesEnv
+ * @since db-browser_1.0.0-SNAPSHOT
*/
@Slf4j
public abstract class BaseTestEnv extends BasePropertiesEnv {
@@ -55,7 +55,7 @@ public abstract class BaseTestEnv extends BasePropertiesEnv {
private static final String TEST_OB_ORACLE_DATABASE_NAME = generate().toUpperCase();
private static final String TEST_MYSQL_DATABASE_NAME = generate().toLowerCase();
- protected BaseTestEnv() {
+ static {
String obMysqlCommandLine = get(OB_MYSQL_COMMANDLINE_KEY);
ConnectionParseResult obMysqlParseResult = MySQLClientArgsParser.parse(obMysqlCommandLine);
initDataSource(obMysqlParseResult, OB_MYSQL_DS_KEY);
@@ -83,27 +83,27 @@ protected BaseTestEnv() {
Runtime.getRuntime().addShutdownHook(shutdownHookThread);
}
- protected DataSource getOBMySQLDataSource() {
+ protected static DataSource getOBMySQLDataSource() {
return DATASOURCE_MAP.get(OB_MYSQL_DS_KEY);
}
- protected DataSource getOBOracleDataSource() {
+ protected static DataSource getOBOracleDataSource() {
return DATASOURCE_MAP.get(OB_ORACLE_DS_KEY);
}
- protected DataSource getMySQLDataSource() {
+ protected static DataSource getMySQLDataSource() {
return DATASOURCE_MAP.get(MYSQL_DS_KEY);
}
- protected String getOBMySQLDataBaseName() {
+ protected static String getOBMySQLDataBaseName() {
return TEST_OB_MYSQL_DATABASE_NAME;
}
- protected String getOBOracleSchema() {
+ protected static String getOBOracleSchema() {
return TEST_OB_ORACLE_DATABASE_NAME;
}
- protected String getMySQLDataBaseName() {
+ protected static String getMySQLDataBaseName() {
return TEST_MYSQL_DATABASE_NAME;
}
@@ -136,7 +136,7 @@ private static String generate() {
return "dbbrowser_" + hostName + "_" + currentMillis;
}
- private void initDataSource(ConnectionParseResult parseResult, String dataSourceKey) {
+ private static void initDataSource(ConnectionParseResult parseResult, String dataSourceKey) {
clear(parseResult, dataSourceKey);
String jdbcUrl = buildOBJdbcUrl(parseResult);
String username = buildUser(parseResult);
@@ -186,7 +186,7 @@ private void initDataSource(ConnectionParseResult parseResult, String dataSource
parseResult.setDefaultDBName(origin);
}
- private void clear(ConnectionParseResult parseResult, String dataSourceKey) {
+ private static void clear(ConnectionParseResult parseResult, String dataSourceKey) {
String jdbcUrl = buildOBJdbcUrl(parseResult);
String username = buildUser(parseResult);
if (OB_MYSQL_DS_KEY.equals(dataSourceKey)) {
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessors.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessors.java
index 94b95905f2..a6fd8f0e27 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessors.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessors.java
@@ -17,6 +17,7 @@
import javax.sql.DataSource;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -54,6 +55,9 @@ private String getOBVersion() {
}
return rs.getString(2);
});
+ if (StringUtils.isBlank(v)) {
+ throw new IllegalStateException("failed to get OB's version, reason: result set is empty");
+ }
return parseObVersionComment(v);
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/MySQLNoGreaterThan5740SchemaAccessorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/MySQLNoGreaterThan5740SchemaAccessorTest.java
index 20f778f466..38c29efe7d 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/MySQLNoGreaterThan5740SchemaAccessorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/MySQLNoGreaterThan5740SchemaAccessorTest.java
@@ -21,11 +21,12 @@
import java.util.Arrays;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.stream.Collectors;
-import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -54,17 +55,18 @@
* @date 2023/6/8
*/
public class MySQLNoGreaterThan5740SchemaAccessorTest extends BaseTestEnv {
- private final String BASE_PATH = "src/test/resources/table/mysql/";
- private String ddl;
- private String dropTables;
- private String testProcedureDDL;
- private String testFunctionDDL;
- private List verifyDataTypes = new ArrayList<>();
- private List columnAttributes = new ArrayList<>();
- private JdbcTemplate jdbcTemplate = new JdbcTemplate(getMySQLDataSource());
-
- @Before
- public void setUp() throws Exception {
+ private static final String BASE_PATH = "src/test/resources/table/mysql/";
+ private static String ddl;
+ private static String dropTables;
+ private static String testProcedureDDL;
+ private static String testFunctionDDL;
+ private static List verifyDataTypes = new ArrayList<>();
+ private static List columnAttributes = new ArrayList<>();
+ private static JdbcTemplate jdbcTemplate = new JdbcTemplate(getMySQLDataSource());
+ private static DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
initVerifyDataTypes();
initVerifyColumnAttributes();
@@ -82,12 +84,12 @@ public void setUp() throws Exception {
batchExecuteSql(testProcedureDDL, "/");
}
- @After
- public void tearDown() {
+ @AfterClass
+ public static void tearDown() {
batchExecuteSql(dropTables, ";");
}
- private void batchExecuteSql(String str, String delimiter) {
+ private static void batchExecuteSql(String str, String delimiter) {
for (String ddl : Arrays.stream(str.split(delimiter)).filter(item -> StringUtils.isNotBlank(item)).collect(
Collectors.toList())) {
jdbcTemplate.execute(ddl);
@@ -96,21 +98,18 @@ private void batchExecuteSql(String str, String delimiter) {
@Test
public void getDatabase_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBDatabase database = accessor.getDatabase(getMySQLDataBaseName());
Assert.assertNotNull(database);
}
@Test
public void listDatabases_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List databases = accessor.listDatabases();
Assert.assertTrue(databases.size() > 0);
}
@Test
public void listTableColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List columns =
accessor.listTableColumns(getMySQLDataBaseName(), "test_data_type");
Assert.assertEquals(columns.size(), verifyDataTypes.size());
@@ -124,7 +123,6 @@ public void listTableColumns_TestAllColumnDataTypes_Success() {
@Test
public void listTableColumns_TestColumnAttributesOtherThanDataType_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List columns =
accessor.listTableColumns(getMySQLDataBaseName(), "test_other_than_data_type");
Assert.assertEquals(columns.size(), columnAttributes.size());
@@ -140,7 +138,6 @@ public void listTableColumns_TestColumnAttributesOtherThanDataType_Success() {
@Test
public void listTableIndex_TestIndexType_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List indexList = accessor.listTableIndexes(getMySQLDataBaseName(), "test_index_type");
Assert.assertEquals(5, indexList.size());
Assert.assertEquals(DBIndexAlgorithm.BTREE, indexList.get(0).getAlgorithm());
@@ -154,9 +151,14 @@ public void listTableIndex_TestIndexType_Success() {
Assert.assertEquals(DBIndexType.FULLTEXT, indexList.get(4).getType());
}
+ @Test
+ public void listTableIndex_TestIndexAvailable_Success() {
+ List indexList = accessor.listTableIndexes(getMySQLDataBaseName(), "test_index_type");
+ Assert.assertTrue(indexList.get(0).getAvailable());
+ }
+
@Test
public void listTableIndex_get_all_index_in_schema_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
Map> map = accessor.listTableIndexes(getMySQLDataBaseName());
Assert.assertNotNull(map);
Assert.assertTrue(map.size() > 0);
@@ -164,7 +166,6 @@ public void listTableIndex_get_all_index_in_schema_Success() {
@Test
public void listTableConstraint_TestForeignKey_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List constraintListList =
accessor.listTableConstraints(getMySQLDataBaseName(), "test_fk_child");
Assert.assertEquals(1, constraintListList.size());
@@ -174,7 +175,6 @@ public void listTableConstraint_TestForeignKey_Success() {
@Test
public void listTableConstraint_TestPrimaryKey_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List constraintListList =
accessor.listTableConstraints(getMySQLDataBaseName(), "test_fk_parent");
Assert.assertEquals(1, constraintListList.size());
@@ -184,28 +184,24 @@ public void listTableConstraint_TestPrimaryKey_Success() {
@Test
public void listSystemViews_information_schema_not_empty() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List viewNames = accessor.showSystemViews("information_schema");
Assert.assertTrue(!viewNames.isEmpty());
}
@Test
public void listAllSystemViews_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List sysViews = accessor.listAllSystemViews();
Assert.assertTrue(sysViews != null && sysViews.size() > 0);
}
@Test
public void listSystemViews_databaseNotFound_empty() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List viewNames = accessor.showSystemViews("databaseNotExists");
Assert.assertTrue(viewNames.isEmpty());
}
@Test
public void getPartition_Hash_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBTablePartition partition =
accessor.getPartition(getMySQLDataBaseName(), "part_hash");
Assert.assertEquals(5L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -214,7 +210,6 @@ public void getPartition_Hash_Success() {
@Test
public void getPartition_List_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBTablePartition partition =
accessor.getPartition(getMySQLDataBaseName(), "part_list");
Assert.assertEquals(5L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -224,7 +219,6 @@ public void getPartition_List_Success() {
@Test
public void getPartition_Range_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBTablePartition partition =
accessor.getPartition(getMySQLDataBaseName(), "part_range");
Assert.assertEquals(3L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -234,7 +228,6 @@ public void getPartition_Range_Success() {
@Test
public void listTableOptions_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
Map table2Options =
accessor.listTableOptions(getMySQLDataBaseName());
Assert.assertTrue(table2Options.containsKey("part_hash"));
@@ -242,28 +235,24 @@ public void listTableOptions_Success() {
@Test
public void showTablelike_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List tables = accessor.listTables(getMySQLDataBaseName(), null);
Assert.assertTrue(tables != null && tables.size() > 0);
}
@Test
public void showViews_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List views = accessor.listViews(getMySQLDataBaseName());
Assert.assertTrue(views != null && views.size() == 2);
}
@Test
public void getView_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBView view = accessor.getView(getMySQLDataBaseName(), "view_test1");
Assert.assertTrue(view != null && view.getColumns().size() == 2);
}
@Test
public void showVariables_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List variables = accessor.showVariables();
List sessionVariables = accessor.showSessionVariables();
List globalVariables = accessor.showGlobalVariables();
@@ -274,7 +263,6 @@ public void showVariables_Success() {
@Test
public void getFunction_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBFunction function = accessor.getFunction(getMySQLDataBaseName(), "function_test");
Assert.assertTrue(function != null
&& function.getParams().size() == 2
@@ -283,7 +271,6 @@ public void getFunction_Success() {
@Test
public void getProcedure_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
DBProcedure procedure = accessor.getProcedure(getMySQLDataBaseName(), "procedure_detail_test");
Assert.assertTrue(procedure != null
&& procedure.getParams().size() == 2
@@ -292,19 +279,26 @@ public void getProcedure_Success() {
@Test
public void showTables_unknowDatabase_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getMySQLDataSource()).createMysql();
List tables = accessor.showTables("abc");
Assert.assertTrue(tables.size() == 0);
}
- private void initVerifyColumnAttributes() {
+ @Test
+ public void getTableOptions_Success() {
+ DBTableOptions options =
+ accessor.getTableOptions(getMySQLDataBaseName(), "test_data_type");
+ Assert.assertTrue(Objects.nonNull(options.getCharsetName()));
+ Assert.assertTrue(Objects.nonNull(options.getCollationName()));
+ }
+
+ private static void initVerifyColumnAttributes() {
columnAttributes.addAll(Arrays.asList(
MySQLNoGreaterThan5740SchemaAccessorTest.ColumnAttributes.of("col1", false, false, true, null,
"col1_comments"),
MySQLNoGreaterThan5740SchemaAccessorTest.ColumnAttributes.of("col2", true, false, false, null, "")));
}
- private void initVerifyDataTypes() {
+ private static void initVerifyDataTypes() {
verifyDataTypes.addAll(Arrays.asList(
MySQLNoGreaterThan5740SchemaAccessorTest.DataType.of("col1", "int", 10, 10L, 0, null),
MySQLNoGreaterThan5740SchemaAccessorTest.DataType.of("col2", "decimal", 10, 10L, 2, 2),
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBMySQLSchemaAccessorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBMySQLSchemaAccessorTest.java
index a9c58d9c40..6395bf1322 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBMySQLSchemaAccessorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBMySQLSchemaAccessorTest.java
@@ -22,9 +22,9 @@
import java.util.List;
import java.util.Map;
-import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
-import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -53,17 +53,18 @@
* @author jingtian
*/
public class OBMySQLSchemaAccessorTest extends BaseTestEnv {
- private final String BASE_PATH = "src/test/resources/table/obmysql/";
- private String ddl;
- private String dropTables;
- private String testProcedureDDL;
- private String testFunctionDDL;
- private List verifyDataTypes = new ArrayList<>();
- private List columnAttributes = new ArrayList<>();
- private JdbcTemplate jdbcTemplate = new JdbcTemplate(getOBMySQLDataSource());
-
- @Before
- public void setUp() throws Exception {
+ private static final String BASE_PATH = "src/test/resources/table/obmysql/";
+ private static String ddl;
+ private static String dropTables;
+ private static String testProcedureDDL;
+ private static String testFunctionDDL;
+ private static List verifyDataTypes = new ArrayList<>();
+ private static List columnAttributes = new ArrayList<>();
+ private static final JdbcTemplate jdbcTemplate = new JdbcTemplate(getOBMySQLDataSource());
+ private static DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
initVerifyDataTypes();
initVerifyColumnAttributes();
@@ -81,12 +82,12 @@ public void setUp() throws Exception {
batchExcuteSql(testFunctionDDL);
}
- @After
- public void tearDown() throws Exception {
+ @AfterClass
+ public static void tearDown() throws Exception {
jdbcTemplate.execute(dropTables);
}
- private void batchExcuteSql(String str) {
+ private static void batchExcuteSql(String str) {
for (String ddl : str.split("/")) {
jdbcTemplate.execute(ddl);
}
@@ -94,7 +95,6 @@ private void batchExcuteSql(String str) {
@Test
public void listUsers_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List dbUsers = accessor.listUsers();
Assert.assertFalse(dbUsers.isEmpty());
Assert.assertSame(DBObjectType.USER, dbUsers.get(0).getType());
@@ -103,7 +103,6 @@ public void listUsers_Success() {
@Test
public void listBasicSchemaColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
Map> columns = accessor.listBasicTableColumns(getOBMySQLDataBaseName());
Assert.assertTrue(columns.containsKey("test_data_type"));
Assert.assertEquals(verifyDataTypes.size(), columns.get("test_data_type").size());
@@ -111,7 +110,6 @@ public void listBasicSchemaColumns_TestAllColumnDataTypes_Success() {
@Test
public void listBasicTableColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List columns =
accessor.listBasicTableColumns(getOBMySQLDataBaseName(), "test_data_type");
Assert.assertEquals(columns.size(), verifyDataTypes.size());
@@ -121,9 +119,23 @@ public void listBasicTableColumns_TestAllColumnDataTypes_Success() {
}
}
+ @Test
+ public void listBasicViewColumns_SchemaViewColumns_Success() {
+ Map> columns = accessor.listBasicViewColumns(getOBMySQLDataBaseName());
+ Assert.assertTrue(columns.containsKey("view_test1"));
+ Assert.assertTrue(columns.containsKey("view_test2"));
+ Assert.assertEquals(2, columns.get("view_test1").size());
+ Assert.assertEquals(1, columns.get("view_test2").size());
+ }
+
+ @Test
+ public void listBasicViewColumns_ViewColumns_Success() {
+ List columns = accessor.listBasicViewColumns(getOBMySQLDataBaseName(), "view_test1");
+ Assert.assertEquals(2, columns.size());
+ }
+
@Test
public void listTableColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List columns =
accessor.listTableColumns(getOBMySQLDataBaseName(), "test_data_type");
Assert.assertEquals(columns.size(), verifyDataTypes.size());
@@ -137,7 +149,6 @@ public void listTableColumns_TestAllColumnDataTypes_Success() {
@Test
public void listTableColumns_TestColumnAttributesOtherThanDataType_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List columns =
accessor.listTableColumns(getOBMySQLDataBaseName(), "test_other_than_data_type");
Assert.assertEquals(columns.size(), columnAttributes.size());
@@ -153,7 +164,6 @@ public void listTableColumns_TestColumnAttributesOtherThanDataType_Success() {
@Test
public void listTableIndex_TestIndexType_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List indexList = accessor.listTableIndexes(getOBMySQLDataBaseName(), "test_index_type");
Assert.assertEquals(2, indexList.size());
Assert.assertEquals(DBIndexAlgorithm.BTREE, indexList.get(0).getAlgorithm());
@@ -162,23 +172,26 @@ public void listTableIndex_TestIndexType_Success() {
@Test
public void listTableIndex_TestIndexRange_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List indexList = accessor.listTableIndexes(getOBMySQLDataBaseName(), "test_index_range");
Assert.assertEquals(2, indexList.size());
Assert.assertEquals(true, indexList.get(0).getGlobal());
Assert.assertEquals(false, indexList.get(1).getGlobal());
}
+ @Test
+ public void listTableIndex_TestIndexAvailable_Success() {
+ List indexList = accessor.listTableIndexes(getOBMySQLDataBaseName(), "test_index_type");
+ Assert.assertTrue(indexList.get(0).getAvailable());
+ }
+
@Test
public void listTableIndex_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
Map> indexes = accessor.listTableIndexes(getOBMySQLDataBaseName());
Assert.assertTrue(indexes.size() > 0);
}
@Test
public void listTableConstraint_TestForeignKey_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List constraintListList =
accessor.listTableConstraints(getOBMySQLDataBaseName(), "test_fk_child");
Assert.assertEquals(1, constraintListList.size());
@@ -188,7 +201,6 @@ public void listTableConstraint_TestForeignKey_Success() {
@Test
public void listTableConstraint_TestPrimaryKey_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List constraintListList =
accessor.listTableConstraints(getOBMySQLDataBaseName(), "test_fk_parent");
Assert.assertEquals(1, constraintListList.size());
@@ -217,28 +229,24 @@ public void testParseType_ContainsEmptyString_Success() {
@Test
public void listSystemViews_information_schema_not_empty() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List viewNames = accessor.showSystemViews("information_schema");
Assert.assertTrue(!viewNames.isEmpty());
}
@Test
public void listAllSystemViews_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List sysViews = accessor.listAllSystemViews();
Assert.assertTrue(sysViews != null && sysViews.size() > 0);
}
@Test
public void listSystemViews_databaseNotFound_empty() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List viewNames = accessor.showSystemViews("databaseNotExists");
Assert.assertTrue(viewNames.isEmpty());
}
@Test
public void getPartition_Hash_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBTablePartition partition =
accessor.getPartition(getOBMySQLDataBaseName(), "part_hash");
Assert.assertEquals(5L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -247,7 +255,6 @@ public void getPartition_Hash_Success() {
@Test
public void getTableOptions_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBTableOptions options =
accessor.getTableOptions(getOBMySQLDataBaseName(), "part_hash");
Assert.assertEquals("utf8mb4", options.getCharsetName());
@@ -255,7 +262,6 @@ public void getTableOptions_Success() {
@Test
public void listTableOptions_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
Map table2Options =
accessor.listTableOptions(getOBMySQLDataBaseName());
Assert.assertTrue(table2Options.containsKey("part_hash"));
@@ -263,28 +269,24 @@ public void listTableOptions_Success() {
@Test
public void showTablelike_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List tables = accessor.listTables(getOBMySQLDataBaseName(), null);
Assert.assertTrue(tables != null && tables.size() > 0);
}
@Test
public void showViews_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List views = accessor.listViews(getOBMySQLDataBaseName());
Assert.assertTrue(views != null && views.size() == 2);
}
@Test
public void getView_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBView view = accessor.getView(getOBMySQLDataBaseName(), "view_test1");
Assert.assertTrue(view != null && view.getColumns().size() == 2);
}
@Test
public void showVariables_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List variables = accessor.showVariables();
List sessionVariables = accessor.showSessionVariables();
List globalVariables = accessor.showGlobalVariables();
@@ -295,28 +297,24 @@ public void showVariables_Success() {
@Test
public void showCharset_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List charset = accessor.showCharset();
Assert.assertTrue(charset != null && charset.size() > 0);
}
@Test
public void showCollation_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List collation = accessor.showCollation();
Assert.assertTrue(collation != null && collation.size() > 0);
}
@Test
public void listFunctions_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List functions = accessor.listFunctions(getOBMySQLDataBaseName());
Assert.assertTrue(functions != null && functions.size() == 1);
}
@Test
public void getFunction_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBFunction function = accessor.getFunction(getOBMySQLDataBaseName(), "function_test");
Assert.assertTrue(function != null
&& function.getParams().size() == 2
@@ -325,14 +323,12 @@ public void getFunction_Success() {
@Test
public void listProcedures_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List procedures = accessor.listProcedures(getOBMySQLDataBaseName());
Assert.assertTrue(!procedures.isEmpty());
}
@Test
public void getProcedure_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBProcedure procedure = accessor.getProcedure(getOBMySQLDataBaseName(), "procedure_detail_test");
Assert.assertTrue(procedure != null
&& procedure.getParams().size() == 2
@@ -341,7 +337,6 @@ public void getProcedure_Success() {
@Test
public void getProcedure_without_parameters_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBProcedure procedure = accessor.getProcedure(getOBMySQLDataBaseName(), "procedure_without_parameters");
Assert.assertTrue(procedure != null
&& procedure.getParams().size() == 0
@@ -350,21 +345,18 @@ public void getProcedure_without_parameters_Success() {
@Test
public void getDatabase_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBDatabase database = accessor.getDatabase(getOBMySQLDataBaseName());
Assert.assertNotNull(database);
}
@Test
public void listDatabases_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List databases = accessor.listDatabases();
Assert.assertTrue(databases.size() > 0);
}
@Test
public void getPartition_List_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBTablePartition partition =
accessor.getPartition(getOBMySQLDataBaseName(), "part_list");
Assert.assertEquals(5L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -374,7 +366,6 @@ public void getPartition_List_Success() {
@Test
public void getPartition_Range_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
DBTablePartition partition =
accessor.getPartition(getOBMySQLDataBaseName(), "part_range");
Assert.assertEquals(3L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -384,18 +375,17 @@ public void getPartition_Range_Success() {
@Test
public void listTableColumns_test_in_mysql_schema_view_as_base_table_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBMySQLDataSource()).createOBMysql();
List columns = accessor.listTableColumns("mysql", "time_zone_transition");
Assert.assertEquals(3, columns.size());
}
- private void initVerifyColumnAttributes() {
+ private static void initVerifyColumnAttributes() {
columnAttributes.addAll(Arrays.asList(
ColumnAttributes.of("col1", false, false, true, null, "col1_comments"),
ColumnAttributes.of("col2", true, false, false, null, "")));
}
- private void initVerifyDataTypes() {
+ private static void initVerifyDataTypes() {
verifyDataTypes.addAll(Arrays.asList(
DataType.of("col1", "int", 11, 11L, 0, null),
DataType.of("col2", "decimal", 10, 10L, 2, 2),
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBOracleSchemaAccessorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBOracleSchemaAccessorTest.java
index 8a4a3a039a..b6ebd7f745 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBOracleSchemaAccessorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OBOracleSchemaAccessorTest.java
@@ -24,9 +24,10 @@
import java.util.Random;
import java.util.stream.Collectors;
-import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
-import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -64,21 +65,22 @@
* @author jingtian
*/
public class OBOracleSchemaAccessorTest extends BaseTestEnv {
- private final String BASE_PATH = "src/test/resources/table/oracle/";
- private String ddl;
- private String dropTables;
- private String testFunctionDDL;
- private String testPackageDDL;
- private String testProcedureDDL;
- private String testTriggerDDL;
- private List verifyDataTypes = new ArrayList<>();
- private List columnAttributes = new ArrayList<>();
- private JdbcTemplate jdbcTemplate = new JdbcTemplate(getOBOracleDataSource());
- private final String typeName = "emp_type_" + new Random().nextInt(10000);
-
-
- @Before
- public void before() throws Exception {
+ private static final String BASE_PATH = "src/test/resources/table/oracle/";
+ private static String ddl;
+ private static String dropTables;
+ private static String testFunctionDDL;
+ private static String testPackageDDL;
+ private static String testProcedureDDL;
+ private static String testTriggerDDL;
+ private static List verifyDataTypes = new ArrayList<>();
+ private static List columnAttributes = new ArrayList<>();
+ private static JdbcTemplate jdbcTemplate = new JdbcTemplate(getOBOracleDataSource());
+ private static final String typeName = "emp_type_" + new Random().nextInt(10000);
+ private static final DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
+
+
+ @BeforeClass
+ public static void before() throws Exception {
initVerifyDataTypes();
initVerifyColumnAttributes();
@@ -102,12 +104,12 @@ public void before() throws Exception {
batchExcuteSql(testTriggerDDL);
}
- @After
- public void after() throws Exception {
+ @AfterClass
+ public static void after() throws Exception {
batchExcuteSql(dropTables);
}
- private void batchExcuteSql(String str) {
+ private static void batchExcuteSql(String str) {
for (String ddl : str.split("/")) {
jdbcTemplate.execute(ddl);
}
@@ -115,7 +117,6 @@ private void batchExcuteSql(String str) {
@Test
public void listUsers_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List dbUsers = accessor.listUsers();
Assert.assertFalse(dbUsers.isEmpty());
Assert.assertSame(DBObjectType.USER, dbUsers.get(0).getType());
@@ -124,14 +125,12 @@ public void listUsers_Success() {
@Test
public void listDatabases_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List databases = accessor.listDatabases();
Assert.assertTrue(databases.size() > 0);
}
@Test
public void listBasicSchemaColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
Map> columns = accessor.listBasicTableColumns(getOBOracleSchema());
Assert.assertTrue(columns.containsKey("TEST_DATA_TYPE"));
Assert.assertEquals(verifyDataTypes.size(), columns.get("TEST_DATA_TYPE").size());
@@ -139,7 +138,6 @@ public void listBasicSchemaColumns_TestAllColumnDataTypes_Success() {
@Test
public void listBasicTableColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List columns =
accessor.listBasicTableColumns(getOBOracleSchema(), "TEST_DATA_TYPE");
Assert.assertEquals(columns.size(), verifyDataTypes.size());
@@ -150,8 +148,23 @@ public void listBasicTableColumns_TestAllColumnDataTypes_Success() {
}
@Test
+ public void listBasicViewColumns_SchemaViewColumns_Success() {
+ Map> columns = accessor.listBasicViewColumns(getOBOracleSchema());
+ Assert.assertTrue(columns.containsKey("VIEW_TEST1"));
+ Assert.assertTrue(columns.containsKey("VIEW_TEST2"));
+ Assert.assertEquals(2, columns.get("VIEW_TEST1").size());
+ Assert.assertEquals(1, columns.get("VIEW_TEST2").size());
+ }
+
+ @Test
+ public void listBasicViewColumns_ViewColumns_Success() {
+ List columns = accessor.listBasicViewColumns(getOBOracleSchema(), "VIEW_TEST1");
+ Assert.assertEquals(2, columns.size());
+ }
+
+ @Test
+ @Ignore("TODO: fix this test")
public void listTableColumns_TestAllColumnDataTypes_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List columns =
accessor.listTableColumns(getOBOracleSchema(), "TEST_DATA_TYPE");
Assert.assertEquals(columns.size(), verifyDataTypes.size());
@@ -165,7 +178,6 @@ public void listTableColumns_TestAllColumnDataTypes_Success() {
@Test
public void listTableColumns_TestColumnAttributesOtherThanDataType_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List columns =
accessor.listTableColumns(getOBOracleSchema(), "TEST_OTHER_THAN_DATA_TYPE");
Assert.assertEquals(columns.size(), columnAttributes.size());
@@ -180,14 +192,12 @@ public void listTableColumns_TestColumnAttributesOtherThanDataType_Success() {
@Test
public void listTableColumns_TestGetAllColumnInSchema_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
Map> table2Columns = accessor.listTableColumns(getOBOracleSchema());
Assert.assertTrue(table2Columns.size() > 0);
}
@Test
public void listTableIndex_TestIndexType_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List indexList = accessor.listTableIndexes(getOBOracleSchema(), "TEST_INDEX_TYPE");
Assert.assertEquals(2, indexList.size());
Assert.assertEquals(DBIndexType.UNIQUE, indexList.get(0).getType());
@@ -198,16 +208,22 @@ public void listTableIndex_TestIndexType_Success() {
@Test
public void listTableIndex_TestIndexRange_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List indexList = accessor.listTableIndexes(getOBOracleSchema(), "TEST_INDEX_RANGE");
Assert.assertEquals(2, indexList.size());
Assert.assertEquals(true, indexList.get(0).getGlobal());
Assert.assertEquals(false, indexList.get(1).getGlobal());
}
+ @Test
+ public void listTableIndex_TestIndexAvailable_Success() {
+ List indexList = accessor.listTableIndexes(getOBOracleSchema(), "TEST_INDEX_RANGE");
+ Assert.assertEquals(2, indexList.size());
+ Assert.assertTrue(indexList.get(0).getAvailable());
+ Assert.assertTrue(indexList.get(1).getAvailable());
+ }
+
@Test
public void listTableConstraint_TestForeignKey_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List constraintListList =
accessor.listTableConstraints(getOBOracleSchema(), "TEST_FK_CHILD");
Assert.assertEquals(1, constraintListList.size());
@@ -219,7 +235,6 @@ public void listTableConstraint_TestForeignKey_Success() {
@Test
public void listTableConstraint_TestPrimaryKey_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List constraintListList =
accessor.listTableConstraints(getOBOracleSchema(), "TEST_FK_PARENT");
Assert.assertEquals(1, constraintListList.size());
@@ -231,7 +246,6 @@ public void listTableConstraint_TestPrimaryKey_Success() {
@Test
public void listTableConstraint_TestPrimaryKeyIndex_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List indexes =
accessor.listTableIndexes(getOBOracleSchema(), "TEST_PK_INDEX");
Assert.assertEquals(1, indexes.size());
@@ -240,7 +254,6 @@ public void listTableConstraint_TestPrimaryKeyIndex_Success() {
@Test
public void getPartition_Hash_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBTablePartition partition =
accessor.getPartition(getOBOracleSchema(), "part_hash");
Assert.assertEquals(5L, partition.getPartitionOption().getPartitionsNum().longValue());
@@ -249,7 +262,6 @@ public void getPartition_Hash_Success() {
@Test
public void getTableOptions_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBTableOptions options =
accessor.getTableOptions(getOBOracleSchema(), "part_hash");
Assert.assertEquals("this is a comment", options.getComment());
@@ -257,21 +269,18 @@ public void getTableOptions_Success() {
@Test
public void listSystemViews_databaseNotSYS_empty() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List viewNames = accessor.showSystemViews("notsys");
Assert.assertTrue(viewNames.isEmpty());
}
@Test
public void listSystemViews_databaseSYS_notEmpty() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List viewNames = accessor.showSystemViews("SYS");
Assert.assertTrue(!viewNames.isEmpty());
}
@Test
public void showVariables_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List variables = accessor.showVariables();
List sessionVariables = accessor.showSessionVariables();
List globalVariables = accessor.showGlobalVariables();
@@ -282,42 +291,36 @@ public void showVariables_Success() {
@Test
public void showCharset_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List charset = accessor.showCharset();
Assert.assertTrue(charset != null && charset.size() > 0);
}
@Test
public void showCollation_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List collation = accessor.showCollation();
Assert.assertTrue(collation != null && collation.size() > 0);
}
@Test
public void showViews_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List views = accessor.listViews(getOBOracleSchema());
Assert.assertTrue(views != null && views.size() == 2);
}
@Test
public void getView_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBView view = accessor.getView(getOBOracleSchema(), "VIEW_TEST1");
Assert.assertTrue(view != null && view.getColumns().size() == 2);
}
@Test
public void listFunctions_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List functions = accessor.listFunctions(getOBOracleSchema());
Assert.assertTrue(functions != null && functions.size() == 3);
}
@Test
public void listFunctions_invalidFunctionList() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List functions = accessor.listFunctions(getOBOracleSchema());
functions = functions.stream().filter(function -> {
if (StringUtils.equals(function.getName(), "INVALIDE_FUNC")) {
@@ -334,7 +337,6 @@ public void listFunctions_invalidFunctionList() {
@Test
public void getFunction_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBFunction function = accessor.getFunction(getOBOracleSchema(), "FUNC_DETAIL_TEST");
Assert.assertTrue(function != null
&& function.getParams().size() == 1
@@ -345,14 +347,12 @@ public void getFunction_Success() {
@Test
public void showProcedures_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List procedures = accessor.listProcedures(getOBOracleSchema());
Assert.assertTrue(procedures != null && procedures.size() >= 3);
}
@Test
public void showProcedures_invalidProcedureList() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List procedures = accessor.listProcedures(getOBOracleSchema());
procedures = procedures.stream().filter(procedure -> {
if (StringUtils.equals(procedure.getName(), "INVALID_PROCEDURE_TEST")) {
@@ -369,7 +369,6 @@ public void showProcedures_invalidProcedureList() {
@Test
public void getProcedure_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBProcedure procedure = accessor.getProcedure(getOBOracleSchema(), "PROCEDURE_DETAIL_TEST");
Assert.assertTrue(procedure != null
&& procedure.getParams().size() == 2
@@ -378,14 +377,12 @@ public void getProcedure_Success() {
@Test
public void listPackages_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List packages = accessor.listPackages(getOBOracleSchema());
Assert.assertTrue(packages != null && !packages.isEmpty());
}
@Test
public void listPackages_invalidPackageList() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List packages = accessor.listPackages(getOBOracleSchema());
boolean flag = false;
for (DBPLObjectIdentity dbPackage : packages) {
@@ -398,7 +395,6 @@ public void listPackages_invalidPackageList() {
@Test
public void getPackage_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBPackage dbPackage = accessor.getPackage(getOBOracleSchema(), "T_PACKAGE");
Assert.assertTrue(dbPackage != null
&& dbPackage.getPackageHead().getVariables().size() == 1
@@ -413,7 +409,6 @@ public void getPackage_Success() {
@Test
public void listriggers_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List triggers = accessor.listTriggers(getOBOracleSchema());
Assert.assertNotEquals(null, triggers);
boolean flag = false;
@@ -427,7 +422,6 @@ public void listriggers_Success() {
@Test
public void listTriggers_InvalidTriggerList() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List triggers = accessor.listTriggers(getOBOracleSchema());
boolean flag = false;
for (DBPLObjectIdentity trigger : triggers) {
@@ -440,7 +434,6 @@ public void listTriggers_InvalidTriggerList() {
@Test
public void getTrigger_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBTrigger trigger = accessor.getTrigger(getOBOracleSchema(), "TRIGGER_TEST");
Assert.assertNotNull(trigger);
Assert.assertEquals("TRIGGER_TEST", trigger.getTriggerName());
@@ -451,7 +444,6 @@ public void listTypes_Success() {
String createTypeDdl = String.format("CREATE TYPE \"%s\" AS OBJECT (name VARCHAR2(100), ssn NUMBER)", typeName);
jdbcTemplate.execute(createTypeDdl);
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List types = accessor.listTypes(getOBOracleSchema());
Assert.assertNotNull(types);
Assert.assertEquals(1, types.size());
@@ -465,7 +457,6 @@ public void getType_testTypeInfoForOracleObject() {
String createTypeDdl = String.format("CREATE TYPE \"%s\" AS OBJECT (name VARCHAR2(100), ssn NUMBER)", typeName);
jdbcTemplate.execute(createTypeDdl);
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBType type = accessor.getType(getOBOracleSchema(), typeName);
Assert.assertNotNull(type);
Assert.assertEquals(typeName, type.getTypeName());
@@ -479,7 +470,6 @@ public void getType_testTypeInfoForOracleVarray() {
String createTypeDdl = String.format("CREATE TYPE \"%s\" AS VARRAY(5) OF VARCHAR2(25);", typeName);
jdbcTemplate.execute(createTypeDdl);
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBType type = accessor.getType(getOBOracleSchema(), typeName);
Assert.assertNotNull(type);
Assert.assertEquals(typeName, type.getTypeName());
@@ -502,7 +492,6 @@ public void getType_testTypeInfoForOracleTable() {
String ddl = String.format("CREATE TYPE \"%s\" AS TABLE OF \"cust_address_typ2\";", typeName);
jdbcTemplate.execute(ddl);
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBType type = accessor.getType(getOBOracleSchema(), typeName);
Assert.assertNotNull(type);
Assert.assertEquals(typeName, type.getTypeName());
@@ -514,7 +503,6 @@ public void getType_testTypeInfoForOracleTable() {
@Test
public void listSynonyms_testPublicSynonymListForOracle() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List synonyms = accessor.listSynonyms(getOBOracleSchema(), DBSynonymType.PUBLIC);
Assert.assertNotEquals(0, synonyms.size());
boolean flag = false;
@@ -528,7 +516,6 @@ public void listSynonyms_testPublicSynonymListForOracle() {
@Test
public void listSynonyms_testCommonSynonymListForOracle() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List synonyms = accessor.listSynonyms(getOBOracleSchema(), DBSynonymType.COMMON);
Assert.assertNotEquals(0, synonyms.size());
boolean flag = false;
@@ -542,7 +529,6 @@ public void listSynonyms_testCommonSynonymListForOracle() {
@Test
public void getSynonym_testPublicSynonymInfoForOracle() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBSynonym synonym = accessor.getSynonym(getOBOracleSchema(), "PUBLIC_SYNONYM_TEST", DBSynonymType.PUBLIC);
Assert.assertNotNull(synonym);
Assert.assertEquals(DBSynonymType.PUBLIC, synonym.getSynonymType());
@@ -551,7 +537,6 @@ public void getSynonym_testPublicSynonymInfoForOracle() {
@Test
public void getSynonym_testCommonSynonymInfoForOracle() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBSynonym synonym = accessor.getSynonym(getOBOracleSchema(), "COMMON_SYNONYM_TEST", DBSynonymType.COMMON);
Assert.assertNotNull(synonym);
Assert.assertEquals(DBSynonymType.COMMON, synonym.getSynonymType());
@@ -560,21 +545,18 @@ public void getSynonym_testCommonSynonymInfoForOracle() {
@Test
public void getDatabase_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBDatabase database = accessor.getDatabase(getOBOracleSchema());
Assert.assertNotNull(database);
}
@Test
public void listSequences_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List sequences = accessor.listSequences(getOBOracleSchema());
Assert.assertTrue(sequences != null && !sequences.isEmpty());
}
@Test
public void getSequence_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
DBSequence sequence = accessor.getSequence(getOBOracleSchema(), "SEQ_TEST");
Assert.assertTrue(sequence != null && sequence.getName().equalsIgnoreCase("SEQ_TEST"));
Assert.assertEquals("CREATE SEQUENCE \"SEQ_TEST\" MINVALUE 1 MAXVALUE 10 INCREMENT BY 2 CACHE 5 ORDER CYCLE;",
@@ -583,7 +565,6 @@ public void getSequence_Success() {
@Test
public void listTables_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List tables =
accessor.listTables(getOBOracleSchema(), null);
Assert.assertTrue(tables.size() > 0);
@@ -592,7 +573,6 @@ public void listTables_Success() {
@Test
public void listTableColumns_test_default_null_Success() {
- DBSchemaAccessor accessor = new DBSchemaAccessors(getOBOracleDataSource()).createOBOracle();
List columns =
accessor.listTableColumns(getOBOracleSchema(), "TEST_DEFAULT_NULL");
Assert.assertTrue(columns.size() > 0);
@@ -602,14 +582,14 @@ public void listTableColumns_test_default_null_Success() {
Assert.assertEquals("'null'", columns.get(3).getDefaultValue());
}
- private void initVerifyColumnAttributes() {
+ private static void initVerifyColumnAttributes() {
columnAttributes.addAll(Arrays.asList(
ColumnAttributes.of("COL1", false, false, null, "col1_comments"),
ColumnAttributes.of("COL2", true, false, null, null),
ColumnAttributes.of("COL3", true, true, "(\"COL1\" + \"COL2\")", null)));
}
- private void initVerifyDataTypes() {
+ private static void initVerifyDataTypes() {
verifyDataTypes.addAll(Arrays.asList(
DataType.of("COL1", "NUMBER", 38, 38L, 0, 0),
DataType.of("COL2", "NUMBER", 0, 22L, 0, 0),
diff --git a/libs/db-browser/src/test/resources/table/mysql/testTableColumnDDl.sql b/libs/db-browser/src/test/resources/table/mysql/testTableColumnDDL.sql
similarity index 100%
rename from libs/db-browser/src/test/resources/table/mysql/testTableColumnDDl.sql
rename to libs/db-browser/src/test/resources/table/mysql/testTableColumnDDL.sql
diff --git a/libs/db-browser/src/test/resources/table/oracle/drop.sql b/libs/db-browser/src/test/resources/table/oracle/drop.sql
index 027b6ee668..cb9d3c9c68 100644
--- a/libs/db-browser/src/test/resources/table/oracle/drop.sql
+++ b/libs/db-browser/src/test/resources/table/oracle/drop.sql
@@ -8,7 +8,7 @@ BEGIN
WHERE table_name = upper(new_table);
IF v_count > 0
THEN
- EXECUTE IMMEDIATE 'drop table ' || new_table || ' purge';
+ EXECUTE IMMEDIATE 'drop table ' || new_table || ' cascade constraints purge';
END IF;
END;
/
diff --git a/libs/ob-sql-parser/README.md b/libs/ob-sql-parser/README.md
index 4219b9244b..b4bfa4d4cd 100644
--- a/libs/ob-sql-parser/README.md
+++ b/libs/ob-sql-parser/README.md
@@ -56,7 +56,7 @@ $ cd ob-odc/libs/ob-sql-parser
com.oceanbase
ob-sql-parser
- 1.1.1
+ 1.1.2
```
diff --git a/libs/ob-sql-parser/pom.xml b/libs/ob-sql-parser/pom.xml
index 3fc8d86e2f..6c125c155e 100644
--- a/libs/ob-sql-parser/pom.xml
+++ b/libs/ob-sql-parser/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.oceanbase
ob-sql-parser
- 1.1.1
+ 1.1.3
ob-sql-parser
https://github.com/oceanbase/odc/tree/main/libs/ob-sql-parser
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBMySQLParser.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBMySQLParser.java
index badbec5159..a72ebfdd58 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBMySQLParser.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBMySQLParser.java
@@ -52,7 +52,7 @@ protected String getStatementFactoryBasePackage() {
@Override
protected ParseTree doParse(OBParser parser) {
- return parser.stmt().getChild(0);
+ return parser.sql_stmt().stmt_list().stmt().getChild(0);
}
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBOracleSQLParser.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBOracleSQLParser.java
index 0218850844..fe8795bdd8 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBOracleSQLParser.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/OBOracleSQLParser.java
@@ -47,7 +47,7 @@ protected OBParser getParser(TokenStream tokens) {
@Override
protected ParseTree doParse(OBParser parser) {
- return parser.stmt().getChild(0);
+ return parser.sql_stmt().stmt_list().stmt().getChild(0);
}
@Override
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableActionFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableActionFactory.java
index 99d8048818..a1a81ee6ac 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableActionFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableActionFactory.java
@@ -33,11 +33,9 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Modify_partition_infoContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Name_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Opt_partition_range_or_listContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Relation_factorContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.alter.table.AlterTableAction;
import com.oceanbase.tools.sqlparser.statement.alter.table.AlterTableAction.AlterColumnBehavior;
-import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition;
import com.oceanbase.tools.sqlparser.statement.createtable.ConstraintState;
import com.oceanbase.tools.sqlparser.statement.createtable.OutOfLineConstraint;
@@ -76,7 +74,7 @@ public AlterTableAction visitAlter_table_action(Alter_table_actionContext ctx) {
ctx.table_option_list_space_seperated()).generate());
return alterTableAction;
} else if (ctx.RENAME() != null) {
- alterTableAction.setRenameToTable(getRelationFactor(ctx.relation_factor()));
+ alterTableAction.setRenameToTable(MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor()));
return alterTableAction;
} else if (ctx.CONVERT() != null && ctx.TO() != null) {
alterTableAction.setCharset(ctx.charset_name().getText());
@@ -84,6 +82,9 @@ public AlterTableAction visitAlter_table_action(Alter_table_actionContext ctx) {
alterTableAction.setCollation(ctx.collation().collation_name().getText());
}
return alterTableAction;
+ } else if (ctx.REFRESH() != null) {
+ alterTableAction.setRefresh(true);
+ return alterTableAction;
}
return visitChildren(ctx);
}
@@ -126,6 +127,9 @@ public AlterTableAction visitAlter_column_option(Alter_column_optionContext ctx)
behavior.setDefaultValue(MySQLTableElementFactory.getSignedLiteral(aCtx.signed_literal()));
}
alterTableAction.alterColumnBehavior(colRef, behavior);
+ } else if (ctx.RENAME() != null) {
+ ColumnReference ref = new MySQLColumnRefFactory(ctx.column_definition_ref()).generate();
+ alterTableAction.renameColumn(ref, ctx.column_name().getText());
}
return alterTableAction;
}
@@ -228,12 +232,6 @@ public AlterTableAction visitAlter_constraint_option(Alter_constraint_optionCont
return action;
}
- private RelationFactor getRelationFactor(Relation_factorContext ctx) {
- RelationFactor relationFactor = new RelationFactor(ctx, MySQLFromReferenceFactory.getRelation(ctx));
- relationFactor.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx));
- return relationFactor;
- }
-
private List getNames(Name_listContext context) {
List list = new ArrayList<>();
if (context.NAME_OB() != null && context.name_list() == null) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableFactory.java
index edd4697c81..7f8e208a97 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLAlterTableFactory.java
@@ -26,6 +26,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.alter.table.AlterTable;
import com.oceanbase.tools.sqlparser.statement.alter.table.AlterTableAction;
+import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import lombok.NonNull;
@@ -51,10 +52,15 @@ public AlterTable generate() {
@Override
public AlterTable visitAlter_table_stmt(Alter_table_stmtContext ctx) {
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
AlterTable alterTable = new AlterTable(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()),
+ factor.getRelation(),
getAlterTableActions(ctx.alter_table_actions()));
- alterTable.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ if (ctx.EXTERNAL() != null) {
+ alterTable.setExternal(true);
+ }
+ alterTable.setSchema(factor.getSchema());
+ alterTable.setUserVariable(factor.getUserVariable());
return alterTable;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLCreateTableFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLCreateTableFactory.java
index ee0d2c8364..3c7f429e30 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLCreateTableFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLCreateTableFactory.java
@@ -19,8 +19,8 @@
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Create_table_stmtContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Relation_factorContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
+import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import com.oceanbase.tools.sqlparser.statement.createtable.CreateTable;
import lombok.NonNull;
@@ -48,15 +48,18 @@ public CreateTable generate() {
@Override
public CreateTable visitCreate_table_stmt(Create_table_stmtContext ctx) {
- Relation_factorContext relationFactor = ctx.relation_factor();
- CreateTable createTable = new CreateTable(ctx, MySQLFromReferenceFactory.getRelation(relationFactor));
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
+ CreateTable createTable = new CreateTable(ctx, factor.getRelation());
if (ctx.temporary_option().TEMPORARY() != null) {
createTable.setTemporary(true);
+ } else if (ctx.temporary_option().EXTERNAL() != null) {
+ createTable.setExternal(true);
}
if (ctx.IF() != null && ctx.not() != null && ctx.EXISTS() != null) {
createTable.setIfNotExists(true);
}
- createTable.setSchema(MySQLFromReferenceFactory.getSchemaName(relationFactor));
+ createTable.setSchema(factor.getSchema());
+ createTable.setUserVariable(factor.getUserVariable());
if (ctx.table_element_list() != null) {
createTable.setTableElements(ctx.table_element_list().table_element().stream()
.map(c -> new MySQLTableElementFactory(c).generate()).collect(Collectors.toList()));
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDataTypeFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDataTypeFactory.java
index 340e37d321..2d6fc5422a 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDataTypeFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDataTypeFactory.java
@@ -21,6 +21,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
@@ -38,6 +39,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Date_year_type_iContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Datetime_type_iContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Float_type_iContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Geo_type_iContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Int_type_iContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_type_iContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Number_type_iContext;
@@ -64,40 +66,25 @@
*/
public class MySQLDataTypeFactory extends OBParserBaseVisitor implements StatementFactory {
- private final Data_typeContext dataTypeContext;
- private final Cast_data_typeContext castDataTypeContext;
+ private final ParserRuleContext parserRuleContext;
public MySQLDataTypeFactory(@NonNull Cast_data_typeContext castDataTypeContext) {
- this.dataTypeContext = null;
- this.castDataTypeContext = castDataTypeContext;
+ this.parserRuleContext = castDataTypeContext;
}
public MySQLDataTypeFactory(@NonNull Data_typeContext dataTypeContext) {
- this.castDataTypeContext = null;
- this.dataTypeContext = dataTypeContext;
+ this.parserRuleContext = dataTypeContext;
}
@Override
public DataType generate() {
- if (this.dataTypeContext != null) {
- return visit(this.dataTypeContext);
- }
- return visit(this.castDataTypeContext);
+ return visit(this.parserRuleContext);
}
@Override
public DataType visitData_type(Data_typeContext ctx) {
if (ctx.STRING_VALUE() != null) {
return new GeneralDataType(ctx, ctx.STRING_VALUE().getText(), null);
- } else if (ctx.text_type_i() != null) {
- CharacterType characterType = new CharacterType(ctx, (CharacterType) visit(ctx.text_type_i()));
- if (ctx.charset_name() != null) {
- characterType.setCharset(ctx.charset_name().getText());
- }
- if (ctx.collation() != null) {
- characterType.setCollation(ctx.collation().collation_name().getText());
- }
- return characterType;
}
return visitChildren(ctx);
}
@@ -119,7 +106,6 @@ public DataType visitCast_data_type(Cast_data_typeContext ctx) {
return visitChildren(ctx);
}
-
@Override
public DataType visitBinary_type_i(Binary_type_iContext ctx) {
List args = new ArrayList<>();
@@ -130,6 +116,11 @@ public DataType visitBinary_type_i(Binary_type_iContext ctx) {
return new GeneralDataType(ctx, ctx.getChild(0).getText(), args);
}
+ @Override
+ public DataType visitGeo_type_i(Geo_type_iContext ctx) {
+ return new GeneralDataType(ctx, ctx.getChild(0).getText(), null);
+ }
+
@Override
public DataType visitCharacter_type_i(Character_type_iContext ctx) {
BigDecimal len = null;
@@ -137,10 +128,24 @@ public DataType visitCharacter_type_i(Character_type_iContext ctx) {
if (arg != null) {
len = new BigDecimal(arg);
}
- CharacterType type = new CharacterType(ctx, ctx.CHARACTER().getText(), len);
+ List names = new ArrayList<>(2);
+ for (int i = 0; i < ctx.getChildCount(); i++) {
+ ParseTree parseTree = ctx.getChild(i);
+ if (!(parseTree instanceof TerminalNode)) {
+ break;
+ }
+ names.add(parseTree.getText());
+ }
+ CharacterType type = new CharacterType(ctx, String.join(" ", names), len);
if (ctx.BINARY() != null) {
type.setBinary(true);
}
+ if (ctx.charset_name() != null) {
+ type.setCharset(ctx.charset_name().getText());
+ }
+ if (ctx.collation() != null) {
+ type.setCollation(ctx.collation().collation_name().getText());
+ }
return type;
}
@@ -223,18 +228,29 @@ public DataType visitBool_type_i(Bool_type_iContext ctx) {
@Override
public DataType visitText_type_i(Text_type_iContext ctx) {
- if (ctx.character_type_i() != null) {
- return visit(ctx.character_type_i());
- }
BigDecimal len = null;
String arg = getLength(ctx.string_length_i());
if (arg != null) {
len = new BigDecimal(arg);
}
- CharacterType characterType = new CharacterType(ctx, ctx.getChild(0).getText(), len);
+ List names = new ArrayList<>(2);
+ for (int i = 0; i < ctx.getChildCount(); i++) {
+ ParseTree parseTree = ctx.getChild(i);
+ if (!(parseTree instanceof TerminalNode)) {
+ break;
+ }
+ names.add(parseTree.getText());
+ }
+ CharacterType characterType = new CharacterType(ctx, String.join(" ", names), len);
if (ctx.BINARY() != null) {
characterType.setBinary(true);
}
+ if (ctx.charset_name() != null) {
+ characterType.setCharset(ctx.charset_name().getText());
+ }
+ if (ctx.collation() != null) {
+ characterType.setCollation(ctx.collation().collation_name().getText());
+ }
return characterType;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDeleteFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDeleteFactory.java
index 3ca251102f..c78f28ad40 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDeleteFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLDeleteFactory.java
@@ -19,6 +19,7 @@
import java.util.List;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Delete_basic_stmtContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Delete_stmtContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Multi_delete_tableContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Relation_factor_with_starContext;
@@ -56,7 +57,8 @@ public Delete generate() {
}
@Override
- public Delete visitDelete_stmt(Delete_stmtContext ctx) {
+ public Delete visitDelete_stmt(Delete_stmtContext deleteCtx) {
+ Delete_basic_stmtContext ctx = deleteCtx.delete_basic_stmt();
Delete delete = null;
if (ctx.tbl_name() != null) {
MySQLFromReferenceFactory factory = new MySQLFromReferenceFactory(ctx.tbl_name());
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLExpressionFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLExpressionFactory.java
index 83400eb268..6774e3b8ec 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLExpressionFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLExpressionFactory.java
@@ -17,28 +17,45 @@
import java.math.BigDecimal;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.commons.collections4.CollectionUtils;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.obmysql.OBLexer;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Bit_exprContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Bool_priContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Case_exprContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Complex_func_exprContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Complex_string_literalContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Cur_date_funcContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Cur_time_funcContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Cur_timestamp_funcContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Date_paramsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.ExprContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Expr_constContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Expr_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.In_exprContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_on_responseContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_table_column_defContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_table_exists_column_defContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_table_exprContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_table_nested_column_defContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_table_ordinality_column_defContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_table_value_column_defContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Json_value_exprContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.LiteralContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Mock_jt_on_error_on_emptyContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_emptyContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_errorContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Opt_value_on_empty_or_error_or_mismatchContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Parameterized_trimContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.PredicateContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_no_parensContext;
@@ -55,6 +72,7 @@
import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.Operator;
import com.oceanbase.tools.sqlparser.statement.Statement;
+import com.oceanbase.tools.sqlparser.statement.common.BraceBlock;
import com.oceanbase.tools.sqlparser.statement.common.CharacterType;
import com.oceanbase.tools.sqlparser.statement.common.GeneralDataType;
import com.oceanbase.tools.sqlparser.statement.common.WindowSpec;
@@ -71,11 +89,10 @@
import com.oceanbase.tools.sqlparser.statement.expression.FunctionParam;
import com.oceanbase.tools.sqlparser.statement.expression.GroupConcat;
import com.oceanbase.tools.sqlparser.statement.expression.IntervalExpression;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOnOption;
import com.oceanbase.tools.sqlparser.statement.expression.NullExpression;
import com.oceanbase.tools.sqlparser.statement.expression.TextSearchMode;
import com.oceanbase.tools.sqlparser.statement.expression.WhenClause;
-import com.oceanbase.tools.sqlparser.statement.expression.WindowFunction;
-import com.oceanbase.tools.sqlparser.statement.select.OrderBy;
import lombok.NonNull;
@@ -89,25 +106,35 @@
*/
public class MySQLExpressionFactory extends OBParserBaseVisitor implements StatementFactory {
- private final ExprContext exprContext;
- private final Bit_exprContext bitExprContext;
+ private final ParserRuleContext parserRuleContext;
public MySQLExpressionFactory(@NonNull ExprContext exprContext) {
- this.bitExprContext = null;
- this.exprContext = exprContext;
+ this.parserRuleContext = exprContext;
+ }
+
+ public MySQLExpressionFactory() {
+ this.parserRuleContext = null;
}
public MySQLExpressionFactory(@NonNull Bit_exprContext bitExprContext) {
- this.exprContext = null;
- this.bitExprContext = bitExprContext;
+ this.parserRuleContext = bitExprContext;
+ }
+
+ public MySQLExpressionFactory(@NonNull LiteralContext literalContext) {
+ this.parserRuleContext = literalContext;
}
@Override
public Expression generate() {
- if (this.exprContext != null) {
- return visit(this.exprContext);
+ return visit(this.parserRuleContext);
+ }
+
+ @Override
+ public Expression visit(ParseTree tree) {
+ if (tree == null) {
+ return null;
}
- return visit(this.bitExprContext);
+ return super.visit(tree);
}
@Override
@@ -280,6 +307,22 @@ public Expression visitPredicate(PredicateContext ctx) {
return new CompoundExpression(ctx, left, right, operator);
}
+ @Override
+ public Expression visitLiteral(LiteralContext ctx) {
+ if (ctx.complex_string_literal() != null) {
+ return visit(ctx.complex_string_literal());
+ }
+ return new ConstExpression(ctx);
+ }
+
+ @Override
+ public Expression visitExpr_const(Expr_constContext ctx) {
+ if (ctx.literal() != null) {
+ return visit(ctx.literal());
+ }
+ return new ConstExpression(ctx);
+ }
+
@Override
public Expression visitSimple_expr(Simple_exprContext ctx) {
List simpleExprContexts = ctx.simple_expr();
@@ -310,7 +353,7 @@ public Expression visitSimple_expr(Simple_exprContext ctx) {
StatementFactory factory = new MySQLColumnRefFactory(ctx.column_ref());
return factory.generate();
} else if (ctx.expr_const() != null) {
- return new ConstExpression(ctx.expr_const());
+ return visit(ctx.expr_const());
} else if (ctx.expr_list() != null) {
if (ctx.ROW() == null) {
return visit(ctx.expr_list());
@@ -343,14 +386,28 @@ public Expression visitSimple_expr(Simple_exprContext ctx) {
} else if (ctx.window_function() != null) {
return visit(ctx.window_function());
} else if (ctx.USER_VARIABLE() != null) {
- return new ConstExpression(ctx.USER_VARIABLE());
+ if (CollectionUtils.isEmpty(ctx.relation_name())) {
+ return new ConstExpression(ctx.USER_VARIABLE());
+ }
+ List relations = ctx.relation_name().stream()
+ .map(RuleContext::getText).collect(Collectors.toList());
+ String column = relations.get(relations.size() - 1);
+ String relation = relations.get(relations.size() - 2);
+ String schema = null;
+ if (relations.size() >= 3) {
+ schema = relations.get(relations.size() - 3);
+ }
+ ColumnReference ref = new ColumnReference(ctx, schema, relation, column);
+ ref.setUserVariable(ctx.USER_VARIABLE().getText());
+ return ref;
} else if (ctx.column_definition_ref() != null) {
StatementFactory factory = new MySQLColumnRefFactory(ctx.column_definition_ref());
Operator operator = ctx.JSON_EXTRACT() == null ? Operator.JSON_EXTRACT_UNQUOTED : Operator.JSON_EXTRACT;
- return new CompoundExpression(ctx, factory.generate(),
- new ConstExpression(ctx.complex_string_literal()), operator);
+ return new CompoundExpression(ctx, factory.generate(), visit(ctx.complex_string_literal()), operator);
} else if (ctx.case_expr() != null) {
return visit(ctx.case_expr());
+ } else if (ctx.LeftBrace() != null && ctx.RightBrace() != null) {
+ return new BraceBlock(ctx, ctx.relation_name(0).getText(), visit(ctx.expr()));
}
return new DefaultExpression(ctx);
}
@@ -387,13 +444,13 @@ public Expression visitSimple_func_expr(Simple_func_exprContext ctx) {
} else {
if (CollectionUtils.isNotEmpty(ctx.expr())) {
params.addAll(ctx.expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList()));
+ .map(this::wrap).collect(Collectors.toList()));
} else if (ctx.expr_list() != null) {
params.addAll(ctx.expr_list().expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList()));
+ .map(this::wrap).collect(Collectors.toList()));
} else if (CollectionUtils.isNotEmpty(ctx.bit_expr())) {
params.addAll(ctx.bit_expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList()));
+ .map(this::wrap).collect(Collectors.toList()));
} else if (ctx.column_definition_ref() != null) {
StatementFactory factory =
new MySQLColumnRefFactory(ctx.column_definition_ref());
@@ -401,49 +458,62 @@ public Expression visitSimple_func_expr(Simple_func_exprContext ctx) {
} else if (ctx.expr_as_list() != null) {
params.addAll(ctx.expr_as_list().expr_with_opt_alias().stream().map(e -> {
if (e.column_label() == null && e.STRING_VALUE() == null) {
- return wrap(e.expr(), null);
+ return wrap(e.expr());
} else if (e.column_label() != null) {
- return wrap(e.expr(), e.column_label().getText());
+ ExpressionParam p = wrap(e.expr());
+ p.addOption(new ConstExpression(e.column_label()));
+ return p;
}
- return wrap(e.expr(), e.STRING_VALUE().getText());
+ ExpressionParam p = wrap(e.expr());
+ p.addOption(new ConstExpression(e.STRING_VALUE()));
+ return p;
}).collect(Collectors.toList()));
}
}
FunctionCall fCall = new FunctionCall(ctx, funcName, params);
- fCall.setParamsFlag(getParamFlags(ctx));
+ fCall.addOption(getAggregator(ctx));
return fCall;
}
+ @Override
+ public Expression visitComplex_string_literal(Complex_string_literalContext ctx) {
+ if (ctx.string_val_list() == null) {
+ return new ConstExpression(ctx);
+ }
+ List exprs = new ArrayList<>(ctx.string_val_list().STRING_VALUE().size());
+ exprs.add(new ConstExpression(ctx.STRING_VALUE()));
+ exprs.addAll(
+ ctx.string_val_list().STRING_VALUE().stream().map(ConstExpression::new).collect(Collectors.toList()));
+ return new CollectionExpression(ctx, exprs);
+ }
+
@Override
public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
if (ctx.GROUP_CONCAT() != null) {
List params = ctx.expr_list().expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList());
+ .map(this::wrap).collect(Collectors.toList());
GroupConcat fCall = new GroupConcat(ctx, params);
- if (ctx.SEPARATOR() != null) {
- fCall.setSeparator(ctx.STRING_VALUE().getText());
- }
+ fCall.addOption(getAggregator(ctx));
if (ctx.order_by() != null) {
- StatementFactory factory = new MySQLOrderByFactory(ctx.order_by());
- fCall.setOrderBy(factory.generate());
+ fCall.addOption(new MySQLOrderByFactory(ctx.order_by()).generate());
+ }
+ if (ctx.SEPARATOR() != null) {
+ fCall.addOption(new ConstExpression(ctx.SEPARATOR(), ctx.STRING_VALUE()));
}
- fCall.setParamsFlag(getParamFlags(ctx));
return fCall;
} else if (ctx.CAST() != null) {
- FunctionCall fCall = new FunctionCall(ctx, ctx.CAST().getText(),
- Collections.singletonList(wrap(ctx.expr(), null)));
- fCall.addParamsOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
- return fCall;
+ FunctionParam p = wrap(ctx.expr());
+ p.addOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
+ return new FunctionCall(ctx, ctx.CAST().getText(), Collections.singletonList(p));
} else if (ctx.CONVERT() != null) {
- FunctionCall fCall = new FunctionCall(ctx, ctx.CONVERT().getText(),
- Collections.singletonList(wrap(ctx.expr(), null)));
+ FunctionParam p = wrap(ctx.expr());
if (ctx.cast_data_type() != null) {
- fCall.addParamsOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
+ p.addOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
}
if (ctx.charset_name() != null) {
- fCall.addParamsOption(new ConstExpression(ctx.charset_name()));
+ p.addOption(new ConstExpression(ctx.charset_name()));
}
- return fCall;
+ return new FunctionCall(ctx, ctx.CONVERT().getText(), Collections.singletonList(p));
} else if (ctx.POSITION() != null) {
List params = new ArrayList<>();
params.add(new ExpressionParam(new CompoundExpression(ctx,
@@ -452,23 +522,24 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
} else if (ctx.substr_or_substring() != null) {
String funcName = ctx.substr_or_substring().getText();
List params = ctx.substr_params().expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList());
+ .map(this::wrap).collect(Collectors.toList());
return new FunctionCall(ctx, funcName, params);
} else if (ctx.TRIM() != null) {
- List params = ctx.parameterized_trim().expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList());
- FunctionCall fCall = new FunctionCall(ctx, ctx.TRIM().getText(), params);
- List paramFlags = new ArrayList<>();
+ FunctionParam param = wrap(ctx.parameterized_trim().expr(0));
+ if (ctx.parameterized_trim().expr(1) != null) {
+ param.addOption(visit(ctx.parameterized_trim().expr(1)));
+ }
+ FunctionCall fCall = new FunctionCall(ctx, ctx.TRIM().getText(),
+ Collections.singletonList(param));
Parameterized_trimContext trim = ctx.parameterized_trim();
for (int i = 0; i < trim.getChildCount(); i++) {
ParseTree p = trim.getChild(i);
if (p instanceof TerminalNode) {
- paramFlags.add(p.getText());
+ fCall.addOption(new ConstExpression((TerminalNode) p));
+ } else {
+ break;
}
}
- if (!paramFlags.isEmpty()) {
- fCall.setParamsFlag(String.join(" ", paramFlags));
- }
return fCall;
} else if (ctx.GET_FORMAT() != null) {
List params = new ArrayList<>();
@@ -488,14 +559,10 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
}
Date_paramsContext p = ctx.date_params();
List params = new ArrayList<>();
- params.add(wrap(p.expr(0), null));
+ params.add(wrap(p.expr(0)));
params.add(new ExpressionParam(new IntervalExpression(p,
visit(p.expr(1)), p.date_unit().getText())));
- FunctionCall fCall = new FunctionCall(ctx, funcName, params);
- if (ctx.date_params().date_unit() != null) {
- fCall.addParamsOption(new ConstExpression(ctx.date_params().date_unit()));
- }
- return fCall;
+ return new FunctionCall(ctx, funcName, params);
} else if (ctx.TIMESTAMPDIFF() != null || ctx.TIMESTAMPADD() != null) {
String funcName;
if (ctx.TIMESTAMPDIFF() != null) {
@@ -506,19 +573,18 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
List params = new ArrayList<>();
params.add(new ExpressionParam(new ConstExpression(ctx.timestamp_params().date_unit())));
params.addAll(ctx.timestamp_params().expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList()));
+ .map(this::wrap).collect(Collectors.toList()));
return new FunctionCall(ctx, funcName, params);
} else if (ctx.EXTRACT() != null) {
- FunctionCall fCall = new FunctionCall(ctx, ctx.EXTRACT().getText(),
- Collections.singletonList(wrap(ctx.expr(), null)));
- fCall.addParamsOption(new ConstExpression(ctx.date_unit()));
- return fCall;
+ FunctionParam p = new ExpressionParam(new ConstExpression(ctx.date_unit()));
+ p.addOption(visit(ctx.expr()));
+ return new FunctionCall(ctx, ctx.EXTRACT().getText(), Collections.singletonList(p));
} else if (ctx.CHARACTER() != null && ctx.WEIGHT_STRING() == null) {
List params = ctx.expr_list().expr().stream()
- .map(e -> wrap(e, null)).collect(Collectors.toList());
- FunctionCall fCall = new FunctionCall(ctx, ctx.CHARACTER().getText(), params);
- fCall.addParamsOption(new ConstExpression(ctx.charset_name()));
- return fCall;
+ .map(this::wrap).collect(Collectors.toList());
+ FunctionCall f = new FunctionCall(ctx, ctx.CHARACTER().getText(), params);
+ f.addOption(new ConstExpression(ctx.USING(), ctx.charset_name()));
+ return f;
} else if (ctx.WEIGHT_STRING() != null) {
String funcName = ctx.WEIGHT_STRING().getText();
List params = new ArrayList<>();
@@ -529,12 +595,13 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
if (ctx.ws_nweights() == null) {
return fCall;
}
+ FunctionParam p1 = params.get(params.size() - 1);
Ws_nweightsContext weights = ctx.ws_nweights();
String arg = weights.INTNUM().getText();
if (ctx.CHARACTER() != null) {
- fCall.addParamsOption(new CharacterType(weights, ctx.CHARACTER().getText(), new BigDecimal(arg)));
+ p1.addOption(new CharacterType(weights, ctx.CHARACTER().getText(), new BigDecimal(arg)));
} else if (ctx.BINARY() != null) {
- fCall.addParamsOption(new GeneralDataType(weights, ctx.BINARY().getText(),
+ p1.addOption(new GeneralDataType(weights, ctx.BINARY().getText(),
Collections.singletonList(arg)));
}
return fCall;
@@ -542,9 +609,32 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
Json_value_exprContext jsonValue = ctx.json_value_expr();
List params = new ArrayList<>();
params.add(new ExpressionParam(visit(jsonValue.simple_expr())));
- params.add(new ExpressionParam(new ConstExpression(jsonValue.complex_string_literal())));
+ params.add(new ExpressionParam(visit(jsonValue.complex_string_literal())));
FunctionCall fCall = new FunctionCall(ctx, jsonValue.JSON_VALUE().getText(), params);
- fCall.addParamsOption(new MySQLDataTypeFactory(jsonValue.cast_data_type()).generate());
+ if (jsonValue.cast_data_type() != null) {
+ fCall.addOption(new MySQLDataTypeFactory(jsonValue.cast_data_type()).generate());
+ }
+ if (jsonValue.TRUNCATE() != null) {
+ fCall.addOption(new ConstExpression(jsonValue.TRUNCATE()));
+ }
+ if (jsonValue.ASCII() != null) {
+ fCall.addOption(new ConstExpression(jsonValue.ASCII()));
+ }
+ JsonOnOption jsonOnOption;
+ if (jsonValue.on_empty() != null && jsonValue.on_error() != null) {
+ jsonOnOption = new JsonOnOption(jsonValue.on_empty(), jsonValue.on_error());
+ setOnError(jsonOnOption, jsonValue.on_error());
+ setOnEmpty(jsonOnOption, jsonValue.on_empty());
+ fCall.addOption(jsonOnOption);
+ } else if (jsonValue.on_error() != null) {
+ jsonOnOption = new JsonOnOption(jsonValue.on_error());
+ setOnError(jsonOnOption, jsonValue.on_error());
+ fCall.addOption(jsonOnOption);
+ } else if (jsonValue.on_empty() != null) {
+ jsonOnOption = new JsonOnOption(jsonValue.on_empty());
+ setOnEmpty(jsonOnOption, jsonValue.on_empty());
+ fCall.addOption(jsonOnOption);
+ }
return fCall;
}
String funcName = null;
@@ -586,8 +676,12 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
funcName = ctx.utc_date_func().UTC_DATE().getText();
} else if (ctx.sys_interval_func() != null) {
params = ctx.sys_interval_func().expr()
- .stream().map(e -> wrap(e, null)).collect(Collectors.toList());
- funcName = ctx.sys_interval_func().INTERVAL().getText();
+ .stream().map(this::wrap).collect(Collectors.toList());
+ if (ctx.sys_interval_func().INTERVAL() != null) {
+ funcName = ctx.sys_interval_func().INTERVAL().getText();
+ } else if (ctx.sys_interval_func().CHECK() != null) {
+ funcName = ctx.sys_interval_func().CHECK().getText();
+ }
}
if (funcName == null) {
throw new IllegalStateException("Missing function name");
@@ -601,18 +695,17 @@ public Expression visitWindow_function(Window_functionContext ctx) {
throw new IllegalStateException("Missing function name");
}
String funcName = ctx.func_name.getText();
- String paramsFlag = null;
+ List functionOpts = new ArrayList<>();
StatementFactory factory = new MySQLWindowSpecFactory(ctx.new_generalized_window_clause());
WindowSpec window = factory.generate();
if (ctx.ALL() != null) {
- paramsFlag = ctx.ALL().getText();
+ functionOpts.add(new ConstExpression(ctx.ALL()));
} else if (ctx.DISTINCT() != null) {
- paramsFlag = ctx.DISTINCT().getText();
+ functionOpts.add(new ConstExpression(ctx.DISTINCT()));
} else if (ctx.UNIQUE() != null) {
- paramsFlag = ctx.UNIQUE().getText();
+ functionOpts.add(new ConstExpression(ctx.UNIQUE()));
}
List params = new ArrayList<>();
- List paramsOpts = new ArrayList<>();
if (ctx.Star() != null) {
params.add(new ExpressionParam(new ConstExpression(ctx.Star())));
} else if (CollectionUtils.isNotEmpty(ctx.expr())) {
@@ -626,42 +719,34 @@ public Expression visitWindow_function(Window_functionContext ctx) {
Win_fun_first_last_paramsContext c = ctx.win_fun_first_last_params();
params.add(new ExpressionParam(visit(c.expr())));
if (c.respect_or_ignore() != null) {
- paramsOpts.add(new ConstExpression(c.respect_or_ignore()));
+ functionOpts.add(new ConstExpression(c.respect_or_ignore(), c.NULLS()));
}
}
if (ctx.NTH_VALUE() != null) {
if (ctx.first_or_last() != null) {
- paramsOpts.add(new ConstExpression(ctx.first_or_last()));
+ functionOpts.add(new ConstExpression(ctx.FROM(), ctx.first_or_last()));
}
if (ctx.respect_or_ignore() != null) {
- paramsOpts.add(new ConstExpression(ctx.respect_or_ignore()));
+ functionOpts.add(new ConstExpression(ctx.respect_or_ignore(), ctx.NULLS()));
}
}
if (ctx.GROUP_CONCAT() != null || ctx.LISTAGG() != null) {
- OrderBy orderBy = null;
if (ctx.order_by() != null) {
- StatementFactory order = new MySQLOrderByFactory(ctx.order_by());
- orderBy = order.generate();
- paramsOpts.add(orderBy);
+ functionOpts.add(new MySQLOrderByFactory(ctx.order_by()).generate());
}
- String separator = null;
if (ctx.SEPARATOR() != null) {
- separator = ctx.STRING_VALUE().getText();
- paramsOpts.add(new ConstExpression(ctx.STRING_VALUE()));
+ functionOpts.add(new ConstExpression(ctx.SEPARATOR(), ctx.STRING_VALUE()));
}
if (ctx.GROUP_CONCAT() != null) {
GroupConcat groupConcat = new GroupConcat(ctx, params);
- groupConcat.setParamsFlag(paramsFlag);
- groupConcat.setSeparator(separator);
- groupConcat.setOrderBy(orderBy);
groupConcat.setWindow(window);
+ functionOpts.forEach(groupConcat::addOption);
return groupConcat;
}
}
- WindowFunction fCall = new WindowFunction(ctx, funcName, params);
- fCall.setParamsFlag(paramsFlag);
+ FunctionCall fCall = new FunctionCall(ctx, funcName, params);
fCall.setWindow(window);
- paramsOpts.forEach(fCall::addParamsOption);
+ functionOpts.forEach(fCall::addOption);
return fCall;
}
@@ -726,6 +811,12 @@ public Expression visitBit_expr(Bit_exprContext ctx) {
right = visit(ctx.bit_expr(1));
} else if (ctx.expr() != null) {
right = new IntervalExpression(ctx, visit(ctx.expr()), ctx.date_unit().getText());
+ ParseTree firstNode = ctx.getChild(0);
+ if (firstNode instanceof TerminalNode
+ && ((TerminalNode) firstNode).getSymbol().getType() == OBLexer.INTERVAL) {
+ return new CompoundExpression(ctx, right, left, operator);
+ }
+ return new CompoundExpression(ctx, left, right, operator);
}
if (right == null) {
throw new IllegalStateException("Missing expression");
@@ -733,28 +824,132 @@ public Expression visitBit_expr(Bit_exprContext ctx) {
return new CompoundExpression(ctx, left, right, operator);
}
- private String getParamFlags(Simple_func_exprContext ctx) {
+ @Override
+ public Expression visitJson_on_response(Json_on_responseContext ctx) {
+ if (ctx.ERROR_P() != null) {
+ return new ConstExpression(ctx.ERROR_P());
+ } else if (ctx.NULLX() != null) {
+ return new NullExpression(ctx.NULLX());
+ }
+ return MySQLTableElementFactory.getSignedLiteral(ctx.signed_literal());
+ }
+
+ @Override
+ public Expression visitJson_table_expr(Json_table_exprContext ctx) {
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_TABLE().getText(),
+ Arrays.asList(new ExpressionParam(visit(ctx.simple_expr())),
+ new ExpressionParam(visit(ctx.literal()))));
+ fCall.addOption(getJsonOnOption(ctx.mock_jt_on_error_on_empty()));
+ ctx.jt_column_list().json_table_column_def().forEach(c -> fCall.addOption(visitJsonTableColumnDef(c)));
+ return fCall;
+ }
+
+ private JsonOnOption getJsonOnOption(Mock_jt_on_error_on_emptyContext ctx) {
+ return null;
+ }
+
+ private JsonOnOption getJsonOnOption(Opt_value_on_empty_or_error_or_mismatchContext ctx) {
+ if (ctx == null) {
+ return null;
+ } else if (ctx.opt_on_empty_or_error().empty() != null) {
+ return null;
+ }
+ JsonOnOption jsonOnOption = new JsonOnOption(ctx);
+ setOnEmpty(jsonOnOption, ctx.opt_on_empty_or_error().on_empty());
+ setOnError(jsonOnOption, ctx.opt_on_empty_or_error().on_error());
+ return jsonOnOption;
+ }
+
+ private void setOnEmpty(JsonOnOption jsonOnOption, On_emptyContext ctx) {
+ if (ctx == null) {
+ return;
+ }
+ jsonOnOption.setOnEmpty(visit(ctx.json_on_response()));
+ }
+
+ private void setOnError(JsonOnOption jsonOnOption, On_errorContext ctx) {
+ if (ctx == null) {
+ return;
+ }
+ jsonOnOption.setOnError(visit(ctx.json_on_response()));
+ }
+
+ private FunctionParam visitJsonTableColumnDef(Json_table_column_defContext ctx) {
+ if (ctx.json_table_ordinality_column_def() != null) {
+ return visitJsonTableOrdinalityColumnDef(ctx.json_table_ordinality_column_def());
+ } else if (ctx.json_table_exists_column_def() != null) {
+ return visitJsonTableExistsColumnDef(ctx.json_table_exists_column_def());
+ } else if (ctx.json_table_value_column_def() != null) {
+ return visitJsonTableValueColumnDef(ctx.json_table_value_column_def());
+ }
+ return visitJsonTableNestedColumnDef(ctx.json_table_nested_column_def());
+ }
+
+ private FunctionParam visitJsonTableOrdinalityColumnDef(Json_table_ordinality_column_defContext ctx) {
+ FunctionParam param = new ExpressionParam(new ColumnReference(
+ ctx.column_name(), null, null, ctx.column_name().getText()));
+ param.addOption(new ConstExpression(ctx.FOR(), ctx.ORDINALITY()));
+ return param;
+ }
+
+ private FunctionParam visitJsonTableExistsColumnDef(Json_table_exists_column_defContext ctx) {
+ FunctionParam param = new ExpressionParam(new ColumnReference(
+ ctx.column_name(), null, null, ctx.column_name().getText()));
+ param.addOption(new MySQLDataTypeFactory(ctx.data_type()).generate());
+ if (ctx.collation() != null) {
+ param.addOption(new ConstExpression(ctx.collation().collation_name()));
+ }
+ param.addOption(new ConstExpression(ctx.EXISTS()));
+ param.addOption(visit(ctx.literal()));
+ param.addOption(getJsonOnOption(ctx.mock_jt_on_error_on_empty()));
+ return param;
+ }
+
+ private FunctionParam visitJsonTableValueColumnDef(Json_table_value_column_defContext ctx) {
+ FunctionParam param = new ExpressionParam(new ColumnReference(
+ ctx.column_name(), null, null, ctx.column_name().getText()));
+ param.addOption(new MySQLDataTypeFactory(ctx.data_type()).generate());
+ if (ctx.collation() != null) {
+ param.addOption(new ConstExpression(ctx.collation().collation_name()));
+ }
+ param.addOption(visit(ctx.literal()));
+ param.addOption(getJsonOnOption(ctx.opt_value_on_empty_or_error_or_mismatch()));
+ return param;
+ }
+
+ private FunctionParam visitJsonTableNestedColumnDef(Json_table_nested_column_defContext ctx) {
+ FunctionParam param;
+ if (ctx.PATH() == null) {
+ param = new ExpressionParam(new ConstExpression(ctx.NESTED()));
+ } else {
+ param = new ExpressionParam(new ConstExpression(ctx.NESTED(), ctx.PATH()));
+ }
+ param.addOption(visit(ctx.literal()));
+ ctx.jt_column_list().json_table_column_def()
+ .forEach(c -> param.addOption(visitJsonTableColumnDef(c)));
+ return param;
+ }
+
+ private ConstExpression getAggregator(Simple_func_exprContext ctx) {
if (ctx.ALL() != null) {
- return ctx.ALL().getText();
+ return new ConstExpression(ctx.ALL());
} else if (ctx.DISTINCT() != null) {
- return ctx.DISTINCT().getText();
+ return new ConstExpression(ctx.DISTINCT());
} else if (ctx.UNIQUE() != null) {
- return ctx.UNIQUE().getText();
+ return new ConstExpression(ctx.UNIQUE());
}
return null;
}
- private ExpressionParam wrap(ParserRuleContext expr, String alias) {
- ExpressionParam param = new ExpressionParam(visit(expr));
- param.setAlias(alias);
- return param;
+ private ExpressionParam wrap(ParserRuleContext expr) {
+ return new ExpressionParam(visit(expr));
}
- private String getParamFlags(Complex_func_exprContext ctx) {
+ private ConstExpression getAggregator(Complex_func_exprContext ctx) {
if (ctx.DISTINCT() != null) {
- return ctx.DISTINCT().getText();
+ return new ConstExpression(ctx.DISTINCT());
} else if (ctx.UNIQUE() != null) {
- return ctx.UNIQUE().getText();
+ return new ConstExpression(ctx.UNIQUE());
}
return null;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLFromReferenceFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLFromReferenceFactory.java
index d695549651..8e38c6c8b8 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLFromReferenceFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLFromReferenceFactory.java
@@ -42,6 +42,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.JoinType;
+import com.oceanbase.tools.sqlparser.statement.common.BraceBlock;
import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
import com.oceanbase.tools.sqlparser.statement.select.ExpressionReference;
@@ -103,7 +104,18 @@ public FromReference visitTable_factor(Table_factorContext ctx) {
} else if (ctx.table_subquery() != null) {
return visit(ctx.table_subquery());
} else if (ctx.table_reference() != null) {
- return visit(ctx.table_reference());
+ FromReference from = visit(ctx.table_reference());
+ if (ctx.LeftBrace() == null || ctx.OJ() == null || ctx.RightBrace() == null) {
+ return from;
+ }
+ return new BraceBlock(ctx, ctx.OJ().getText(), from);
+ } else if (ctx.json_table_expr() != null) {
+ String alias = null;
+ if (ctx.relation_name() != null) {
+ alias = ctx.relation_name().getText();
+ }
+ MySQLExpressionFactory factory = new MySQLExpressionFactory();
+ return new ExpressionReference(ctx, factory.visitJson_table_expr(ctx.json_table_expr()), alias);
}
StatementFactory factory = new MySQLSelectBodyFactory(ctx.select_with_parens());
ExpressionReference reference = new ExpressionReference(ctx, factory.generate(), null);
@@ -121,6 +133,8 @@ public FromReference visitJoined_table(Joined_tableContext ctx) {
joinType = JoinType.CROSS_JOIN;
} else if (ctx.inner_join_type().INNER() != null) {
joinType = JoinType.INNER_JOIN;
+ } else if (ctx.inner_join_type().STRAIGHT_JOIN() != null) {
+ joinType = JoinType.STRAIGHT_JOIN;
} else {
joinType = JoinType.JOIN;
}
@@ -168,31 +182,70 @@ public FromReference visitJoined_table(Joined_tableContext ctx) {
@Override
public FromReference visitTbl_name(Tbl_nameContext ctx) {
- Relation_factorContext relationFactor = ctx.relation_factor();
- String schema = getSchemaName(relationFactor);
- String relationName = getRelation(relationFactor);
+ RelationFactor factor = getRelationFactor(ctx.relation_factor());
String alias = null;
if (ctx.relation_name() != null) {
alias = ctx.relation_name().getText();
}
- NameReference nameReference = new NameReference(ctx, schema, relationName, alias);
+ NameReference nameReference = new NameReference(ctx, factor.getSchema(), factor.getRelation(), alias);
if (ctx.use_partition() != null) {
nameReference.setPartitionUsage(visitPartitonUsage(ctx.use_partition()));
}
if (ctx.use_flashback() != null) {
nameReference.setFlashbackUsage(visitFlashbackUsage(ctx.use_flashback()));
}
+ nameReference.setUserVariable(factor.getUserVariable());
return nameReference;
}
- public static String getSchemaName(Relation_factorContext context) {
- if (context == null || context.normal_relation_factor() == null) {
- return null;
+ public static RelationFactor getRelationFactor(Normal_relation_factorContext ctx) {
+ RelationFactor relationFactor = new RelationFactor(ctx, getRelation(ctx));
+ relationFactor.setSchema(getSchemaName(ctx));
+ if (ctx.USER_VARIABLE() != null) {
+ relationFactor.setUserVariable(ctx.USER_VARIABLE().getText());
}
- return getSchemaName(context.normal_relation_factor());
+ return relationFactor;
+ }
+
+ public static RelationFactor getRelationFactor(Relation_factorContext ctx) {
+ RelationFactor relationFactor = new RelationFactor(ctx, getRelation(ctx));
+ relationFactor.setSchema(getSchemaName(ctx));
+ if (ctx.normal_relation_factor() != null && ctx.normal_relation_factor().USER_VARIABLE() != null) {
+ relationFactor.setUserVariable(ctx.normal_relation_factor().USER_VARIABLE().getText());
+ }
+ return relationFactor;
+ }
+
+ @Override
+ public FromReference visitTable_subquery(Table_subqueryContext ctx) {
+ StatementFactory factory = new MySQLSelectBodyFactory(ctx.select_with_parens());
+ String alias = ctx.table_subquery_alias().relation_name().getText();
+ ExpressionReference reference = new ExpressionReference(ctx, factory.generate(), alias);
+ if (ctx.use_flashback() != null) {
+ reference.setFlashbackUsage(visitFlashbackUsage(ctx.use_flashback()));
+ }
+ if (ctx.table_subquery_alias().alias_name_list() != null) {
+ reference.setAliasColumns(ctx.table_subquery_alias().alias_name_list()
+ .column_alias_name().stream().map(c -> c.column_name().getText())
+ .collect(Collectors.toList()));
+ }
+ return reference;
+ }
+
+ private static String getRelation(Normal_relation_factorContext c) {
+ List names = c.relation_name().stream()
+ .map(RuleContext::getText).collect(Collectors.toList());
+ if (c.mysql_reserved_keyword() != null) {
+ return c.mysql_reserved_keyword().getText();
+ } else if (names.size() == 2) {
+ return names.get(1);
+ } else if (names.size() == 1) {
+ return names.get(0);
+ }
+ return null;
}
- public static String getRelation(Relation_factorContext context) {
+ private static String getRelation(Relation_factorContext context) {
if (context == null) {
return null;
}
@@ -208,52 +261,23 @@ public static String getRelation(Relation_factorContext context) {
return null;
}
- public static String getSchemaName(Normal_relation_factorContext c) {
- List names = c.relation_name().stream()
- .map(RuleContext::getText).collect(Collectors.toList());
- if (c.mysql_reserved_keyword() != null) {
- return names.get(0);
- }
- if (names.size() == 2) {
- return names.get(0);
+ private static String getSchemaName(Relation_factorContext context) {
+ if (context == null || context.normal_relation_factor() == null) {
+ return null;
}
- return null;
- }
-
- public static RelationFactor getRelationFactor(Normal_relation_factorContext ctx) {
- RelationFactor relationFactor = new RelationFactor(ctx, getRelation(ctx));
- relationFactor.setSchema(getSchemaName(ctx));
- return relationFactor;
- }
-
- public static RelationFactor getRelationFactor(Relation_factorContext ctx) {
- RelationFactor relationFactor = new RelationFactor(ctx, getRelation(ctx));
- relationFactor.setSchema(getSchemaName(ctx));
- return relationFactor;
+ return getSchemaName(context.normal_relation_factor());
}
- public static String getRelation(Normal_relation_factorContext c) {
+ private static String getSchemaName(Normal_relation_factorContext c) {
List names = c.relation_name().stream()
.map(RuleContext::getText).collect(Collectors.toList());
if (c.mysql_reserved_keyword() != null) {
- return c.mysql_reserved_keyword().getText();
- } else if (names.size() == 2) {
- return names.get(1);
- } else if (names.size() == 1) {
return names.get(0);
}
- return null;
- }
-
- @Override
- public FromReference visitTable_subquery(Table_subqueryContext ctx) {
- StatementFactory factory = new MySQLSelectBodyFactory(ctx.select_with_parens());
- String alias = ctx.relation_name().getText();
- ExpressionReference reference = new ExpressionReference(ctx, factory.generate(), alias);
- if (ctx.use_flashback() != null) {
- reference.setFlashbackUsage(visitFlashbackUsage(ctx.use_flashback()));
+ if (names.size() == 2) {
+ return names.get(0);
}
- return reference;
+ return null;
}
private FlashbackUsage visitFlashbackUsage(Use_flashbackContext ctx) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionElementFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionElementFactory.java
index a4a9523db4..cfac89a9af 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionElementFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionElementFactory.java
@@ -27,6 +27,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Subpartition_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
+import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import com.oceanbase.tools.sqlparser.statement.createtable.HashPartitionElement;
import com.oceanbase.tools.sqlparser.statement.createtable.ListPartitionElement;
import com.oceanbase.tools.sqlparser.statement.createtable.PartitionElement;
@@ -67,9 +68,10 @@ public PartitionElement generate() {
@Override
public PartitionElement visitHash_partition_element(Hash_partition_elementContext ctx) {
- HashPartitionElement element = new HashPartitionElement(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()));
- element.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
+ HashPartitionElement element = new HashPartitionElement(ctx, factor.getRelation());
+ element.setSchema(factor.getSchema());
+ element.setUserVariable(factor.getUserVariable());
element.setSubPartitionElements(getSubPartitionElements(ctx.subpartition_list()));
PartitionOptions options =
MySQLSubPartitionElementFactory.getPartitionOptions(ctx.partition_attributes_option());
@@ -85,11 +87,12 @@ public PartitionElement visitHash_partition_element(Hash_partition_elementContex
@Override
public PartitionElement visitRange_partition_element(Range_partition_elementContext ctx) {
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
List rangeExprs =
MySQLSubPartitionElementFactory.getRangePartitionExprs(ctx.range_partition_expr());
- RangePartitionElement element = new RangePartitionElement(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()), rangeExprs);
- element.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ RangePartitionElement element = new RangePartitionElement(ctx, factor.getRelation(), rangeExprs);
+ element.setSchema(factor.getSchema());
+ element.setUserVariable(factor.getUserVariable());
element.setSubPartitionElements(getSubPartitionElements(ctx.subpartition_list()));
PartitionOptions options =
MySQLSubPartitionElementFactory.getPartitionOptions(ctx.partition_attributes_option());
@@ -106,9 +109,10 @@ public PartitionElement visitRange_partition_element(Range_partition_elementCont
@Override
public PartitionElement visitList_partition_element(List_partition_elementContext ctx) {
List listExprs = MySQLSubPartitionElementFactory.getListPartitionExprs(ctx.list_partition_expr());
- ListPartitionElement element = new ListPartitionElement(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()), listExprs);
- element.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
+ ListPartitionElement element = new ListPartitionElement(ctx, factor.getRelation(), listExprs);
+ element.setSchema(factor.getSchema());
+ element.setUserVariable(factor.getUserVariable());
element.setSubPartitionElements(getSubPartitionElements(ctx.subpartition_list()));
PartitionOptions options =
MySQLSubPartitionElementFactory.getPartitionOptions(ctx.partition_attributes_option());
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionFactory.java
index 0021a5bd39..d098fc4627 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLPartitionFactory.java
@@ -30,6 +30,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Key_partition_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.List_partition_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Opt_partition_optionContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Partition_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Range_partition_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Subpartition_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Vertical_column_nameContext;
@@ -65,6 +66,14 @@ public MySQLPartitionFactory(@NonNull Opt_partition_optionContext optPartitionOp
this.parserRuleContext = optPartitionOptionContext;
}
+ public MySQLPartitionFactory(@NonNull Partition_optionContext partitionOptionContext) {
+ this.parserRuleContext = partitionOptionContext;
+ }
+
+ public MySQLPartitionFactory(@NonNull Auto_partition_optionContext autoPartitionOptionContext) {
+ this.parserRuleContext = autoPartitionOptionContext;
+ }
+
public MySQLPartitionFactory(@NonNull Hash_partition_optionContext context) {
this.parserRuleContext = context;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLRenameTableActionFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLRenameTableActionFactory.java
index c3014d364f..f37a25d265 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLRenameTableActionFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLRenameTableActionFactory.java
@@ -16,11 +16,9 @@
package com.oceanbase.tools.sqlparser.adapter.mysql;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Relation_factorContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Rename_table_actionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.alter.table.RenameTableAction;
-import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import lombok.NonNull;
@@ -47,16 +45,9 @@ public RenameTableAction generate() {
@Override
public RenameTableAction visitRename_table_action(Rename_table_actionContext ctx) {
- Relation_factorContext from = ctx.relation_factor(0);
- Relation_factorContext to = ctx.relation_factor(1);
-
- RelationFactor fromFactor = new RelationFactor(from,
- MySQLFromReferenceFactory.getRelation(from));
- fromFactor.setSchema(MySQLFromReferenceFactory.getSchemaName(from));
-
- RelationFactor toFactor = new RelationFactor(to, MySQLFromReferenceFactory.getRelation(to));
- toFactor.setSchema(MySQLFromReferenceFactory.getSchemaName(to));
- return new RenameTableAction(ctx, fromFactor, toFactor);
+ return new RenameTableAction(ctx,
+ MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor(0)),
+ MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor(1)));
}
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSelectBodyFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSelectBodyFactory.java
index e34b3ca440..9b4f351fe0 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSelectBodyFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSelectBodyFactory.java
@@ -29,14 +29,12 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.ExprContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.From_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Groupby_clauseContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Insert_valsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Named_windowsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.No_table_selectContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.No_table_select_with_order_and_limitContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Query_expression_option_listContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_clauseContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_clause_setContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_clause_set_leftContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_clause_set_rightContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_clause_set_with_order_and_limitContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_expr_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Select_no_parensContext;
@@ -47,10 +45,13 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Simple_selectContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Simple_select_with_order_and_limitContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_referencesContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_values_clauseContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_values_clause_with_order_by_and_limitContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.With_clauseContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.common.Window;
+import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
import com.oceanbase.tools.sqlparser.statement.select.ForUpdate;
import com.oceanbase.tools.sqlparser.statement.select.FromReference;
import com.oceanbase.tools.sqlparser.statement.select.GroupBy;
@@ -129,24 +130,31 @@ public SelectBody visitSelect_no_parens(Select_no_parensContext ctx) {
}
if (ctx.for_update_clause() != null) {
StatementFactory factory = new MySQLForUpdateFactory(ctx.for_update_clause());
- ForUpdate forUpdate = factory.generate();
- if (select.getRelatedSelect() == null) {
- select.setForUpdate(forUpdate);
- } else {
- select.getRelatedSelect().setForUpdate(forUpdate);
- }
+ select.getLastSelectBody().setForUpdate(factory.generate());
+ }
+ if (ctx.opt_lock_in_share_mode() != null) {
+ select.getLastSelectBody().setLockInShareMode(true);
}
return select;
}
@Override
- public SelectBody visitSelect_clause(Select_clauseContext ctx) {
- if (ctx.no_table_select_with_order_and_limit() != null) {
- return visit(ctx.no_table_select_with_order_and_limit());
- } else if (ctx.simple_select_with_order_and_limit() != null) {
- return visit(ctx.simple_select_with_order_and_limit());
+ public SelectBody visitTable_values_clause(Table_values_clauseContext ctx) {
+ return new SelectBody(ctx, ctx.values_row_list().row_value().stream()
+ .map(c -> getValueRows(c.insert_vals())).collect(Collectors.toList()));
+ }
+
+ @Override
+ public SelectBody visitTable_values_clause_with_order_by_and_limit(
+ Table_values_clause_with_order_by_and_limitContext ctx) {
+ SelectBody selectBody = new SelectBody(ctx, visit(ctx.table_values_clause()));
+ if (ctx.order_by() != null) {
+ selectBody.setOrderBy(new MySQLOrderByFactory(ctx.order_by()).generate());
+ }
+ if (ctx.limit_clause() != null) {
+ selectBody.setLimit(new MySQLLimitFactory(ctx.limit_clause()).generate());
}
- return visit(ctx.select_with_parens_with_order_and_limit());
+ return selectBody;
}
@Override
@@ -154,21 +162,11 @@ public SelectBody visitSelect_with_parens_with_order_and_limit(Select_with_paren
SelectBody select = new SelectBody(ctx, visit(ctx.select_with_parens()));
if (ctx.order_by() != null) {
StatementFactory factory = new MySQLOrderByFactory(ctx.order_by());
- OrderBy orderBy = factory.generate();
- if (select.getRelatedSelect() == null) {
- select.setOrderBy(orderBy);
- } else {
- select.getRelatedSelect().setOrderBy(orderBy);
- }
+ select.getLastSelectBody().setOrderBy(factory.generate());
}
if (ctx.limit_clause() != null) {
StatementFactory factory = new MySQLLimitFactory(ctx.limit_clause());
- Limit limit = factory.generate();
- if (select.getRelatedSelect() == null) {
- select.setLimit(limit);
- } else {
- select.getRelatedSelect().setLimit(limit);
- }
+ select.getLastSelectBody().setLimit(factory.generate());
}
return select;
}
@@ -178,11 +176,11 @@ public SelectBody visitSelect_clause_set_with_order_and_limit(Select_clause_set_
SelectBody select = new SelectBody(ctx, visit(ctx.select_clause_set()));
if (ctx.order_by() != null) {
StatementFactory factory = new MySQLOrderByFactory(ctx.order_by());
- select.getRelatedSelect().setOrderBy(factory.generate());
+ select.getLastSelectBody().setOrderBy(factory.generate());
}
if (ctx.limit_clause() != null) {
StatementFactory factory = new MySQLLimitFactory(ctx.limit_clause());
- select.getRelatedSelect().setLimit(factory.generate());
+ select.getLastSelectBody().setLimit(factory.generate());
}
return select;
}
@@ -194,11 +192,11 @@ public SelectBody visitSelect_clause_set(Select_clause_setContext ctx) {
left = new SelectBody(ctx, visit(ctx.select_clause_set()));
if (ctx.order_by() != null) {
StatementFactory factory = new MySQLOrderByFactory(ctx.order_by());
- left.getRelatedSelect().setOrderBy(factory.generate());
+ left.getLastSelectBody().setOrderBy(factory.generate());
}
if (ctx.limit_clause() != null) {
StatementFactory factory = new MySQLLimitFactory(ctx.limit_clause());
- left.getRelatedSelect().setLimit(factory.generate());
+ left.getLastSelectBody().setLimit(factory.generate());
}
} else if (ctx.select_clause_set_left() != null) {
left = new SelectBody(ctx, visit(ctx.select_clause_set_left()));
@@ -206,46 +204,12 @@ public SelectBody visitSelect_clause_set(Select_clause_setContext ctx) {
if (left == null) {
throw new IllegalStateException("Missing left clause");
}
- List s = ctx.select_clause_set_right();
- SelectBody target = left;
- while (target.getRelatedSelect() != null) {
- target = target.getRelatedSelect().getSelect();
- }
- if (s.size() == 1) {
- RelationType type = getRelationType(ctx.set_type(0));
- SelectBody right = visit(s.get(0));
- target.setRelatedSelect(new RelatedSelectBody(right, type));
- } else {
- for (int i = 0; i < s.size(); i++) {
- RelationType type = getRelationType(ctx.set_type(i));
- SelectBody right = visit(s.get(i));
- target.setRelatedSelect(new RelatedSelectBody(right, type));
- target = target.getRelatedSelect().getSelect();
- }
- }
+ RelationType type = getRelationType(ctx.set_type());
+ SelectBody right = visit(ctx.select_clause_set_right());
+ left.getLastSelectBody().setRelatedSelect(new RelatedSelectBody(right, type));
return left;
}
- @Override
- public SelectBody visitSelect_clause_set_left(Select_clause_set_leftContext ctx) {
- if (ctx.no_table_select_with_order_and_limit() != null) {
- return visit(ctx.no_table_select_with_order_and_limit());
- } else if (ctx.simple_select_with_order_and_limit() != null) {
- return visit(ctx.simple_select_with_order_and_limit());
- }
- return visit(ctx.select_with_parens());
- }
-
- @Override
- public SelectBody visitSelect_clause_set_right(Select_clause_set_rightContext ctx) {
- if (ctx.no_table_select() != null) {
- return visit(ctx.no_table_select());
- } else if (ctx.simple_select() != null) {
- return visit(ctx.simple_select());
- }
- return visit(ctx.select_with_parens());
- }
-
private RelationType getRelationType(Set_typeContext setType) {
if (setType.set_type_other() != null) {
return RelationType.valueOf(setType.set_type_other().getText().toUpperCase());
@@ -489,6 +453,28 @@ private String getQueryExpr(Query_expression_option_listContext context) {
return context.query_expression_option().stream().map(RuleContext::getText).collect(Collectors.joining(" "));
}
+ private List getValueRows(Insert_valsContext ctx) {
+ Expression expr = null;
+ if (ctx.expr_or_default() != null) {
+ if (ctx.expr_or_default().expr() == null) {
+ expr = new ConstExpression(ctx.expr_or_default().DEFAULT());
+ } else {
+ expr = new MySQLExpressionFactory(ctx.expr_or_default().expr()).generate();
+ }
+ }
+ if (ctx.empty() != null || expr == null) {
+ return new ArrayList<>();
+ }
+ List exprs;
+ if (ctx.insert_vals() == null) {
+ exprs = new ArrayList<>();
+ } else {
+ exprs = getValueRows(ctx.insert_vals());
+ }
+ exprs.add(expr);
+ return exprs;
+ }
+
/**
* {@link SelectContext}
*
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSortColumnFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSortColumnFactory.java
index a75783cef2..daef440a3a 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSortColumnFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSortColumnFactory.java
@@ -18,6 +18,7 @@
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Sort_column_keyContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
+import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.createtable.SortColumn;
import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
import com.oceanbase.tools.sqlparser.statement.select.SortDirection;
@@ -46,11 +47,17 @@ public SortColumn generate() {
@Override
public SortColumn visitSort_column_key(Sort_column_keyContext ctx) {
- ColumnReference r = new ColumnReference(ctx.column_name(), null, null,
- ctx.column_name().getText());
- SortColumn sortColumn = new SortColumn(ctx, r);
- if (ctx.LeftParen() != null && ctx.RightParen() != null) {
- sortColumn.setLength(Integer.valueOf(ctx.INTNUM(0).getText()));
+ SortColumn sortColumn;
+ if (ctx.expr() != null) {
+ Expression e = new MySQLExpressionFactory(ctx.expr()).generate();
+ sortColumn = new SortColumn(ctx, e);
+ } else {
+ ColumnReference r = new ColumnReference(ctx.column_name(), null, null,
+ ctx.column_name().getText());
+ sortColumn = new SortColumn(ctx, r);
+ if (ctx.LeftParen() != null && ctx.RightParen() != null) {
+ sortColumn.setLength(Integer.valueOf(ctx.INTNUM(0).getText()));
+ }
}
SortDirection direction = null;
if (ctx.ASC() != null) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSubPartitionElementFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSubPartitionElementFactory.java
index 61365b8632..48ebad2bb3 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSubPartitionElementFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLSubPartitionElementFactory.java
@@ -30,6 +30,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Range_subpartition_elementContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
+import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import com.oceanbase.tools.sqlparser.statement.createtable.PartitionOptions;
import com.oceanbase.tools.sqlparser.statement.createtable.SubHashPartitionElement;
import com.oceanbase.tools.sqlparser.statement.createtable.SubListPartitionElement;
@@ -70,29 +71,32 @@ public SubPartitionElement generate() {
@Override
public SubPartitionElement visitHash_subpartition_element(Hash_subpartition_elementContext ctx) {
- SubHashPartitionElement element = new SubHashPartitionElement(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()));
- element.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
+ SubHashPartitionElement element = new SubHashPartitionElement(ctx, factor.getRelation());
+ element.setSchema(factor.getSchema());
+ element.setUserVariable(factor.getUserVariable());
element.setPartitionOptions(getPartitionOptions(ctx.partition_attributes_option()));
return element;
}
@Override
public SubPartitionElement visitRange_subpartition_element(Range_subpartition_elementContext ctx) {
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
List rangeExprs = getRangePartitionExprs(ctx.range_partition_expr());
- SubRangePartitionElement element = new SubRangePartitionElement(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()), rangeExprs);
- element.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ SubRangePartitionElement element = new SubRangePartitionElement(ctx, factor.getRelation(), rangeExprs);
+ element.setSchema(factor.getSchema());
+ element.setUserVariable(factor.getUserVariable());
element.setPartitionOptions(getPartitionOptions(ctx.partition_attributes_option()));
return element;
}
@Override
public SubPartitionElement visitList_subpartition_element(List_subpartition_elementContext ctx) {
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor());
List listExprs = getListPartitionExprs(ctx.list_partition_expr());
- SubListPartitionElement element = new SubListPartitionElement(ctx,
- MySQLFromReferenceFactory.getRelation(ctx.relation_factor()), listExprs);
- element.setSchema(MySQLFromReferenceFactory.getSchemaName(ctx.relation_factor()));
+ SubListPartitionElement element = new SubListPartitionElement(ctx, factor.getRelation(), listExprs);
+ element.setSchema(factor.getSchema());
+ element.setUserVariable(factor.getUserVariable());
element.setPartitionOptions(getPartitionOptions(ctx.partition_attributes_option()));
return element;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableElementFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableElementFactory.java
index 5ebe5b2caf..87a0ac8008 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableElementFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableElementFactory.java
@@ -42,7 +42,6 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Reference_actionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Reference_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.References_clauseContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Relation_factorContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Signed_literalContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Sort_column_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_elementContext;
@@ -50,6 +49,7 @@
import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.Operator;
import com.oceanbase.tools.sqlparser.statement.common.DataType;
+import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnAttributes;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition.Location;
@@ -145,6 +145,11 @@ public TableElement visitOut_of_line_index(Out_of_line_indexContext ctx) {
index.setIndexOptions(getIndexOptions(ctx.index_using_algorithm(), ctx.opt_index_options()));
index.setSpatial(ctx.SPATIAL() != null);
index.setFullText(ctx.FULLTEXT() != null);
+ if (ctx.partition_option() != null) {
+ index.setPartition(new MySQLPartitionFactory(ctx.partition_option()).generate());
+ } else if (ctx.auto_partition_option() != null) {
+ index.setPartition(new MySQLPartitionFactory(ctx.auto_partition_option()).generate());
+ }
return index;
}
@@ -163,6 +168,7 @@ public TableElement visitOut_of_line_primary_index(Out_of_line_primary_indexCont
}
OutOfLineConstraint constraint = new OutOfLineConstraint(ctx, state, columns);
constraint.setPrimaryKey(true);
+ constraint.setIndexName(ctx.index_name() == null ? null : ctx.index_name().getText());
return constraint;
}
@@ -176,9 +182,20 @@ public TableElement visitOut_of_line_unique_index(Out_of_line_unique_indexContex
: new ConstraintState(ctx.index_using_algorithm());
state.setIndexOptions(indexOptions);
}
+ if (ctx.partition_option() != null) {
+ if (state == null) {
+ state = new ConstraintState(ctx.partition_option());
+ }
+ state.setPartition(new MySQLPartitionFactory(ctx.partition_option()).generate());
+ } else if (ctx.auto_partition_option() != null) {
+ if (state == null) {
+ state = new ConstraintState(ctx.auto_partition_option());
+ }
+ state.setPartition(new MySQLPartitionFactory(ctx.auto_partition_option()).generate());
+ }
OutOfLineConstraint constraint = new OutOfLineConstraint(ctx, state, getSortColumns(ctx.sort_column_list()));
- constraint.setIndexName(ctx.index_name() == null ? null : ctx.index_name().getText());
constraint.setUniqueKey(true);
+ constraint.setIndexName(ctx.index_name() == null ? null : ctx.index_name().getText());
return constraint;
}
@@ -224,16 +241,16 @@ public TableElement visitColumn_definition(Column_definitionContext ctx) {
}
private ForeignReference visitForeignReference(References_clauseContext context) {
- Relation_factorContext relationFactor = context.relation_factor();
- String schema = MySQLFromReferenceFactory.getSchemaName(relationFactor);
- String tableName = MySQLFromReferenceFactory.getRelation(relationFactor);
+ RelationFactor factor = MySQLFromReferenceFactory.getRelationFactor(context.relation_factor());
List columns = new ArrayList<>();
if (context.column_name_list() != null) {
columns = context.column_name_list().column_name().stream()
.map(c1 -> new ColumnReference(c1, null, null, c1.getText()))
.collect(Collectors.toList());
}
- ForeignReference foreignReference = new ForeignReference(context, schema, tableName, columns);
+ ForeignReference foreignReference = new ForeignReference(context,
+ factor.getSchema(), factor.getRelation(), columns);
+ foreignReference.setUserVariable(factor.getUserVariable());
if (context.match_action() != null) {
foreignReference.setMatchOption(MatchOption.valueOf(context.match_action().getText().toUpperCase()));
}
@@ -319,6 +336,8 @@ private ColumnAttributes visitGeneratedColumnAttribute(Generated_column_attribut
attributes.setId(Integer.valueOf(ctx.INTNUM().getText()));
} else if (ctx.COMMENT() != null) {
attributes.setComment(ctx.STRING_VALUE().getText());
+ } else if (ctx.SRID() != null) {
+ attributes.setSrid(Integer.valueOf(ctx.INTNUM().getText()));
} else {
InLineConstraint attribute = new InLineConstraint(ctx, null, null);
if (ctx.NULLX() != null) {
@@ -335,7 +354,17 @@ private ColumnAttributes visitGeneratedColumnAttribute(Generated_column_attribut
attributes.setConstraints(Collections.singletonList(attribute));
} else if (ctx.CHECK() != null) {
Expression expr = new MySQLExpressionFactory(ctx.expr()).generate();
- attributes.setConstraints(Collections.singletonList(new InLineCheckConstraint(ctx, null, null, expr)));
+ ConstraintState state = null;
+ if (ctx.check_state() != null) {
+ state = new ConstraintState(ctx.check_state());
+ state.setEnforced(ctx.check_state().NOT() == null);
+ }
+ String constraintName = null;
+ if (ctx.opt_constraint_name() != null && ctx.opt_constraint_name().constraint_name() != null) {
+ constraintName = ctx.opt_constraint_name().constraint_name().getText();
+ }
+ attributes.setConstraints(
+ Collections.singletonList(new InLineCheckConstraint(ctx, constraintName, state, expr)));
}
}
return attributes;
@@ -366,7 +395,16 @@ private ColumnAttributes visitColumnAttribute(Column_attributeContext ctx) {
attribute.setPrimaryKey(true);
attributes.setConstraints(Collections.singletonList(attribute));
} else if (ctx.CHECK() != null) {
- attribute = new InLineCheckConstraint(ctx, null, null,
+ ConstraintState state = null;
+ if (ctx.check_state() != null) {
+ state = new ConstraintState(ctx.check_state());
+ state.setEnforced(ctx.check_state().NOT() == null);
+ }
+ String constraintName = null;
+ if (ctx.opt_constraint_name() != null && ctx.opt_constraint_name().constraint_name() != null) {
+ constraintName = ctx.opt_constraint_name().constraint_name().getText();
+ }
+ attribute = new InLineCheckConstraint(ctx, constraintName, state,
new MySQLExpressionFactory(ctx.expr()).generate());
attributes.setConstraints(Collections.singletonList(attribute));
} else if (ctx.DEFAULT() != null || ctx.ORIG_DEFAULT() != null) {
@@ -384,6 +422,10 @@ private ColumnAttributes visitColumnAttribute(Column_attributeContext ctx) {
attributes.setOnUpdate(visitCurTimestampFunc(ctx.cur_timestamp_func()));
} else if (ctx.ID() != null) {
attributes.setId(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.SRID() != null) {
+ attributes.setSrid(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.collation_name() != null) {
+ attributes.setCollation(ctx.collation_name().getText());
}
return attributes;
}
@@ -399,9 +441,9 @@ public static Expression getSignedLiteral(Signed_literalContext context) {
if (context == null) {
return null;
}
- ConstExpression constExpr;
+ Expression constExpr;
if (context.literal() != null) {
- constExpr = new ConstExpression(context.literal());
+ constExpr = new MySQLExpressionFactory(context.literal()).generate();
} else {
constExpr = new ConstExpression(context.number_literal());
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableOptionsFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableOptionsFactory.java
index 9f1c01823f..80062d2e86 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableOptionsFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLTableOptionsFactory.java
@@ -16,6 +16,9 @@
package com.oceanbase.tools.sqlparser.adapter.mysql;
import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
@@ -26,8 +29,12 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_option_listContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_option_list_space_seperatedContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
+import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.createtable.TableOptions;
+import com.oceanbase.tools.sqlparser.statement.expression.BoolValue;
+import com.oceanbase.tools.sqlparser.statement.expression.CollectionExpression;
import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
+import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
import lombok.NonNull;
@@ -146,6 +153,31 @@ public TableOptions visitTable_option(Table_optionContext ctx) {
target.setAutoIncrementMode(ctx.STRING_VALUE().getText());
} else if (ctx.ENABLE_EXTENDED_ROWID() != null) {
target.setEnableExtendedRowId(Boolean.valueOf(ctx.BOOL_VALUE().getText()));
+ } else if (ctx.LOCATION() != null) {
+ target.setLocation(ctx.STRING_VALUE().getText());
+ } else if (ctx.FORMAT() != null) {
+ Map formatMap = new HashMap<>();
+ ctx.external_file_format_list().external_file_format().forEach(e -> {
+ Expression value = null;
+ if (e.STRING_VALUE() != null) {
+ value = new ConstExpression(e.STRING_VALUE());
+ } else if (e.expr() != null) {
+ value = new MySQLExpressionFactory(e.expr()).generate();
+ } else if (e.INTNUM() != null) {
+ value = new ConstExpression(e.INTNUM());
+ } else if (e.BOOL_VALUE() != null) {
+ value = new BoolValue(e.BOOL_VALUE());
+ } else if (e.expr_list() != null) {
+ List exprs = e.expr_list().expr().stream()
+ .map(ex -> new MySQLExpressionFactory(ex).generate())
+ .collect(Collectors.toList());
+ value = new CollectionExpression(e.expr_list(), exprs);
+ }
+ formatMap.put(e.format_key.getText().toUpperCase(), value);
+ });
+ target.setFormat(formatMap);
+ } else if (ctx.PATTERN() != null) {
+ target.setPattern(ctx.STRING_VALUE().getText());
}
return target;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLUpdateFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLUpdateFactory.java
index c62bb7f7aa..2f892d73b7 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLUpdateFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLUpdateFactory.java
@@ -23,6 +23,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Expr_or_defaultContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Update_asgn_factorContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Update_asgn_listContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Update_basic_stmtContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Update_stmtContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
@@ -56,7 +57,8 @@ public Update generate() {
}
@Override
- public Update visitUpdate_stmt(Update_stmtContext ctx) {
+ public Update visitUpdate_stmt(Update_stmtContext updateCtx) {
+ Update_basic_stmtContext ctx = updateCtx.update_basic_stmt();
Update update = new Update(ctx, MySQLSelectBodyFactory.visitFromList(ctx.table_references()),
visitUpdateAsgnList(ctx.update_asgn_list()));
if (ctx.expr() != null) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableActionFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableActionFactory.java
index ecde353541..3baed192d9 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableActionFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableActionFactory.java
@@ -89,6 +89,9 @@ public AlterTableAction visitAlter_table_action(Alter_table_actionContext ctx) {
} else if (ctx.RENAME() != null) {
alterTableAction.setRenameToTable(getRelationFactor(ctx.relation_factor()));
return alterTableAction;
+ } else if (ctx.REFRESH() != null) {
+ alterTableAction.setRefresh(true);
+ return alterTableAction;
} else if (ctx.DROP() != null && ctx.CONSTRAINT() != null) {
alterTableAction.setDropConstraintNames(Collections.singletonList(ctx.constraint_name().getText()));
return alterTableAction;
@@ -294,6 +297,14 @@ public AlterTableAction visitAlter_partition_option(Alter_partition_optionContex
actions.setIntos(elts);
}
alterTableAction.splitPartition(getRelationFactor(ctx.relation_factor()), actions);
+ } else if (ctx.RENAME() != null) {
+ String from = ctx.relation_name(0).getText();
+ String to = ctx.relation_name(1).getText();
+ if (ctx.PARTITION() != null) {
+ alterTableAction.renamePartition(from, to);
+ } else {
+ alterTableAction.renameSubPartition(from, to);
+ }
}
return alterTableAction;
}
@@ -315,6 +326,11 @@ private RelationFactor getRelationFactor(Relation_factorContext ctx) {
RelationFactor relationFactor = new RelationFactor(ctx, OracleFromReferenceFactory.getRelation(ctx));
relationFactor.setSchema(OracleFromReferenceFactory.getSchemaName(ctx));
relationFactor.setUserVariable(OracleFromReferenceFactory.getUserVariable(ctx));
+ if (ctx.normal_relation_factor() != null
+ && ctx.normal_relation_factor().opt_reverse_link_flag() != null
+ && ctx.normal_relation_factor().opt_reverse_link_flag().Not() != null) {
+ relationFactor.setReverseLink(true);
+ }
return relationFactor;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableFactory.java
index 2f803bb264..6eab0d3ab5 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleAlterTableFactory.java
@@ -54,6 +54,9 @@ public AlterTable visitAlter_table_stmt(Alter_table_stmtContext ctx) {
.map(c -> new OracleAlterTableActionFactory(c).generate()).collect(Collectors.toList());
AlterTable alterTable = new AlterTable(ctx,
OracleFromReferenceFactory.getRelation(ctx.relation_factor()), actions);
+ if (ctx.EXTERNAL() != null) {
+ alterTable.setExternal(true);
+ }
alterTable.setSchema(OracleFromReferenceFactory.getSchemaName(ctx.relation_factor()));
alterTable.setUserVariable(OracleFromReferenceFactory.getUserVariable(ctx.relation_factor()));
return alterTable;
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateTableFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateTableFactory.java
index fd35cafada..1af9c6755a 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateTableFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateTableFactory.java
@@ -55,6 +55,8 @@ public CreateTable visitCreate_table_stmt(Create_table_stmtContext ctx) {
if (ctx.temporary_option().GLOBAL() != null && ctx.temporary_option().TEMPORARY() != null) {
createTable.setGlobal(true);
createTable.setTemporary(true);
+ } else if (ctx.temporary_option().EXTERNAL() != null) {
+ createTable.setExternal(true);
}
if (ctx.table_element_list() != null) {
createTable.setTableElements(ctx.table_element_list().table_element().stream()
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleDataTypeFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleDataTypeFactory.java
index efe2f8abba..7396b4ef68 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleDataTypeFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleDataTypeFactory.java
@@ -19,6 +19,7 @@
import java.util.ArrayList;
import java.util.List;
+import org.antlr.v4.runtime.ParserRuleContext;
import org.apache.commons.collections4.CollectionUtils;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
@@ -32,11 +33,20 @@
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Float_type_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Int_type_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Interval_type_iContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_agg_returning_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_query_return_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_return_default_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_return_text_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_return_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_value_return_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Nstring_length_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Number_precisionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Number_type_iContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_jt_value_typeContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Rowid_type_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.String_length_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Timestamp_type_iContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Treat_data_typeContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Udt_type_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.common.CharacterType;
@@ -58,31 +68,49 @@
*/
public class OracleDataTypeFactory extends OBParserBaseVisitor implements StatementFactory {
- private final Data_typeContext dataTypeContext;
- private final Cast_data_typeContext castDataTypeContext;
+ private final ParserRuleContext parserRuleContext;
public OracleDataTypeFactory(@NonNull Data_typeContext dataTypeContext) {
- this.dataTypeContext = dataTypeContext;
- this.castDataTypeContext = null;
+ this.parserRuleContext = dataTypeContext;
}
public OracleDataTypeFactory(@NonNull Cast_data_typeContext castDataTypeContext) {
- this.dataTypeContext = null;
- this.castDataTypeContext = castDataTypeContext;
+ this.parserRuleContext = castDataTypeContext;
+ }
+
+ public OracleDataTypeFactory(@NonNull Treat_data_typeContext treatDataTypeContext) {
+ this.parserRuleContext = treatDataTypeContext;
+ }
+
+ public OracleDataTypeFactory(@NonNull Opt_jt_value_typeContext optJtValueTypeContext) {
+ this.parserRuleContext = optJtValueTypeContext;
+ }
+
+ public OracleDataTypeFactory(@NonNull Js_value_return_typeContext jsValueReturnTypeContext) {
+ this.parserRuleContext = jsValueReturnTypeContext;
+ }
+
+ public OracleDataTypeFactory(@NonNull Js_query_return_typeContext jsQueryReturnTypeContext) {
+ this.parserRuleContext = jsQueryReturnTypeContext;
+ }
+
+ public OracleDataTypeFactory(@NonNull Js_return_typeContext jsReturnTypeContext) {
+ this.parserRuleContext = jsReturnTypeContext;
+ }
+
+ public OracleDataTypeFactory(@NonNull Js_agg_returning_typeContext jsAggReturningTypeContext) {
+ this.parserRuleContext = jsAggReturningTypeContext;
}
@Override
public DataType generate() {
- if (this.dataTypeContext != null) {
- return visit(this.dataTypeContext);
- }
- return visit(this.castDataTypeContext);
+ return visit(this.parserRuleContext);
}
@Override
public DataType visitData_type(Data_typeContext ctx) {
- if (ctx.STRING_VALUE() != null) {
- return new GeneralDataType(ctx, ctx.STRING_VALUE().getText(), null);
+ if (ctx.STRING_VALUE() != null || ctx.JSON() != null || ctx.XMLTYPE() != null) {
+ return new GeneralDataType(ctx, ctx.getChild(0).getText(), null);
} else if (ctx.character_type_i() != null) {
CharacterType type = new CharacterType(ctx, (CharacterType) visit(ctx.character_type_i()));
if (ctx.charset_name() != null) {
@@ -96,6 +124,143 @@ public DataType visitData_type(Data_typeContext ctx) {
return visitChildren(ctx);
}
+ @Override
+ public DataType visitOpt_jt_value_type(Opt_jt_value_typeContext ctx) {
+ if (ctx.CHAR() != null || ctx.NVARCHAR2() != null || ctx.NCHAR() != null) {
+ return getDataType(new TextTypeOpt() {
+ @Override
+ public ParserRuleContext getCtx() {
+ return ctx;
+ }
+
+ @Override
+ public String getTypeName() {
+ return ctx.getChild(0).getText();
+ }
+
+ @Override
+ public String_length_iContext getStringLengthIContext() {
+ return ctx.string_length_i();
+ }
+
+ @Override
+ public Nstring_length_iContext getNstringLengthIContext() {
+ return ctx.nstring_length_i();
+ }
+
+ @Override
+ public boolean isBinary() {
+ return ctx.BINARY() != null;
+ }
+ });
+ }
+ return visitChildren(ctx);
+ }
+
+ @Override
+ public DataType visitJs_value_return_type(Js_value_return_typeContext ctx) {
+ if (ctx.NUMBER() != null) {
+ return getNumberType(ctx.NUMBER().getText(), ctx, ctx.number_precision());
+ }
+ return visitChildren(ctx);
+ }
+
+ @Override
+ public DataType visitJs_query_return_type(Js_query_return_typeContext ctx) {
+ if (ctx.BLOB() != null || ctx.JSON() != null) {
+ return new GeneralDataType(ctx, ctx.getChild(0).getText(), null);
+ }
+ return visitChildren(ctx);
+ }
+
+ @Override
+ public DataType visitJs_agg_returning_type(Js_agg_returning_typeContext ctx) {
+ if (ctx.RAW() != null) {
+ List args = new ArrayList<>();
+ if (ctx.zero_suffix_intnum() != null) {
+ args.add(ctx.zero_suffix_intnum().getText());
+ }
+ return new GeneralDataType(ctx, ctx.RAW().getText(), args);
+ }
+ return getDataType(new TextTypeOpt() {
+ @Override
+ public ParserRuleContext getCtx() {
+ return ctx;
+ }
+
+ @Override
+ public String getTypeName() {
+ return ctx.NVARCHAR2().getText();
+ }
+
+ @Override
+ public String_length_iContext getStringLengthIContext() {
+ return null;
+ }
+
+ @Override
+ public Nstring_length_iContext getNstringLengthIContext() {
+ return ctx.nstring_length_i();
+ }
+
+ @Override
+ public boolean isBinary() {
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public DataType visitJs_return_type(Js_return_typeContext ctx) {
+ if (ctx.BLOB() != null || ctx.JSON() != null) {
+ return new GeneralDataType(ctx, ctx.getChild(0).getText(), null);
+ }
+ return visitChildren(ctx);
+ }
+
+ @Override
+ public DataType visitJs_return_text_type(Js_return_text_typeContext ctx) {
+ return getDataType(new TextTypeOpt() {
+ @Override
+ public ParserRuleContext getCtx() {
+ return ctx;
+ }
+
+ @Override
+ public String getTypeName() {
+ return ctx.getChild(0).getText();
+ }
+
+ @Override
+ public String_length_iContext getStringLengthIContext() {
+ return ctx.string_length_i();
+ }
+
+ @Override
+ public Nstring_length_iContext getNstringLengthIContext() {
+ return null;
+ }
+
+ @Override
+ public boolean isBinary() {
+ return ctx.BINARY() != null;
+ }
+ });
+ }
+
+ @Override
+ public DataType visitTreat_data_type(Treat_data_typeContext ctx) {
+ if (ctx.JSON() != null) {
+ return new GeneralDataType(ctx, ctx.JSON().getText(), null);
+ }
+ return visitChildren(ctx);
+ }
+
+ @Override
+ public DataType visitJs_return_default_type(Js_return_default_typeContext ctx) {
+ return null;
+ }
+
@Override
public DataType visitInt_type_i(Int_type_iContext ctx) {
return new NumberType(ctx, ctx.getText(), null, null);
@@ -125,26 +290,7 @@ public DataType visitDouble_type_i(Double_type_iContext ctx) {
@Override
public DataType visitNumber_type_i(Number_type_iContext ctx) {
- List args = new ArrayList<>();
- visitNumberPrecision(ctx.number_precision(), args);
- BigDecimal first = null;
- BigDecimal second = null;
- boolean starPrecision = false;
- if (!args.isEmpty()) {
- if (!"*".equals(args.get(0))) {
- first = new BigDecimal(args.get(0));
- } else {
- starPrecision = true;
- }
- if (args.size() > 1) {
- second = new BigDecimal(args.get(1));
- }
- }
- NumberType numberType = new NumberType(ctx, ctx.getChild(0).getText(), first, second);
- if (starPrecision) {
- numberType.setStarPresicion(true);
- }
- return numberType;
+ return getNumberType(ctx.getChild(0).getText(), ctx, ctx.number_precision());
}
@Override
@@ -169,23 +315,32 @@ public DataType visitDatetime_type_i(Datetime_type_iContext ctx) {
@Override
public DataType visitCharacter_type_i(Character_type_iContext ctx) {
- List args = new ArrayList<>();
- String typeName = ctx.getChild(0).getText();
- visitStringLengthI(ctx.string_length_i(), args);
- CharacterType type;
- if (args.isEmpty()) {
- type = new CharacterType(ctx, typeName, null);
- } else {
- String[] arg = args.get(0).split(" ");
- type = new CharacterType(ctx, typeName, new BigDecimal(arg[0]));
- if (arg.length > 1) {
- type.setLengthOption(arg[1]);
+ return getDataType(new TextTypeOpt() {
+ @Override
+ public ParserRuleContext getCtx() {
+ return ctx;
}
- }
- if (ctx.BINARY() != null) {
- type.setBinary(true);
- }
- return type;
+
+ @Override
+ public String getTypeName() {
+ return ctx.getChild(0).getText();
+ }
+
+ @Override
+ public String_length_iContext getStringLengthIContext() {
+ return ctx.string_length_i();
+ }
+
+ @Override
+ public Nstring_length_iContext getNstringLengthIContext() {
+ return null;
+ }
+
+ @Override
+ public boolean isBinary() {
+ return ctx.BINARY() != null;
+ }
+ });
}
@Override
@@ -231,6 +386,30 @@ public DataType visitUdt_type_i(Udt_type_iContext ctx) {
return new GeneralDataType(ctx, ctx.getText(), null);
}
+ private DataType getNumberType(String typeName, ParserRuleContext parent,
+ Number_precisionContext numberPrecisionContext) {
+ List args = new ArrayList<>();
+ visitNumberPrecision(numberPrecisionContext, args);
+ BigDecimal first = null;
+ BigDecimal second = null;
+ boolean starPrecision = false;
+ if (!args.isEmpty()) {
+ if (!"*".equals(args.get(0))) {
+ first = new BigDecimal(args.get(0));
+ } else {
+ starPrecision = true;
+ }
+ if (args.size() > 1) {
+ second = new BigDecimal(args.get(1));
+ }
+ }
+ NumberType numberType = new NumberType(parent, typeName, first, second);
+ if (starPrecision) {
+ numberType.setStarPresicion(true);
+ }
+ return numberType;
+ }
+
private void visitNumberPrecision(Number_precisionContext ctx, List args) {
if (ctx == null) {
return;
@@ -247,7 +426,7 @@ private void visitNumberPrecision(Number_precisionContext ctx, List args
}
}
- private void visitStringLengthI(String_length_iContext ctx, List args) {
+ private static void visitStringLengthI(String_length_iContext ctx, List args) {
if (ctx == null) {
return;
}
@@ -258,6 +437,13 @@ private void visitStringLengthI(String_length_iContext ctx, List args) {
args.add(builder.toString());
}
+ private static void visitNstringLengthI(Nstring_length_iContext ctx, List args) {
+ if (ctx == null) {
+ return;
+ }
+ args.add(ctx.zero_suffix_intnum().getText());
+ }
+
private String getPrecision(Data_type_precisionContext context) {
if (context.precision_int_num() != null) {
return context.precision_int_num().getText();
@@ -265,4 +451,36 @@ private String getPrecision(Data_type_precisionContext context) {
return context.precision_decimal_num().getText();
}
+ public static DataType getDataType(TextTypeOpt opt) {
+ List args = new ArrayList<>();
+ visitStringLengthI(opt.getStringLengthIContext(), args);
+ visitNstringLengthI(opt.getNstringLengthIContext(), args);
+ CharacterType type;
+ if (args.isEmpty()) {
+ type = new CharacterType(opt.getCtx(), opt.getTypeName(), null);
+ } else {
+ String[] arg = args.get(0).split(" ");
+ type = new CharacterType(opt.getCtx(), opt.getTypeName(), new BigDecimal(arg[0]));
+ if (arg.length > 1) {
+ type.setLengthOption(arg[1]);
+ }
+ }
+ if (opt.isBinary()) {
+ type.setBinary(true);
+ }
+ return type;
+ }
+
+ interface TextTypeOpt {
+ ParserRuleContext getCtx();
+
+ String getTypeName();
+
+ String_length_iContext getStringLengthIContext();
+
+ Nstring_length_iContext getNstringLengthIContext();
+
+ boolean isBinary();
+ }
+
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleExpressionFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleExpressionFactory.java
index 8e8bf31f09..1aee1dd5b2 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleExpressionFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleExpressionFactory.java
@@ -16,16 +16,22 @@
package com.oceanbase.tools.sqlparser.adapter.oracle;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
+import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.apache.commons.collections4.CollectionUtils;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.adapter.oracle.OracleDataTypeFactory.TextTypeOpt;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Access_func_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Access_func_expr_countContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Aggregate_functionContext;
@@ -35,20 +41,66 @@
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Case_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Character_functionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Collection_predicate_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Column_nameContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Conversion_functionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Cur_timestamp_funcContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Dot_notation_fun_sysContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Dot_notation_pathContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Dot_notation_path_obj_access_refContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Entry_opContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Evalname_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.ExprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Func_access_refContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Func_paramContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Func_param_with_assignContext;
-import com.oceanbase.tools.sqlparser.oboracle.OBParser.Function_nameContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.In_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Is_json_constrainContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_agg_on_nullContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Js_agg_returning_type_optContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_array_contentContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_array_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_exists_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_exists_response_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_mergepatch_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_obj_unique_keyContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_object_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_query_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_query_on_optContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_column_defContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_column_def_pathContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_exists_column_defContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_nested_column_defContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_on_responseContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_ordinality_column_defContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_query_column_defContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_table_value_column_defContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_value_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_value_on_empty_responseContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_value_on_error_responseContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_value_on_optContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Json_value_on_responseContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Nstring_length_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Obj_access_refContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Obj_access_ref_normalContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_js_value_returning_typeContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_json_existContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_json_exists_on_error_on_emptyContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_json_mergepatchContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_json_object_clauseContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_json_table_on_error_on_emptyContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_response_queryContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Opt_response_query_on_empty_errorContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Parameterized_trimContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.PredicateContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Regular_entry_objContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Relation_nameContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Scalars_optContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Signed_literalContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Simple_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Single_row_functionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Special_func_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.String_length_iContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Table_element_access_listContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Table_indexContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Unary_exprContext;
@@ -56,11 +108,23 @@
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Win_fun_first_last_paramsContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Win_fun_lead_lag_paramsContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Window_functionContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Wrapper_optsContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xml_attributes_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xml_attributes_value_clauseContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xml_element_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xml_extract_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xml_tagContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xmlcast_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xmlparse_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Xmlserialize_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
+import com.oceanbase.tools.sqlparser.statement.Expression.ReferenceOperator;
import com.oceanbase.tools.sqlparser.statement.Operator;
import com.oceanbase.tools.sqlparser.statement.Statement;
-import com.oceanbase.tools.sqlparser.statement.common.WindowSpec;
+import com.oceanbase.tools.sqlparser.statement.common.DataType;
+import com.oceanbase.tools.sqlparser.statement.common.GeneralDataType;
+import com.oceanbase.tools.sqlparser.statement.common.oracle.KeepClause;
import com.oceanbase.tools.sqlparser.statement.expression.BoolValue;
import com.oceanbase.tools.sqlparser.statement.expression.CaseWhen;
import com.oceanbase.tools.sqlparser.statement.expression.CollectionExpression;
@@ -70,16 +134,23 @@
import com.oceanbase.tools.sqlparser.statement.expression.DefaultExpression;
import com.oceanbase.tools.sqlparser.statement.expression.ExpressionParam;
import com.oceanbase.tools.sqlparser.statement.expression.FullTextSearch;
-import com.oceanbase.tools.sqlparser.statement.expression.FunctionAccess;
import com.oceanbase.tools.sqlparser.statement.expression.FunctionCall;
import com.oceanbase.tools.sqlparser.statement.expression.FunctionParam;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonConstraint;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonConstraint.ScalarsMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonConstraint.StrictMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonConstraint.UniqueMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonConstraint.WrapperMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonKeyValue;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOnOption;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOnOption.OnMismatch;
import com.oceanbase.tools.sqlparser.statement.expression.NullExpression;
import com.oceanbase.tools.sqlparser.statement.expression.ParamWithAssign;
import com.oceanbase.tools.sqlparser.statement.expression.RelationReference;
import com.oceanbase.tools.sqlparser.statement.expression.TextSearchMode;
import com.oceanbase.tools.sqlparser.statement.expression.WhenClause;
-import com.oceanbase.tools.sqlparser.statement.expression.WindowFunction;
import com.oceanbase.tools.sqlparser.statement.select.OrderBy;
+import com.oceanbase.tools.sqlparser.statement.select.SelectBody;
import lombok.NonNull;
@@ -99,6 +170,10 @@ public OracleExpressionFactory(@NonNull ExprContext context) {
this.parserRuleContext = context;
}
+ public OracleExpressionFactory(@NonNull PredicateContext context) {
+ this.parserRuleContext = context;
+ }
+
public OracleExpressionFactory() {
this.parserRuleContext = null;
}
@@ -120,6 +195,14 @@ public Expression generate() {
return this.parserRuleContext == null ? null : visit(this.parserRuleContext);
}
+ @Override
+ public Expression visit(ParseTree parseTree) {
+ if (parseTree == null) {
+ return null;
+ }
+ return super.visit(parseTree);
+ }
+
@Override
public Expression visitExpr(ExprContext ctx) {
if (ctx.bool_pri() != null) {
@@ -211,7 +294,12 @@ public Expression visitSimple_expr(Simple_exprContext ctx) {
return new ConstExpression(ctx.expr_const());
} else if (ctx.select_with_parens() != null) {
OracleSelectBodyFactory selectFactory = new OracleSelectBodyFactory(ctx.select_with_parens());
- return selectFactory.generate();
+ SelectBody selectBody = selectFactory.generate();
+ if (ctx.MULTISET() == null) {
+ return selectBody;
+ }
+ return new FunctionCall(ctx, ctx.MULTISET().getText(),
+ Collections.singletonList(new ExpressionParam(selectBody)));
} else if (ctx.select_stmt() != null) {
OracleSelectFactory selectFactory = new OracleSelectFactory(ctx.select_stmt());
FunctionParam p = new ExpressionParam(selectFactory.generate());
@@ -226,13 +314,32 @@ public Expression visitSimple_expr(Simple_exprContext ctx) {
return exprs;
}
if (ctx.SET() != null) {
- CollectionExpression exprs = new CollectionExpression(ctx);
- exprs.addExpression(visit(ctx.bit_expr()));
- return exprs;
+ FunctionParam p = new ExpressionParam(visit(ctx.bit_expr()));
+ return new FunctionCall(ctx, ctx.SET().getText(), Collections.singletonList(p));
}
return visit(ctx.bit_expr());
} else if (ctx.USER_VARIABLE() != null) {
- return new ConstExpression(ctx.USER_VARIABLE());
+ if (CollectionUtils.isEmpty(ctx.column_ref())) {
+ return new ConstExpression(ctx.USER_VARIABLE());
+ }
+ RelationReference seq = new RelationReference(
+ ctx.column_ref(ctx.column_ref().size() - 2),
+ ctx.column_ref(ctx.column_ref().size() - 2).getText());
+ RelationReference column = new RelationReference(
+ ctx.column_ref(ctx.column_ref().size() - 1),
+ ctx.column_ref(ctx.column_ref().size() - 1).getText());
+ column.setUserVariable(ctx.USER_VARIABLE().getText());
+ seq.reference(column, ReferenceOperator.DOT);
+ if (ctx.column_ref().size() < 3) {
+ return seq;
+ }
+ RelationReference ref = new RelationReference(
+ ctx.column_ref(ctx.column_ref().size() - 3),
+ ctx.column_ref(ctx.column_ref().size() - 3).getText());
+ ref.reference(seq, ReferenceOperator.DOT);
+ return ref;
+ } else if (ctx.PLSQL_VARIABLE() != null) {
+ return new ConstExpression(ctx.PLSQL_VARIABLE());
} else if (ctx.unary_expr() != null) {
Operator operator = ctx.PRIOR() == null ? Operator.CONNECT_BY_ROOT : Operator.PRIOR;
return new CompoundExpression(ctx, visit(ctx.unary_expr()), null, operator);
@@ -286,8 +393,151 @@ public Expression visitObj_access_ref(Obj_access_refContext ctx) {
return visitColumnRef(ctx);
} else if (ctx.access_func_expr() != null) {
return visitAccessFunctionExpr(ctx);
+ } else if (ctx.QUESTIONMARK() != null) {
+ ConstExpression ref = new ConstExpression(ctx.QUESTIONMARK());
+ visitFunctionAccessReference(ref, ctx.func_access_ref());
+ return ref;
}
- return new DefaultExpression(ctx);
+ return visit(ctx.dot_notation_fun_sys());
+ }
+
+ @Override
+ public Expression visitDot_notation_fun_sys(Dot_notation_fun_sysContext ctx) {
+ return new FunctionCall(ctx, ctx.dot_notation_fun().func_name.getText(), Collections.emptyList());
+ }
+
+ @Override
+ public Expression visitXmlparse_expr(Xmlparse_exprContext ctx) {
+ FunctionParam p = new ExpressionParam(visit(ctx.xml_text().bit_expr()));
+ if (ctx.WELLFORMED() != null) {
+ p.addOption(new ConstExpression(ctx.WELLFORMED()));
+ }
+ FunctionCall functionCall = new FunctionCall(ctx, ctx.XMLPARSE().getText(), Collections.singletonList(p));
+ functionCall.addOption(new ConstExpression(ctx.xml_doc_type()));
+ return functionCall;
+ }
+
+ @Override
+ public Expression visitXmlcast_expr(Xmlcast_exprContext ctx) {
+ FunctionParam p = new ExpressionParam(visit(ctx.bit_expr()));
+ if (ctx.cast_data_type() != null) {
+ p.addOption(new OracleDataTypeFactory(ctx.cast_data_type()).generate());
+ }
+ return new FunctionCall(ctx, ctx.XMLCAST().getText(), Collections.singletonList(p));
+ }
+
+ @Override
+ public Expression visitXmlserialize_expr(Xmlserialize_exprContext ctx) {
+ FunctionParam p = new ExpressionParam(visit(ctx.bit_expr()));
+ if (ctx.cast_data_type() != null) {
+ p.addOption(new OracleDataTypeFactory(ctx.cast_data_type()).generate());
+ }
+ FunctionCall functionCall = new FunctionCall(ctx,
+ ctx.XMLSERIALIZE().getText(), Collections.singletonList(p));
+ functionCall.addOption(new ConstExpression(ctx.xml_doc_type()));
+ if (ctx.STRING_VALUE() != null) {
+ functionCall.addOption(new ConstExpression(ctx.ENCODING(), ctx.STRING_VALUE()));
+ }
+ if (ctx.literal() != null) {
+ functionCall.addOption(new ConstExpression(ctx.VERSION(), ctx.literal()));
+ }
+ if (ctx.INDENT() != null) {
+ if (ctx.NO() != null) {
+ functionCall.addOption(new ConstExpression(ctx.NO(), ctx.INDENT()));
+ } else if (ctx.SIZE() != null) {
+ Expression left = new ConstExpression(ctx.INDENT(), ctx.SIZE());
+ Expression right = new ConstExpression(ctx.signed_int_num().INTNUM());
+ if (ctx.signed_int_num().Minus() != null) {
+ right = new CompoundExpression(ctx.signed_int_num(), right, null, Operator.SUB);
+ }
+ functionCall.addOption(new CompoundExpression(
+ ctx.signed_int_num(), left, right, Operator.EQ));
+ } else {
+ functionCall.addOption(new ConstExpression(ctx.INDENT()));
+ }
+ }
+ if (ctx.DEFAULTS() != null) {
+ if (ctx.HIDE() != null) {
+ functionCall.addOption(new ConstExpression(ctx.HIDE(), ctx.DEFAULTS()));
+ } else if (ctx.SHOW() != null) {
+ functionCall.addOption(new ConstExpression(ctx.SHOW(), ctx.DEFAULTS()));
+ }
+ }
+ return functionCall;
+ }
+
+ @Override
+ public Expression visitXml_extract_expr(Xml_extract_exprContext ctx) {
+ List params = ctx.bit_expr().stream()
+ .map(c -> new ExpressionParam(visit(c))).collect(Collectors.toList());
+ if (ctx.literal() != null) {
+ params.add(new ExpressionParam(new ConstExpression(ctx.literal())));
+ }
+ return new FunctionCall(ctx, ctx.EXTRACT().getText(), params);
+ }
+
+ @Override
+ public Expression visitXml_element_expr(Xml_element_exprContext ctx) {
+ Xml_tagContext tCtx = ctx.xml_tag();
+ List params = new ArrayList<>();
+ FunctionParam xmlTag;
+ List functionOpts = new ArrayList<>();
+ if (tCtx.element_name().column_name() != null) {
+ Column_nameContext cCtx = tCtx.element_name().column_name();
+ xmlTag = new ExpressionParam(new ColumnReference(cCtx, null, null, cCtx.getText()));
+ } else {
+ xmlTag = new ExpressionParam(visit(tCtx.element_name().evalname_expr()));
+ }
+ if (tCtx.element_name().NAME() != null) {
+ xmlTag.addOption(new ConstExpression(tCtx.element_name().NAME()));
+ } else if (tCtx.element_name().EVALNAME() != null) {
+ xmlTag.addOption(new ConstExpression(tCtx.element_name().EVALNAME()));
+ }
+ if (tCtx.ENTITYESCAPING() != null) {
+ functionOpts.add(new ConstExpression(tCtx.ENTITYESCAPING()));
+ } else if (tCtx.NOENTITYESCAPING() != null) {
+ functionOpts.add(new ConstExpression(tCtx.NOENTITYESCAPING()));
+ }
+ params.add(xmlTag);
+ if (ctx.xml_attributes_expr() != null) {
+ Xml_attributes_exprContext xCtx = ctx.xml_attributes_expr();
+ List xmlAttrsParams = new ArrayList<>();
+ fullFillXmlAttrs(xmlAttrsParams, ctx.xml_attributes_expr().xml_attributes_value_clause());
+ FunctionCall xmlAttrs = new FunctionCall(xCtx, xCtx.XMLATTRIBUTES().getText(), xmlAttrsParams);
+ if (xCtx.ENTITYESCAPING() != null) {
+ xmlAttrs.addOption(new ConstExpression(xCtx.ENTITYESCAPING()));
+ } else if (xCtx.NOENTITYESCAPING() != null) {
+ xmlAttrs.addOption(new ConstExpression(xCtx.NOENTITYESCAPING()));
+ }
+ if (xCtx.NOSCHEMACHECK() != null) {
+ xmlAttrs.addOption(new ConstExpression(xCtx.NOSCHEMACHECK()));
+ } else if (xCtx.SCHEMACHECK() != null) {
+ xmlAttrs.addOption(new ConstExpression(xCtx.SCHEMACHECK()));
+ }
+ params.add(new ExpressionParam(xmlAttrs));
+ }
+ if (ctx.xml_value_clause() != null) {
+ params.addAll(ctx.xml_value_clause().xml_value().stream().map(c -> {
+ FunctionParam in = new ExpressionParam(visit(c.bit_expr()));
+ if (c.column_label() == null) {
+ return in;
+ }
+ in.addOption(new RelationReference(c.column_label(), c.column_label().getText()));
+ return in;
+ }).collect(Collectors.toList()));
+ }
+ FunctionCall fCall = new FunctionCall(ctx, ctx.XMLELEMENT().getText(), params);
+ functionOpts.forEach(fCall::addOption);
+ return fCall;
+ }
+
+ @Override
+ public Expression visitEvalname_expr(Evalname_exprContext ctx) {
+ if (ctx.simple_expr() != null) {
+ return visit(ctx.simple_expr());
+ }
+ return new CompoundExpression(ctx, visit(ctx.evalname_expr(0)),
+ visit(ctx.evalname_expr(1)), Operator.CNNOP);
}
@Override
@@ -304,6 +554,268 @@ public Expression visitBool_pri_in_pl_func(Bool_pri_in_pl_funcContext ctx) {
return new CompoundExpression(ctx, visit(contexts.get(0)), visit(contexts.get(1)), operator);
}
+ @Override
+ public Expression visitIs_json_constrain(Is_json_constrainContext ctx) {
+ JsonConstraint constraint = new JsonConstraint(ctx);
+ if (ctx.strict_opt() != null) {
+ constraint.setStrictMode(ctx.strict_opt().LAX() != null ? StrictMode.LAX : StrictMode.STRICT);
+ }
+ setScalarsMode(constraint, ctx.scalars_opt());
+ if (ctx.unique_keys_opt() != null) {
+ constraint.setUniqueMode(ctx.unique_keys_opt().WITH() != null ? UniqueMode.WITH_UNIQUE_KEYS
+ : UniqueMode.WITHOUT_UNIQUE_KEYS);
+ }
+ return constraint;
+ }
+
+ @Override
+ public Expression visitJson_object_expr(Json_object_exprContext ctx) {
+ List params = new ArrayList<>();
+ Entry_opContext eCtx = ctx.opt_json_object_content().entry_op();
+ if (eCtx != null) {
+ if (eCtx.Star() != null) {
+ params.add(new ExpressionParam(new ConstExpression(eCtx.Star())));
+ } else {
+ params = eCtx.entry_set().entry_obj().stream().map(c -> {
+ FunctionParam p = new ExpressionParam(visit(c.regular_entry_obj()));
+ if (c.FORMAT() == null) {
+ return p;
+ }
+ p.addOption(new ConstExpression(c.FORMAT(), c.JSON()));
+ return p;
+ }).collect(Collectors.toList());
+ }
+ }
+ FunctionCall fCall = new FunctionCall(ctx, "json_object", params);
+ if (ctx.opt_json_object_content().opt_json_object_clause() != null) {
+ Opt_json_object_clauseContext oCtx = ctx.opt_json_object_content().opt_json_object_clause();
+ if (oCtx.js_on_null() != null) {
+ JsonOnOption onOption = new JsonOnOption(oCtx.js_on_null());
+ if (oCtx.js_on_null().ABSENT() != null) {
+ onOption.setOnNull(new ConstExpression(oCtx.js_on_null().ABSENT()));
+ } else {
+ onOption.setOnNull(new NullExpression(oCtx.js_on_null().NULLX(0)));
+ }
+ fCall.addOption(onOption);
+ }
+ if (oCtx.json_obj_returning_type() != null) {
+ fCall.addOption(new OracleDataTypeFactory(
+ oCtx.json_obj_returning_type().js_return_type()).generate());
+ }
+ if (oCtx.STRICT() != null || oCtx.json_obj_unique_key() != null) {
+ fCall.addOption(getJsonConstraint(oCtx.STRICT(), oCtx.json_obj_unique_key()));
+ }
+ } else if (ctx.opt_json_object_content().STRICT() != null) {
+ fCall.addOption(getJsonConstraint(ctx.opt_json_object_content().STRICT(),
+ ctx.opt_json_object_content().json_obj_unique_key()));
+ } else {
+ fCall.addOption(getJsonConstraint(null, ctx.opt_json_object_content().json_obj_unique_key()));
+ }
+ return fCall;
+ }
+
+ private JsonConstraint getJsonConstraint(TerminalNode strict, Json_obj_unique_keyContext ctx) {
+ JsonConstraint jc;
+ if (strict != null && ctx != null) {
+ jc = new JsonConstraint(strict, ctx);
+ jc.setStrictMode(StrictMode.STRICT);
+ jc.setUniqueMode(UniqueMode.WITH_UNIQUE_KEYS);
+ } else if (strict != null) {
+ jc = new JsonConstraint(strict);
+ jc.setStrictMode(StrictMode.STRICT);
+ } else {
+ jc = new JsonConstraint(ctx);
+ jc.setUniqueMode(UniqueMode.WITH_UNIQUE_KEYS);
+ }
+ return jc;
+ }
+
+ @Override
+ public Expression visitRegular_entry_obj(Regular_entry_objContext ctx) {
+ if (ctx.JSON_OBJECT_VALUE() != null) {
+ String[] kvs = ctx.JSON_OBJECT_VALUE().getText().split(":");
+ if (kvs.length != 2) {
+ return new ConstExpression(ctx.JSON_OBJECT_VALUE());
+ }
+ Expression key = new ConstExpression(kvs[0].trim());
+ Expression value;
+ char firstC = kvs[1].charAt(0);
+ if (firstC > '0' && firstC < '9') {
+ value = new ConstExpression(kvs[1]);
+ } else {
+ value = new RelationReference(kvs[1], null);
+ }
+ return new JsonKeyValue(ctx, key, value);
+ }
+ if (ctx.VALUE() != null) {
+ return new JsonKeyValue(ctx,
+ visit(ctx.json_obj_literal_expr(0).bit_expr()),
+ visit(ctx.json_obj_literal_expr(1).bit_expr()));
+ }
+ Expression value = visit(ctx.json_obj_literal_expr(0).bit_expr());
+ if (ctx.json_obj_literal_key() == null) {
+ return value;
+ }
+ Expression key = new ConstExpression(ctx.json_obj_literal_key());
+ return new JsonKeyValue(ctx, key, value);
+ }
+
+ @Override
+ public Expression visitJson_query_expr(Json_query_exprContext ctx) {
+ FunctionParam p1 = new ExpressionParam(visit(ctx.js_doc_expr().bit_expr()));
+ if (ctx.js_doc_expr().JSON() != null) {
+ p1.addOption(new ConstExpression(ctx.js_doc_expr().FORMAT(), ctx.js_doc_expr().JSON()));
+ }
+ FunctionParam p2 = new ExpressionParam(new ConstExpression(ctx.js_literal().literal()));
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_QUERY().getText(), Arrays.asList(p1, p2));
+ if (ctx.js_query_return_type() != null) {
+ fCall.addOption(new OracleDataTypeFactory(ctx.js_query_return_type()).generate());
+ }
+ if (ctx.TRUNCATE() != null) {
+ fCall.addOption(new ConstExpression(ctx.TRUNCATE()));
+ }
+ if (ctx.PRETTY() != null) {
+ fCall.addOption(new ConstExpression(ctx.PRETTY()));
+ }
+ if (ctx.ASCII() != null) {
+ fCall.addOption(new ConstExpression(ctx.ASCII()));
+ }
+ if (ctx.scalars_opt() != null || ctx.wrapper_opts() != null) {
+ JsonConstraint constraint = new JsonConstraint(
+ ctx.scalars_opt() == null ? ctx.wrapper_opts() : ctx.scalars_opt());
+ setScalarsMode(constraint, ctx.scalars_opt());
+ setWrapperMode(constraint, ctx.wrapper_opts());
+ fCall.addOption(constraint);
+ }
+ fCall.addOption(getJsonOnOption(ctx.json_query_on_opt()));
+ return fCall;
+ }
+
+ @Override
+ public Expression visitJson_mergepatch_expr(Json_mergepatch_exprContext ctx) {
+ FunctionParam p1 = new ExpressionParam(visit(ctx.bit_expr(0)));
+ FunctionParam p2 = new ExpressionParam(visit(ctx.bit_expr(1)));
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_MERGEPATCH().getText(), Arrays.asList(p1, p2));
+ if (ctx.js_mp_return_clause() != null) {
+ fCall.addOption(new OracleDataTypeFactory(ctx.js_mp_return_clause().js_return_type()).generate());
+ }
+ Opt_json_mergepatchContext oCtx = ctx.opt_json_mergepatch();
+ if (oCtx.TRUNCATE() != null) {
+ fCall.addOption(new ConstExpression(oCtx.TRUNCATE()));
+ }
+ if (oCtx.PRETTY() != null) {
+ fCall.addOption(new ConstExpression(oCtx.PRETTY()));
+ }
+ if (oCtx.ASCII() != null) {
+ fCall.addOption(new ConstExpression(oCtx.ASCII()));
+ }
+ if (ctx.json_mergepatch_on_error() != null) {
+ JsonOnOption jsonOnOption = new JsonOnOption(ctx.json_mergepatch_on_error());
+ if (ctx.json_mergepatch_on_error().NULLX() != null) {
+ jsonOnOption.setOnError(new NullExpression(ctx.json_mergepatch_on_error().NULLX()));
+ } else {
+ jsonOnOption.setOnError(new ConstExpression(ctx.json_mergepatch_on_error().ERROR_P(0)));
+ }
+ fCall.addOption(jsonOnOption);
+ }
+ return fCall;
+ }
+
+ @Override
+ public Expression visitJson_array_expr(Json_array_exprContext ctx) {
+ if (ctx.json_array_content() == null) {
+ return new FunctionCall(ctx, "json_array", Collections.emptyList());
+ }
+ Json_array_contentContext jCtx = ctx.json_array_content();
+ List params = jCtx.js_array_eles().js_array_ele().stream().map(c -> {
+ FunctionParam p = new ExpressionParam(visit(c.bit_expr()));
+ if (c.JSON() == null) {
+ return p;
+ }
+ p.addOption(new ConstExpression(c.FORMAT(), c.JSON()));
+ return p;
+ }).collect(Collectors.toList());
+ FunctionCall fCall = new FunctionCall(ctx, "json_array", params);
+ if (jCtx.json_array_on_null() != null) {
+ JsonOnOption jsonOnOption = new JsonOnOption(jCtx.json_array_on_null());
+ if (jCtx.json_array_on_null().ABSENT() != null) {
+ jsonOnOption.setOnNull(new ConstExpression(jCtx.json_array_on_null().ABSENT()));
+ } else {
+ jsonOnOption.setOnNull(new NullExpression(jCtx.json_array_on_null().NULLX(0)));
+ }
+ fCall.addOption(jsonOnOption);
+ }
+ if (jCtx.js_array_return_clause() != null) {
+ fCall.addOption(new OracleDataTypeFactory(jCtx.js_array_return_clause().js_return_type()).generate());
+ }
+ if (jCtx.STRICT() != null) {
+ JsonConstraint jsonConstraint = new JsonConstraint(jCtx.STRICT());
+ jsonConstraint.setStrictMode(StrictMode.STRICT);
+ fCall.addOption(jsonConstraint);
+ }
+ return fCall;
+ }
+
+ @Override
+ public Expression visitJson_value_expr(Json_value_exprContext ctx) {
+ FunctionParam p1 = new ExpressionParam(visit(ctx.js_doc_expr().bit_expr()));
+ if (ctx.js_doc_expr().JSON() != null) {
+ p1.addOption(new ConstExpression(ctx.js_doc_expr().FORMAT(), ctx.js_doc_expr().JSON()));
+ }
+ FunctionParam p2 = new ExpressionParam(new ConstExpression(ctx.js_literal().literal()));
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_VALUE().getText(), Arrays.asList(p1, p2));
+ DataType dataType = getDataType(ctx.opt_js_value_returning_type());
+ if (dataType != null) {
+ fCall.addOption(dataType);
+ }
+ if (ctx.TRUNCATE() != null) {
+ fCall.addOption(new ConstExpression(ctx.TRUNCATE()));
+ }
+ if (ctx.ASCII() != null) {
+ fCall.addOption(new ConstExpression(ctx.ASCII()));
+ }
+ fCall.addOption(getJsonOnOption(ctx.json_value_on_opt()));
+ return fCall;
+ }
+
+ @Override
+ public Expression visitJson_exists_expr(Json_exists_exprContext ctx) {
+ FunctionParam p1 = new ExpressionParam(visit(ctx.js_doc_expr().bit_expr()));
+ if (ctx.js_doc_expr().JSON() != null) {
+ p1.addOption(new ConstExpression(ctx.js_doc_expr().FORMAT(), ctx.js_doc_expr().JSON()));
+ }
+ FunctionParam p2 = new ExpressionParam(new ConstExpression(ctx.literal()));
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_EXISTS().getText(), Arrays.asList(p1, p2));
+ setJsonExistOpt(fCall, ctx.opt_json_exist());
+ return fCall;
+ }
+
+ @Override
+ public Expression visitJson_table_expr(Json_table_exprContext ctx) {
+ List params = new ArrayList<>();
+ FunctionParam p1 = new ExpressionParam(visit(ctx.js_doc_expr().bit_expr()));
+ if (ctx.js_doc_expr().FORMAT() != null) {
+ p1.addOption(new ConstExpression(ctx.js_doc_expr().FORMAT(), ctx.js_doc_expr().JSON()));
+ }
+ params.add(p1);
+ if (ctx.literal() != null) {
+ params.add(new ExpressionParam(new ConstExpression(ctx.literal())));
+ }
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_TABLE().getText(), params);
+ fCall.addOption(getJsonOnOption(ctx.opt_json_table_on_error_on_empty()));
+ ctx.json_table_columns_def_opt().json_table_columns_def().json_table_column_def()
+ .forEach(c -> fCall.addOption(visitJsonTableColumnDef(c)));
+ return fCall;
+ }
+
+ @Override
+ public Expression visitJson_exists_response_type(Json_exists_response_typeContext ctx) {
+ if (ctx.BOOL_VALUE() != null) {
+ return new BoolValue(ctx.BOOL_VALUE());
+ }
+ return new ConstExpression(ctx.ERROR_P());
+ }
+
@Override
public Expression visitBool_pri(Bool_priContext boolPri) {
Bit_exprContext left = boolPri.bit_expr(0);
@@ -312,14 +824,16 @@ public Expression visitBool_pri(Bool_priContext boolPri) {
if (left != null && right == null) {
// is null or is not null 表达式
operator = Operator.EQ;
- if (boolPri.not() != null) {
+ if (boolPri.not() != null || boolPri.NOT() != null) {
operator = Operator.NE;
}
Expression rightExpr;
- if (boolPri.NULLX() == null) {
+ if (boolPri.is_nan_inf_value() != null) {
rightExpr = new NullExpression(boolPri.is_nan_inf_value());
- } else {
+ } else if (boolPri.NULLX() != null) {
rightExpr = new NullExpression(boolPri.NULLX());
+ } else {
+ rightExpr = visit(boolPri.is_json_constrain());
}
return new CompoundExpression(boolPri, visit(left), rightExpr, operator);
} else if (left != null) {
@@ -349,19 +863,17 @@ public Expression visitBool_pri(Bool_priContext boolPri) {
return new CompoundExpression(boolPri, visit(left), visit(right), operator);
}
// left == null && right == null
- PredicateContext predicate = boolPri.predicate();
- if (predicate == null) {
- throw new IllegalStateException("Missing predicate");
+ if (boolPri.predicate() != null) {
+ return visit(boolPri.predicate());
}
- return visit(predicate);
+ throw new IllegalStateException("Illegal branch");
}
@Override
public Expression visitPredicate(PredicateContext predicate) {
if (predicate.bool_pri() != null) {
- List params = new ArrayList<>();
- params.add(new ExpressionParam(visitBool_pri(predicate.bool_pri())));
- return new FunctionCall(predicate, predicate.LNNVL().getText(), params);
+ return new FunctionCall(predicate, predicate.LNNVL().getText(),
+ Collections.singletonList(new ExpressionParam(visitBool_pri(predicate.bool_pri()))));
}
Operator operator = null;
List bitExprs = predicate.bit_expr();
@@ -453,121 +965,152 @@ public Expression visitPredicate(PredicateContext predicate) {
return new FunctionCall(predicate, funcName, params);
}
- private List visitTableElementAccessList(Table_element_access_listContext ctx) {
+ private Expression visitTableElementAccessList(Expression fCall, Table_element_access_listContext ctx) {
Table_indexContext tableIndexContext = ctx.table_index();
if (tableIndexContext == null) {
throw new IllegalStateException("Missing table index");
}
Table_element_access_listContext elts = ctx.table_element_access_list();
- List list = elts == null ? new ArrayList<>() : visitTableElementAccessList(elts);
- list.add(new ConstExpression(tableIndexContext));
- return list;
+ Expression expr = fCall;
+ if (elts != null) {
+ expr = visitTableElementAccessList(fCall, elts);
+ }
+ return expr.reference(new OracleExpressionFactory(tableIndexContext.bit_expr()).generate(),
+ ReferenceOperator.PAREN);
}
private Expression visitColumnRef(Obj_access_refContext ctx) {
- String relationName = ctx.column_ref().getText();
Expression subRef = null;
+ ReferenceOperator operator = ReferenceOperator.DOT;
if (ctx.obj_access_ref() != null) {
subRef = visit(ctx.obj_access_ref());
} else if (ctx.Star() != null) {
- subRef = new RelationReference(ctx.Star(), ctx.Star().getText(), null);
+ subRef = new RelationReference(ctx.Star(), ctx.Star().getText());
} else if (ctx.FIRST() != null) {
subRef = new FunctionCall(ctx, ctx.FIRST().getText(), new ArrayList<>());
} else if (ctx.LAST() != null) {
subRef = new FunctionCall(ctx, ctx.LAST().getText(), new ArrayList<>());
} else if (ctx.COUNT() != null) {
subRef = new FunctionCall(ctx, ctx.COUNT().getText(), new ArrayList<>());
+ } else if (ctx.dot_notation_path() != null) {
+ subRef = visit(ctx.dot_notation_path());
+ operator = ReferenceOperator.BRACKET;
}
- return new RelationReference(ctx, relationName, subRef);
+ Expression colRef = new RelationReference(ctx.column_ref(), ctx.column_ref().getText());
+ if (subRef != null) {
+ colRef.reference(subRef, operator);
+ }
+ return colRef;
}
- private List visitFunctionAccessReference(Func_access_refContext accessRefContext) {
- List functionReferences = new ArrayList<>();
- Obj_access_refContext objReference = accessRefContext.obj_access_ref();
- Table_element_access_listContext eltAccessList = accessRefContext.table_element_access_list();
- if (objReference != null) {
- functionReferences.add(visit(objReference));
- } else if (eltAccessList != null) {
- functionReferences = visitTableElementAccessList(eltAccessList);
+ @Override
+ public Expression visitPath_param(OBParser.Path_paramContext ctx) {
+ Expression left = new ConstExpression(ctx.INTNUM());
+ if (ctx.path_param() == null) {
+ return left;
+ }
+ return new CompoundExpression(ctx, left, visitPath_param(ctx.path_param()), Operator.TO);
+ }
+
+ @Override
+ public Expression visitDot_notation_path(Dot_notation_pathContext ctx) {
+ CollectionExpression exprs = new CollectionExpression(ctx.path_param_array());
+ if (ctx.path_param_array().Star() != null) {
+ exprs.addExpression(new ConstExpression(ctx.path_param_array().Star()));
+ }
+ if (ctx.path_param_array().path_param_list() != null) {
+ ctx.path_param_array().path_param_list().path_param().forEach(c -> exprs.addExpression(visit(c)));
+ }
+ Dot_notation_path_obj_access_refContext dCtx = ctx.dot_notation_path_obj_access_ref();
+ if (dCtx.obj_access_ref() != null) {
+ exprs.reference(visit(dCtx.obj_access_ref()), ReferenceOperator.DOT);
+ } else if (dCtx.dot_notation_path() != null) {
+ exprs.reference(visit(dCtx.dot_notation_path()), ReferenceOperator.BRACKET);
+ }
+ return exprs;
+ }
+
+ private void visitFunctionAccessReference(Expression fCall, Func_access_refContext ctx) {
+ if (ctx.table_element_access_list() != null) {
+ visitTableElementAccessList(fCall, ctx.table_element_access_list());
+ }
+ if (ctx.obj_access_ref() != null) {
+ Expression last;
+ for (last = fCall; last.getReference() != null; last = last.getReference()) {
+ }
+ last.reference(visit(ctx.obj_access_ref()), ReferenceOperator.DOT);
}
- return functionReferences;
}
@Override
public Expression visitAccess_func_expr_count(Access_func_expr_countContext ctx) {
- String functionName = ctx.COUNT().getText();
- String paramsFlag = null;
- List params = new ArrayList<>();
Bit_exprContext bitExpr = ctx.bit_expr();
TerminalNode start = ctx.Star();
+ List params = new ArrayList<>();
if (bitExpr != null) {
params.add(new ExpressionParam(visit(bitExpr)));
} else if (start != null) {
params.add(new ExpressionParam(new ConstExpression(start)));
}
+ FunctionCall fCall = new FunctionCall(ctx, ctx.COUNT().getText(), params);
+ fCall.setKeep(getKeepClause(ctx));
if (ctx.ALL() != null) {
- paramsFlag = ctx.ALL().getText();
+ fCall.addOption(new ConstExpression(ctx.ALL()));
} else if (ctx.DISTINCT() != null) {
- paramsFlag = ctx.DISTINCT().getText();
+ fCall.addOption(new ConstExpression(ctx.DISTINCT()));
} else if (ctx.UNIQUE() != null) {
- paramsFlag = ctx.UNIQUE().getText();
+ fCall.addOption(new ConstExpression(ctx.UNIQUE()));
}
- FunctionCall fCall = new FunctionCall(ctx, functionName, params);
- fCall.setParamsFlag(paramsFlag);
return fCall;
}
private Expression visitAccessFunctionExpr(Obj_access_refContext ctx) {
- FunctionCall tmp = getFunctionCall(ctx.access_func_expr());
- FunctionCall fCall;
+ FunctionCall fCall = getFunctionCall(ctx.access_func_expr());
if (ctx.func_access_ref() == null) {
- fCall = new FunctionCall(ctx, tmp.getFunctionName(), tmp.getParamList());
- } else {
- // 如果存在函数对象访问,先把函数对象访问表达式集合解析出来
- List funcAccess = visitFunctionAccessReference(ctx.func_access_ref());
- fCall = new FunctionAccess(ctx, tmp.getFunctionName(), tmp.getParamList(), funcAccess);
+ return fCall;
}
- fCall.setParamsFlag(tmp.getParamsFlag());
+ visitFunctionAccessReference(fCall, ctx.func_access_ref());
return fCall;
}
- public FunctionCall getFunctionCall(Access_func_exprContext context) {
+ public FunctionCall getFunctionCall(Access_func_exprContext ctx) {
String functionName = null;
- List params = new ArrayList<>();
- String paramsFlag = null;
- Function_nameContext functionNameCxt = context.function_name();
- // 解析函数调用时的参数传入以及函数名
- Access_func_expr_countContext accessCountFunc = context.access_func_expr_count();
- if (accessCountFunc != null) {
- // 目前访问的是 count 函数
- FunctionCall f = (FunctionCall) visit(accessCountFunc);
- functionName = f.getFunctionName();
- params.addAll(f.getParamList());
- paramsFlag = f.getParamsFlag();
- } else if (functionNameCxt != null) {
- // 存在 function name 节点,函数名使用节点的 text 信息填充
- functionName = functionNameCxt.getText();
- if (context.ALL() != null) {
- paramsFlag = context.ALL().getText();
- } else if (context.DISTINCT() != null) {
- paramsFlag = context.DISTINCT().getText();
- } else if (context.UNIQUE() != null) {
- paramsFlag = context.UNIQUE().getText();
- }
- } else if (context.aggregate_function_keyword() != null) {
- functionName = context.aggregate_function_keyword().getText();
- } else if (context.exists_function_name() != null) {
- functionName = context.exists_function_name().getText();
+ if (ctx.access_func_expr_count() != null) {
+ return (FunctionCall) visit(ctx.access_func_expr_count());
+ } else if (ctx.function_name() != null) {
+ functionName = ctx.function_name().getText();
+ } else if (ctx.aggregate_function_keyword() != null) {
+ functionName = ctx.aggregate_function_keyword().getText();
+ } else if (ctx.exists_function_name() != null) {
+ functionName = ctx.exists_function_name().getText();
+ } else if (ctx.NEW() != null && ctx.NAME_OB() != null) {
+ functionName = ctx.NEW().getText() + " " + ctx.NAME_OB().getText();
}
if (functionName == null) {
throw new IllegalStateException("Missing function name");
}
- if (context.func_param_list() != null) {
- params.addAll(context.func_param_list().func_param().stream()
+ List params = new ArrayList<>();
+ if (ctx.func_param_list() != null) {
+ params.addAll(ctx.func_param_list().func_param().stream()
.map(this::visitFunctionParam).collect(Collectors.toList()));
}
- FunctionCall fCall = new FunctionCall(context, functionName, params);
- fCall.setParamsFlag(paramsFlag);
+ FunctionCall fCall = new FunctionCall(ctx, functionName, params);
+ if (ctx.ALL() != null) {
+ fCall.addOption(new ConstExpression(ctx.ALL()));
+ } else if (ctx.DISTINCT() != null) {
+ fCall.addOption(new ConstExpression(ctx.DISTINCT()));
+ } else if (ctx.UNIQUE() != null) {
+ fCall.addOption(new ConstExpression(ctx.UNIQUE()));
+ }
+ setJsonExistOpt(fCall, ctx.opt_json_exist());
+ if (ctx.json_equal_option() != null) {
+ JsonOnOption jsonOnOption = new JsonOnOption(ctx.json_equal_option());
+ if (ctx.json_equal_option().BOOL_VALUE() != null) {
+ jsonOnOption.setOnError(new BoolValue(ctx.json_equal_option().BOOL_VALUE()));
+ } else {
+ jsonOnOption.setOnError(new ConstExpression(ctx.json_equal_option().ERROR_P(0)));
+ }
+ }
return fCall;
}
@@ -592,11 +1135,33 @@ private FunctionParam visitFunctionParam(Func_paramContext paramContext) {
return new ExpressionParam(visit(paramContext.bool_pri_in_pl_func()));
}
+ @Override
+ public Expression visitObj_access_ref_normal(Obj_access_ref_normalContext ctx) {
+ Expression expr;
+ if (ctx.pl_var_name() != null) {
+ expr = new RelationReference(ctx.pl_var_name(), ctx.pl_var_name().getText());
+ } else if (ctx.access_func_expr_count() != null) {
+ expr = visit(ctx.access_func_expr_count());
+ } else {
+ List params = new ArrayList<>();
+ if (ctx.func_param_list() != null) {
+ params.addAll(ctx.func_param_list().func_param().stream()
+ .map(this::visitFunctionParam).collect(Collectors.toList()));
+ }
+ expr = new FunctionCall(ctx, ctx.getChild(0).getText(), params);
+ }
+ if (ctx.obj_access_ref_normal() != null) {
+ expr.reference(visit(ctx.obj_access_ref_normal()), ReferenceOperator.DOT);
+ } else if (ctx.table_element_access_list() != null) {
+ visitTableElementAccessList(expr, ctx.table_element_access_list());
+ }
+ return expr;
+ }
+
@Override
public Expression visitSingle_row_function(Single_row_functionContext ctx) {
String funcName = null;
- Statement paramsOpt = null;
- List paramFlags = new ArrayList<>();
+ List functionOpts = new ArrayList<>();
List params = new ArrayList<>();
if (ctx.numeric_function() != null) {
funcName = ctx.numeric_function().MOD().getText();
@@ -613,47 +1178,66 @@ public Expression visitSingle_row_function(Single_row_functionContext ctx) {
}
if (characterFunc.parameterized_trim() != null) {
Parameterized_trimContext trim = characterFunc.parameterized_trim();
- params.addAll(
- trim.bit_expr().stream().map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
+ FunctionParam param = new ExpressionParam(visit(trim.bit_expr(0)));
+ if (trim.bit_expr(1) != null) {
+ param.addOption(visit(trim.bit_expr(1)));
+ }
+ params.add(param);
for (int i = 0; i < trim.getChildCount(); i++) {
ParseTree p = trim.getChild(i);
if (p instanceof TerminalNode) {
- paramFlags.add(p.getText());
+ functionOpts.add(new ConstExpression((TerminalNode) p));
+ } else {
+ break;
}
}
} else {
params.addAll(characterFunc.bit_expr().stream().map(e -> new ExpressionParam(visit(e)))
.collect(Collectors.toList()));
- }
- if (characterFunc.translate_charset() != null) {
- paramsOpt = new ConstExpression(characterFunc.translate_charset());
+ if (params.size() > 0) {
+ params.get(params.size() - 1).addOption(new ConstExpression(characterFunc.translate_charset()));
+ }
}
} else if (ctx.extract_function() != null) {
funcName = ctx.extract_function().EXTRACT().getText();
- params.add(new ExpressionParam(visit(ctx.extract_function().bit_expr())));
- paramsOpt = new ConstExpression(ctx.extract_function().date_unit_for_extract());
+ FunctionParam p = new ExpressionParam(new ConstExpression(ctx.extract_function().date_unit_for_extract()));
+ p.addOption(visit(ctx.extract_function().bit_expr()));
+ params.add(p);
} else if (ctx.conversion_function() != null) {
Conversion_functionContext fCtx = ctx.conversion_function();
- funcName = fCtx.CAST().getText();
- params.add(new ExpressionParam(visit(fCtx.bit_expr())));
- paramsOpt = new OracleDataTypeFactory(fCtx.cast_data_type()).generate();
+ if (fCtx.CAST() != null) {
+ funcName = fCtx.CAST().getText();
+ FunctionParam functionParam = new ExpressionParam(visit(fCtx.bit_expr()));
+ functionParam.addOption(new OracleDataTypeFactory(fCtx.cast_data_type()).generate());
+ params.add(functionParam);
+ } else {
+ funcName = fCtx.TREAT().getText();
+ FunctionParam functionParam = new ExpressionParam(visit(fCtx.bit_expr()));
+ functionParam.addOption(new OracleDataTypeFactory(fCtx.treat_data_type()).generate());
+ params.add(functionParam);
+ }
} else if (ctx.hierarchical_function() != null) {
funcName = ctx.hierarchical_function().SYS_CONNECT_BY_PATH().getText();
params.addAll(ctx.hierarchical_function().bit_expr().stream().map(e -> new ExpressionParam(visit(e)))
.collect(Collectors.toList()));
} else if (ctx.environment_id_function() != null) {
funcName = ctx.environment_id_function().getText();
+ } else if (ctx.xml_function() != null) {
+ Expression fCall = visit(ctx.xml_function());
+ if (ctx.obj_access_ref_normal() != null) {
+ fCall.reference(visit(ctx.obj_access_ref_normal()), ReferenceOperator.DOT);
+ } else if (ctx.table_element_access_list() != null) {
+ visitTableElementAccessList(fCall, ctx.table_element_access_list());
+ }
+ return fCall;
+ } else if (ctx.json_function() != null) {
+ return visit(ctx.json_function());
}
if (funcName == null) {
throw new IllegalStateException("Missing function name");
}
FunctionCall fCall = new FunctionCall(ctx, funcName, params);
- if (!paramFlags.isEmpty()) {
- fCall.setParamsFlag(String.join(" ", paramFlags));
- }
- if (paramsOpt != null) {
- fCall.addParamsOption(paramsOpt);
- }
+ functionOpts.forEach(fCall::addOption);
return fCall;
}
@@ -666,52 +1250,72 @@ public Expression visitAggregate_function(Aggregate_functionContext ctx) {
if (ctx.subFuncName != null) {
funcName += "." + ctx.subFuncName.getText();
}
- String paramsFlag = null;
- if (ctx.ALL() != null) {
- paramsFlag = ctx.ALL().getText();
- } else if (ctx.DISTINCT() != null) {
- paramsFlag = ctx.DISTINCT().getText();
- } else if (ctx.UNIQUE() != null) {
- paramsFlag = ctx.UNIQUE().getText();
- }
List params = new ArrayList<>();
- if (ctx.expr_list() != null) {
- params.addAll(ctx.expr_list().bit_expr().stream().map(e -> new ExpressionParam(visit(e)))
- .collect(Collectors.toList()));
- }
- if (CollectionUtils.isNotEmpty(ctx.bit_expr())) {
- params.addAll(ctx.bit_expr().stream().map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
- }
- List paramsOpts = new ArrayList<>();
- if (ctx.first_or_last() != null) {
- paramsOpts.add(new ConstExpression(ctx.first_or_last()));
- }
- if (ctx.order_by() != null) {
- StatementFactory factory = new OracleOrderByFactory(ctx.order_by());
- paramsOpts.add(factory.generate());
+ if (ctx.JSON_ARRAYAGG() != null || ctx.JSON_OBJECTAGG() != null) {
+ if (ctx.VALUE() != null) {
+ Expression key = visit(ctx.bit_expr(0));
+ Expression value = visit(ctx.bit_expr(1));
+ if (ctx.KEY() != null) {
+ params.add(new ExpressionParam(new JsonKeyValue(
+ ctx.KEY(), ctx.bit_expr(1), key, value)));
+ } else {
+ params.add(new ExpressionParam(new JsonKeyValue(
+ ctx.bit_expr(0), ctx.bit_expr(1), key, value)));
+ }
+ } else {
+ params.addAll(
+ ctx.bit_expr().stream().map(c -> new ExpressionParam(visit(c))).collect(Collectors.toList()));
+ }
+ } else {
+ if (ctx.expr_list() != null) {
+ params.addAll(ctx.expr_list().bit_expr().stream()
+ .map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
+ }
+ if (CollectionUtils.isNotEmpty(ctx.bit_expr())) {
+ params.addAll(
+ ctx.bit_expr().stream().map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
+ }
+ if (ctx.simple_expr() != null) {
+ params.add(new ExpressionParam(visit(ctx.simple_expr())));
+ }
}
FunctionCall fCall = new FunctionCall(ctx, funcName, params);
- fCall.setParamsFlag(paramsFlag);
- paramsOpts.forEach(fCall::addParamsOption);
+ setFunctionOptions(fCall, ctx);
+ fCall.setKeep(getKeepClause(ctx));
+ fCall.setWithinGroup(getWithinGroup(ctx));
return fCall;
}
+ @Override
+ public Expression visitSigned_literal(Signed_literalContext ctx) {
+ return getExpression(ctx);
+ }
+
+ public static Expression getExpression(Signed_literalContext ctx) {
+ ConstExpression constExpr;
+ if (ctx.literal() != null) {
+ constExpr = new ConstExpression(ctx.literal());
+ } else {
+ constExpr = new ConstExpression(ctx.number_literal());
+ }
+ Operator operator = null;
+ if (ctx.Minus() != null) {
+ operator = Operator.SUB;
+ } else if (ctx.Plus() != null) {
+ operator = Operator.ADD;
+ }
+ return operator == null ? constExpr : new CompoundExpression(ctx, constExpr, null, operator);
+ }
+
@Override
public Expression visitSpecial_func_expr(Special_func_exprContext ctx) {
String funcName;
List params = new ArrayList<>();
if (ctx.cur_timestamp_func() != null) {
Cur_timestamp_funcContext cur = ctx.cur_timestamp_func();
- if (cur.SYSDATE() != null) {
- funcName = cur.SYSDATE().getText();
- } else {
+ funcName = cur.getChild(0).getText();
+ if (cur.INTNUM() != null) {
params.add(new ExpressionParam(new ConstExpression(cur.INTNUM())));
- if (cur.CURRENT_TIMESTAMP() != null) {
- funcName = cur.CURRENT_TIMESTAMP().getText();
- } else {
- funcName =
- cur.SYSTIMESTAMP() == null ? cur.LOCALTIMESTAMP().getText() : cur.SYSTIMESTAMP().getText();
- }
}
} else if (ctx.INSERT() != null) {
funcName = ctx.INSERT().getText();
@@ -728,18 +1332,61 @@ public Expression visitSpecial_func_expr(Special_func_exprContext ctx) {
StatementFactory factory = new OracleColumnRefFactory(ctx.column_definition_ref());
params.add(new ExpressionParam(factory.generate()));
} else {
+ funcName = ctx.getChild(0).getText();
params.add(new ExpressionParam(visit(ctx.bit_expr(0))));
- if (ctx.MONTH() != null) {
- funcName = ctx.MONTH().getText();
- } else {
- String first = ctx.DATE() == null ? ctx.ISNULL().getText() : ctx.DATE().getText();
- String second = ctx.TIME() == null ? ctx.YEAR().getText() : ctx.TIME().getText();
- funcName = first + " " + second;
- }
}
return new FunctionCall(ctx, funcName, params);
}
+ @Override
+ public Expression visitJson_value_on_response(Json_value_on_responseContext ctx) {
+ if (ctx.NULLX() != null) {
+ return new NullExpression(ctx);
+ }
+ return new ConstExpression(ctx);
+ }
+
+ @Override
+ public Expression visitOpt_response_query(Opt_response_queryContext ctx) {
+ if (ctx.NULLX() != null) {
+ return new NullExpression(ctx);
+ }
+ return new ConstExpression(ctx);
+ }
+
+ @Override
+ public Expression visitJson_table_column_def_path(Json_table_column_def_pathContext ctx) {
+ if (ctx == null) {
+ return null;
+ }
+ if (ctx.literal() != null) {
+ return new ConstExpression(ctx.literal());
+ }
+ ColumnReference cr = new ColumnReference(ctx.column_name(), null, null, ctx.column_name().getText());
+ if (ctx.dot_notation_path() != null) {
+ cr.reference(visit(ctx.dot_notation_path()), ReferenceOperator.BRACKET);
+ }
+ return cr;
+ }
+
+ @Override
+ public Expression visitOpt_response_query_on_empty_error(Opt_response_query_on_empty_errorContext ctx) {
+ if (ctx.opt_response_query() != null) {
+ return visit(ctx.opt_response_query());
+ }
+ return new ConstExpression(ctx);
+ }
+
+ @Override
+ public Expression visitJson_table_on_response(Json_table_on_responseContext ctx) {
+ if (ctx.ERROR_P() != null) {
+ return new ConstExpression(ctx.ERROR_P());
+ } else if (ctx.NULLX() != null) {
+ return new NullExpression(ctx.NULLX());
+ }
+ return visit(ctx.signed_literal());
+ }
+
@Override
public Expression visitWindow_function(Window_functionContext ctx) {
StringBuilder builder = new StringBuilder();
@@ -756,7 +1403,7 @@ public Expression visitWindow_function(Window_functionContext ctx) {
}
String funcName = builder.toString();
List