diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index ca7dbc75f0..94340c327d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,97 +1,97 @@
# ODC code owners, refer to https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# These owners will be the default owners for everything in the repo.
-* @yhilmare @yizhouxw
+* @LioRoger @guowl3 @MarkPotato777
# libs
-/libs/db-browser/ @yhilmare @PeachThinking
-/libs/ob-sql-parser/ @yhilmare @PeachThinking
+/libs/db-browser/ @PeachThinking @MarkPotato777
+/libs/ob-sql-parser/ @PeachThinking @MarkPotato777
# 3rd-party
-/server/3rd-party/ @MarkPotato777 @yhilmare
+/server/3rd-party/ @MarkPotato777 @LioRoger
# common
-/server/odc-common/ @yhilmare @yizhouxw
+/server/odc-common/ @LioRoger @guowl3
# migrate
-/server/odc-migrate/ @MarkPotato777 @yhilmare
+/server/odc-migrate/ @MarkPotato777 @LioRoger
# core
-/server/odc-core/ @yhilmare @yizhouxw
+/server/odc-core/ @LioRoger @guowl3
/server/odc-core/**/alarm/ @LuckyPickleZZ
-/server/odc-core/**/authority/ @yhilmare
+/server/odc-core/**/authority/ @MarkPotato777
/server/odc-core/**/datamasking/ @LuckyPickleZZ
-/server/odc-core/**/datasource/ @yhilmare
-/server/odc-core/**/flow/ @yhilmare
-/server/odc-core/**/alarm/ @LuckyPickleZZ @yizhouxw
-/server/odc-core/**/authority/ @yhilmare @yizhouxw
-/server/odc-core/**/datamasking/ @LuckyPickleZZ @yhilmare
-/server/odc-core/**/datasource/ @yhilmare @yizhouxw
-/server/odc-core/**/flow/ @yhilmare @yizhouxw
-/server/odc-core/**/migrate/ @yhilmare @yizhouxw
-/server/odc-core/**/session/ @yhilmare @yizhouxw
-/server/odc-core/**/shared/ @yhilmare @yizhouxw
-/server/odc-core/**/sql/ @yhilmare @LuckyPickleZZ
-/server/odc-core/**/task/ @yhilmare @yizhouxw @guowl3
+/server/odc-core/**/datasource/ @MarkPotato777
+/server/odc-core/**/flow/ @zijiacj @LioRoger @MarkPotato777
+/server/odc-core/**/alarm/ @LuckyPickleZZ @LioRoger
+/server/odc-core/**/authority/ @MarkPotato777 @LioRoger
+/server/odc-core/**/datamasking/ @LuckyPickleZZ @MarkPotato777
+/server/odc-core/**/datasource/ @MarkPotato777 @LioRoger
+/server/odc-core/**/flow/ @zijiacj @LioRoger @MarkPotato777
+/server/odc-core/**/migrate/ @MarkPotato777 @LioRoger
+/server/odc-core/**/session/ @LuckyPickleZZ @LioRoger
+/server/odc-core/**/shared/ @LioRoger @guowl3
+/server/odc-core/**/sql/ @LuckyPickleZZ @LioRoger
+/server/odc-core/**/task/ @LioRoger @guowl3
# service common
-/server/odc-service/ @yhilmare @yizhouxw
-/server/odc-service/**/config/ @yhilmare @yizhouxw
-/server/odc-service/**/metadb/ @yhilmare @yizhouxw
-/server/odc-service/**/service/common/ @yhilmare @MarkPotato777
+/server/odc-service/ @LioRoger @guowl3
+/server/odc-service/**/config/ @LioRoger @guowl3
+/server/odc-service/**/metadb/ @LioRoger @guowl3
+/server/odc-service/**/service/common/ @LioRoger @MarkPotato777
# service business
-/server/odc-service/**/service/audit/ @MarkPotato777 @yizhouxw
+/server/odc-service/**/service/audit/ @MarkPotato777 @LioRoger
/server/odc-service/**/service/automation/ @LuckyPickleZZ @ungreat
-/server/odc-service/**/service/captcha/ @MarkPotato777 @yizhouxw
-/server/odc-service/**/service/collaboration/ @MarkPotato777 @yizhouxw
-/server/odc-service/**/service/config/ @MarkPotato777 @yizhouxw
-/server/odc-service/**/service/datasecurity/ @LuckyPickleZZ @yhilmare
-/server/odc-service/**/service/datatransfer/ @LuckyPickleZZ @yhilmare
-/server/odc-service/**/service/db/ @PeachThinking @yhilmare
-/server/odc-service/**/service/diagnose/ @LuckyPickleZZ @yizhouxw
-/server/odc-service/**/service/dispatch/ @yhilmare @yizhouxw
+/server/odc-service/**/service/captcha/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/collaboration/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/config/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/datasecurity/ @LuckyPickleZZ @MarkPotato777
+/server/odc-service/**/service/datatransfer/ @LuckyPickleZZ @LioRoger
+/server/odc-service/**/service/db/ @PeachThinking @LioRoger
+/server/odc-service/**/service/diagnose/ @LuckyPickleZZ @LioRoger
+/server/odc-service/**/service/dispatch/ @LioRoger @guowl3
/server/odc-service/**/service/dlm/ @guowl3 @kiko-art
/server/odc-service/**/service/dml/ @LuckyPickleZZ @PeachThinking
-/server/odc-service/**/service/encryption/ @PeachThinking @yizhouxw
-/server/odc-service/**/service/feature/ @MarkPotato777 @yizhouxw
-/server/odc-service/**/service/flow/ @yhilmare @yizhouxw
+/server/odc-service/**/service/encryption/ @PeachThinking @LioRoger
+/server/odc-service/**/service/feature/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/flow/ @zijiacj @LioRoger @MarkPotato777
/server/odc-service/**/service/i18n/ @LuckyPickleZZ
-/server/odc-service/**/service/iam/ @MarkPotato777 @PeachThinking @yhilmare
-/server/odc-service/**/service/info/ @yhilmare @yizhouxw
-/server/odc-service/**/service/integration/ @yiminpeng @ungreat @yizhouxw
+/server/odc-service/**/service/iam/ @MarkPotato777 @PeachThinking @LioRoger
+/server/odc-service/**/service/info/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/integration/ @ungreat @LioRoger @yiminpeng
/server/odc-service/**/service/lab/ @LuckyPickleZZ @ungreat
-/server/odc-service/**/service/monitor/ @ungreat @yizhouxw
+/server/odc-service/**/service/monitor/ @ungreat @ysjemmm @LioRoger
/server/odc-service/**/service/notification/ @LuckyPickleZZ @MarkPotato777
-/server/odc-service/**/service/objectstorage/ @MarkPotato777 @yizhouxw
+/server/odc-service/**/service/objectstorage/ @CHLK @MarkPotato777
/server/odc-service/**/service/onlineschemachange/ @LioRoger @LuckyPickleZZ
-/server/odc-service/**/service/partitionplan/ @guowl3 @yhilmare
-/server/odc-service/**/service/permission/ @MarkPotato777 @yhilmare
-/server/odc-service/**/service/pldebug/ @yhilmare @yizhouxw
-/server/odc-service/**/service/plugin/ @yhilmare @LuckyPickleZZ
-/server/odc-service/**/service/quartz/ @guowl3 @yhilmare
-/server/odc-service/**/service/requlation/ @MarkPotato777 @yhilmare
-/server/odc-service/**/service/resourcegroup/ @MarkPotato777 @yhilmare
+/server/odc-service/**/service/partitionplan/ @guowl3 @LioRoger
+/server/odc-service/**/service/permission/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/pldebug/ @zijiacj @MarkPotato777
+/server/odc-service/**/service/plugin/ @LioRoger @LuckyPickleZZ
+/server/odc-service/**/service/quartz/ @guowl3 @LioRoger
+/server/odc-service/**/service/requlation/ @MarkPotato777 @zijiacj
+/server/odc-service/**/service/resourcegroup/ @MarkPotato777 @zijiacj
/server/odc-service/**/service/resultset/ @LuckyPickleZZ @PeachThinking
/server/odc-service/**/service/rollbackplan/ @PeachThinking @MarkPotato777
-/server/odc-service/**/service/schedule/ @guowl3 @yhilmare
-/server/odc-service/**/service/script/ @LuckyPickleZZ @yizhouxw
-/server/odc-service/**/service/session/ @yhilmare @LuckyPickleZZ
+/server/odc-service/**/service/schedule/ @guowl3 @LioRoger
+/server/odc-service/**/service/script/ @LuckyPickleZZ @LioRoger
+/server/odc-service/**/service/session/ @LuckyPickleZZ @LioRoger
/server/odc-service/**/service/shadowtable/ @MarkPotato777 @PeachThinking
-/server/odc-service/**/service/snippet/ @LuckyPickleZZ @yizhouxw
-/server/odc-service/**/service/sqlcheck/ @yhilmare @PeachThinking
-/server/odc-service/**/service/structurecompare/ @PeachThinking @yhilmare
-/server/odc-service/**/service/systemconfig/ @MarkPotato777 @yizhouxw
-/server/odc-service/**/service/task/ @yhilmare @guowl3 @yizhouxw
-/server/odc-service/**/service/websocket/ @LuckyPickleZZ @yizhouxw
+/server/odc-service/**/service/snippet/ @LuckyPickleZZ @LioRoger
+/server/odc-service/**/service/sqlcheck/ @zijiacj @PeachThinking @MarkPotato777
+/server/odc-service/**/service/structurecompare/ @PeachThinking @MarkPotato777
+/server/odc-service/**/service/systemconfig/ @MarkPotato777 @LioRoger
+/server/odc-service/**/service/task/ @guowl3 @LioRoger
+/server/odc-service/**/service/websocket/ @LuckyPickleZZ @LioRoger
# plugins
-/server/plugins/ @yhilmare @yizhouxw
-/server/plugins/connect-plugin-doris/ @yhilmare @yizhouxw
-/server/plugins/connect-plugin-mysql/ @yhilmare @yizhouxw
-/server/plugins/connect-plugin-ob-mysql/ @yhilmare @yizhouxw
-/server/plugins/connect-plugin-ob-oracle/ @yhilmare @yizhouxw
-/server/plugins/connect-plugin-oracle/ @yhilmare @yizhouxw
+/server/plugins/ @LioRoger @guowl3 @MarkPotato777
+/server/plugins/connect-plugin-doris/ @LioRoger @guowl3 @MarkPotato777
+/server/plugins/connect-plugin-mysql/ @LioRoger @guowl3 @MarkPotato777
+/server/plugins/connect-plugin-ob-mysql/ @LioRoger @guowl3 @MarkPotato777
+/server/plugins/connect-plugin-ob-oracle/ @LioRoger @guowl3 @MarkPotato777
+/server/plugins/connect-plugin-oracle/ @LioRoger @guowl3 @MarkPotato777
/server/plugins/schema-plugin-api/ @PeachThinking @MarkPotato777
/server/plugins/schema-plugin-doris/ @PeachThinking @MarkPotato777
@@ -101,37 +101,37 @@
/server/plugins/schema-plugin-odp-sharding-ob-mysql/ @PeachThinking @MarkPotato777
/server/plugins/schema-plugin-oracle/ @PeachThinking @MarkPotato777
-/server/plugins/task-plugin-api/ @LuckyPickleZZ @yhilmare
-/server/plugins/task-plugin-doris/ @LuckyPickleZZ @yhilmare
-/server/plugins/task-plugin-mysql/ @LuckyPickleZZ @yhilmare
-/server/plugins/task-plugin-ob-mysql/ @LuckyPickleZZ @yhilmare
-/server/plugins/task-plugin-ob-oracle/ @LuckyPickleZZ @yhilmare
-/server/plugins/task-plugin-oracle/ @LuckyPickleZZ @yhilmare
+/server/plugins/task-plugin-api/ @LuckyPickleZZ @LioRoger
+/server/plugins/task-plugin-doris/ @LuckyPickleZZ @LioRoger
+/server/plugins/task-plugin-mysql/ @LuckyPickleZZ @LioRoger
+/server/plugins/task-plugin-ob-mysql/ @LuckyPickleZZ @LioRoger
+/server/plugins/task-plugin-ob-oracle/ @LuckyPickleZZ @LioRoger
+/server/plugins/task-plugin-oracle/ @LuckyPickleZZ @LioRoger
# starters
-/server/starters/ @yhilmare @yizhouxw
-/server/starters/desktop-starter/ @yhilmare @yizhouxw
-/server/starters/web-starter/ @yhilmare @MarkPotato777
+/server/starters/ @LioRoger @guowl3 @MarkPotato777
+/server/starters/desktop-starter/ @LioRoger @guowl3 @MarkPotato777
+/server/starters/web-starter/ @LioRoger @guowl3 @MarkPotato777
# modules
-/server/modules/ @yhilmare @yizhouxw
+/server/modules/ @LioRoger @CHLK
# CI/CD
-/.github/ @MarkPotato777 @yhilmare @yizhouxw
-/builds/ @MarkPotato777 @yhilmare @yizhouxw
-/script/ @MarkPotato777 @yhilmare @yizhouxw
-/distribution/ @MarkPotato777 @yhilmare @yizhouxw
-/server/odc-test/ @MarkPotato777 @yhilmare @yizhouxw
-/server/integration-test/ @MarkPotato777 @yhilmare @yizhouxw
-/server/test-script/ @MarkPotato777 @yhilmare @yizhouxw
+/.github/ @MarkPotato777 @LioRoger
+/builds/ @MarkPotato777 @LioRoger
+/script/ @MarkPotato777 @LioRoger
+/distribution/ @MarkPotato777 @LioRoger
+/server/odc-test/ @MarkPotato777 @LioRoger
+/server/integration-test/ @MarkPotato777 @LioRoger
+/server/test-script/ @MarkPotato777 @LioRoger
# i18n
-/server/odc-core/src/main/resources/i18n/ @Jane201510 @JessieWuJiexi @yizhouxw
+/server/odc-core/src/main/resources/i18n/ @Jane201510 @JessieWuJiexi @LioRoger @MarkPotato777 @guowl3
# docs
-/docs/ @Jane201510 @yhilmare @yizhouxw
-CHANGELOG.md @Jane201510 @JessieWuJiexi @yhilmare @yizhouxw
-CHANGELOG-zh-CN.md @Jane201510 @JessieWuJiexi @yhilmare @yizhouxw
-README.md @Jane201510 @JessieWuJiexi @yizhouxw
-README-zh.md @Jane201510 @JessieWuJiexi @yizhouxw
+/docs/ @Jane201510 @MarkPotato777 @LioRoger @guowl3
+CHANGELOG.md @Jane201510 @JessieWuJiexi @MarkPotato777 @LioRoger @guowl3
+CHANGELOG-zh-CN.md @Jane201510 @JessieWuJiexi @MarkPotato777 @LioRoger @guowl3
+README.md @Jane201510 @JessieWuJiexi @MarkPotato777 @LioRoger @guowl3
+README-zh.md @Jane201510 @JessieWuJiexi @MarkPotato777 @LioRoger @guowl3
diff --git a/.gitmodules b/.gitmodules
index bb0072910f..f52bde7184 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,7 +1,7 @@
[submodule "client"]
path = client
url = https://github.com/oceanbase/odc-client.git
- branch = dev-4.3.2
+ branch = dev-4.3.3
[submodule "build-resource"]
path = build-resource
url = https://github.com/oceanbase/odc-build-resource.git
diff --git a/CHANGELOG-zh-CN.md b/CHANGELOG-zh-CN.md
index 3dbf7d1847..6f5e3708c7 100644
--- a/CHANGELOG-zh-CN.md
+++ b/CHANGELOG-zh-CN.md
@@ -1,4 +1,98 @@
# OceanBase Developer Center (ODC) CHANGELOG
+## 4.3.3 (2025-01-13)
+
+### 功能变化
+
+数据生命周期管理
+
+- 新增 Oracle 到对象存储的归档链路
+- 新增 MySQL 到对象存储的归档链路
+- 新增 OceanBase MySQL 到对象存储的归档链路
+- 新增 OceanBase Oracle 到对象存储的归档链路
+- 新增 PostgreSQL 到对象存储的归档链路
+- 支持回溯编辑历史,支持查看编辑内容前后对比
+- 支持定义动态目标表,解决按日、月等单独存放历史数据的诉求
+- 支持删除数据归档、清理任务,当任务已完成或已终止时支持对其进行删除操作
+- 优化回滚逻辑,仅回滚当次任务的归档数据
+
+无锁结构变更
+
+- 支持失败重试,为各环节可能导致失败的场景补充重试逻辑
+- 支持无锁结构变更状态展示,可以查看运行中任务进度
+
+变更风险管控
+
+- 增加全局项目角色,包括全局项目管理员、全局安全管理员以及全局 DBA
+- 增加项目归档检测机制,归档前会检测项目中是否存在未结束的工单及周期任务
+- 支持删除项目,对于已归档的项目支持对其进行删除操作
+- 支持用户申请视图权限,对用户访问视图做了更细粒度的权限控制
+- SQL 窗口拓展了可执行的 SQL 类型,新支持 `call`、`comment`、`set session` 等类型
+- SQL 检查规范支持原生 Oracle 数据源
+- 支持原生 Oracle 数据源的变更走变更审批流程
+- 新增 2 条 SQL 检查规则,支持规范 `create like` 及 `create as` 建表语句
+
+SQL 开发
+
+- 支持 OceanBase 外表白屏化管理
+- 支持 OceanBase 分区表的二级分区展示
+- 支持编辑 OceanBase MySQL 模式的函数和存储过程
+- 支持通过 OBProxy 进行 PL 调试
+
+其他
+
+- 支持 SAML 的单点登录方式
+- 支持查杀原生 Oracle 数据源的会话
+- 适配 OceanBase 4.2.5、4.3.3 版本
+- 适配 OBKV SQL 模式
+- 启用 Secure Cookie 机制,加固数据传输安全
+- 平台表单(含工单列表、数据库列表)列宽支持拉伸
+
+### 易用性改进
+- 支持固化项目搜索条件,避免频繁搜索高频操作项目
+- 支持用户登出再登入后仍旧可以定位在最近使用的项目下,简化用户操作路径
+- 风险识别规则中判断条件文案优化,统一采用运算符及英文表达,以避免歧义
+- 优化连接保活逻辑,每3分钟会主动发送一次数据库请求,保障连接的稳定性
+- 项目外工单模块增加项目列,方便用户快速识别工单所属项目
+- 除逻辑库变更, 分区计划, 影子表外,所有工单类型支持再次发起功能,再次发起后支持二次编辑工单参数
+- 工单可被管理及查看范围调整,管理员和 DBA 可管理项目内所有工单,其它角色仅可管理自己发起的工单。同时项目内所有成员均可查看项目内所有工单
+
+
+### 缺陷修复
+
+数据源
+
+- 堡垒机集成场景不会同步 `information_schema` 等内置数据库到项目内
+- 数据库同步异常挂起时无法恢复
+
+工单
+
+- 创建数据归档工单在个人空间仍产生审批流程
+- 数据归档/清理任务执行成功但执行记录状态异常
+- 非当前账号创建结构对比任务无法正常执行
+- Oracle 导出表结构存在虚拟列时导出会失败
+- OceanBase MySQL 源端库或目标库里若有一张表的 DDL 里指定全文索引的分词器,结构比对任务失败
+- 定时任务如果有太多的子任务,查看操作记录失败问题
+- 导出任务保留当前配置不生效
+
+变更管控
+
+- 没有导出权限也能导出视图
+- 分区计划无法禁用导致无法归档项目
+
+SQL 开发
+
+- SQL Check 特定场景下产生 NPE 异常
+- DROP PL 需要数据库变更的权限
+- 函数返回值类型为 Year 时无法正常显示
+- 当 PL 名称包含 @ 时 create 和 drop 语句将失败
+- 查看原生 Oracle 扩展了统计信息(`DBMS_STATS.CREATE_EXTENDED_STATS`)的表详情失败
+- 限制 SQL 影响的行数时,insert 语句不生效
+- 导出数组函数结果集时,空指针异常问题
+- 在 Chrome 118 版本的浏览器中,右键单击软件包子程序时没有运行按钮
+- 查看程序包包头中的子程序时报错
+
+其他
+- 用户再次进入 ODC 时没有打开上次使用的项目
## 4.3.2 (2024-09-27)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 21dcf26463..f369e1c8c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,102 @@
+# OceanBase Developer Center (ODC) CHANGELOG
+
+## 4.3.3 (2025-01-13)
+
+### Feature Changes
+
+**Data Lifecycle Management**
+
+* Added archiving paths from Oracle to Object Storage.
+* Added archiving paths from MySQL to Object Storage.
+* Added archiving paths from OceanBase MySQL to Object Storage.
+* Added archiving paths from OceanBase Oracle to Object Storage.
+* Added archiving paths from PostgreSQL to Object Storage.
+* Added support for editing history review with content comparison.
+* Introduced dynamic target table definition to support storing historical data by day, month, or other time units.
+* Added ability to delete archiving and cleanup tasks when completed or terminated.
+* Optimized rollback logic to only revert data archived in the current task.
+
+**Online Schema Change**
+
+* Added retry mechanism with enhanced retry logic for various failure scenarios.
+* Added status display for online schema changes, allowing progress tracking of running tasks.
+
+**Change Risk Management**
+
+* Introduced global project roles including Global Project Admin, Global Security Admin, and Global DBA.
+* Added project archiving validation to check for unfinished tickets and periodic tasks before archiving.
+* Added support for project deletion for archived projects.
+* Implemented fine-grained view permission control with user-initiated permission requests.
+* Expanded executable SQL types in SQL window to include `call`, `comment`, `set session`, and more.
+* Extended SQL check support for native Oracle data sources.
+* Added change approval workflow for native Oracle data sources.
+* Added 2 new SQL check rules for standardizing `create like` and `create as` table creation statements.
+
+**SQL Development**
+
+* Added GUI support for OceanBase external tables.
+* Added support for displaying secondary partitions in OceanBase partitioned tables.
+* Added support for editing stored procedures in OceanBase MySQL mode.
+* Added support for PL debugging via OBProxy.
+
+**Other Enhancements**
+
+* Added SAML single sign-on support.
+* Added session kill capability for native Oracle data sources.
+* Added compatibility for OceanBase V4.2.5 and V4.3.3.
+* Added support for OBKV SQL mode.
+* Enabled secure cookie mechanism for enhanced data transmission security.
+* Added column width adjustment support for forms (ticket lists, database lists).
+
+### Usability Improvements
+
+* Added persistent project search criteria to reduce frequent searches.
+* Maintained last used project context across user sessions.
+* Standardized risk identification rule conditions using operators and English expressions to avoid ambiguity.
+* Enhanced connection keep-alive logic with 3-minute database request intervals.
+* Added project column in non-project ticket module for quick project identification.
+* Extended "Create Again" functionality to all ticket types except logical database changes, partition plans, and shadow tables.
+* Refined ticket management scope: admins and DBAs can manage all project tickets, while other roles can only manage self-initiated tickets. Also, all members can view tickets in their projects.
+
+### Bug Fixes
+
+**Data Sources**
+
+* Fixed synchronization of system databases like `information_schema` to projects in bastion host integration scenarios.
+* Resolved database synchronization suspension issues.
+
+**Tickets**
+
+* Fixed approval workflow triggering in personal workspace for data archiving tickets.
+* Fixed status inconsistency in data archiving/cleanup task execution records.
+* Fixed structure comparison task execution issues for non-current account users.
+* Fixed Oracle table structure export failures with virtual columns.
+* Fixed structure comparison failures for OceanBase MySQL tables with full-text index tokenizers.
+* Fixed operation record viewing failures for periodic tasks with numerous subtasks.
+* Fixed non-working configuration retention in export tasks.
+
+**Change Management**
+
+* Fixed unauthorized view exports.
+* Fixed partition plan disable issues affecting project archiving.
+
+**SQL Development**
+
+* Fixed NPE exceptions in specific SQL check scenarios.
+* Fixed PL drop requiring database change permissions.
+* Fixed display issues for functions with year return type.
+* Fixed PL creation and drop failures with @ in names.
+* Fixed table detail viewing failures for Oracle tables with extended statistics (`DBMS_STATS.CREATE_EXTENDED_STATS`).
+* Fixed ineffective row limit for Insert statements.
+* Fixed null pointer exceptions when exporting array function result sets.
+* Fixed missing run button for package subprocedures in Chrome 118.
+* Fixed error when viewing subprocedures in package headers.
+
+**Other**
+
+* Fixed last used project not opening on subsequent ODC access.
+
+
## 4.3.2 (2024-09-27)
### Feature Changes
diff --git a/client b/client
new file mode 160000
index 0000000000..5483141527
--- /dev/null
+++ b/client
@@ -0,0 +1 @@
+Subproject commit 5483141527674c54261206470deddcdf96aaead7
diff --git a/distribution/odc-server-VER.txt b/distribution/odc-server-VER.txt
index cc2fbe89b6..e91d9be2a8 100644
--- a/distribution/odc-server-VER.txt
+++ b/distribution/odc-server-VER.txt
@@ -1 +1 @@
-4.3.2
+4.3.3
diff --git a/docs/en-US/DEVELOPER_GUIDE.md b/docs/en-US/DEVELOPER_GUIDE.md
index dfad2e1808..c4c67059d7 100644
--- a/docs/en-US/DEVELOPER_GUIDE.md
+++ b/docs/en-US/DEVELOPER_GUIDE.md
@@ -407,6 +407,11 @@ The setup for starting OdcServer is shown below.

+The setup for environment variables is shown below.
+
+
+
+
# 4. Frontend-backend integration
## 4.1 Front-end and back-end integration based on a static resource server
diff --git a/docs/en-US/images/idea-run-configuration-start-odc-server-2.png b/docs/en-US/images/idea-run-configuration-start-odc-server-2.png
index 45371ba394..2204690cff 100644
Binary files a/docs/en-US/images/idea-run-configuration-start-odc-server-2.png and b/docs/en-US/images/idea-run-configuration-start-odc-server-2.png differ
diff --git a/docs/en-US/images/idea-run-configuration-start-odc-server-3.png b/docs/en-US/images/idea-run-configuration-start-odc-server-3.png
new file mode 100644
index 0000000000..e6a88556c8
Binary files /dev/null and b/docs/en-US/images/idea-run-configuration-start-odc-server-3.png differ
diff --git a/docs/zh-CN/DEVELOPER_GUIDE.md b/docs/zh-CN/DEVELOPER_GUIDE.md
index c118e03a2f..752779a763 100644
--- a/docs/zh-CN/DEVELOPER_GUIDE.md
+++ b/docs/zh-CN/DEVELOPER_GUIDE.md
@@ -377,6 +377,11 @@ OdcServer 启动设置示意如下

+环境变量(environment variables)配置示意如下
+
+
+
+
# 4. 前后端集成和联调
## 4.1 基于静态资源服务器的前后端联调
diff --git a/libs/db-browser/pom.xml b/libs/db-browser/pom.xml
index a40d4157de..a571e450d3 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.2.0
+ 1.2.2
db-browser
https://github.com/oceanbase/odc/tree/main/libs/db-browser
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBMySQLProcess.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBMySQLProcess.java
index 82d0d92b5f..6bcf741cfc 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBMySQLProcess.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBMySQLProcess.java
@@ -15,6 +15,8 @@
*/
package com.oceanbase.tools.dbbrowser.model;
+import com.oceanbase.tools.dbbrowser.util.StringUtils;
+
import lombok.Data;
/**
@@ -55,6 +57,16 @@ public class DBMySQLProcess {
*/
private String host;
+ /**
+ * observer ip, refer to the column `Ip` in the result set of `SHOW FULL PROCESSLIST`
+ */
+ private String ip;
+
+ /**
+ * observer SQL port, refer to the column `Port` in the result set of `SHOW FULL PROCESSLIST`
+ */
+ private String port;
+
public DBSession toDBSession() {
DBSession session = new DBSession();
session.setId(id);
@@ -66,6 +78,7 @@ public DBSession toDBSession() {
session.setHost(host);
session.setProxyHost(host);
session.setExecuteTime(Integer.parseInt(time));
+ session.setSvrIp(StringUtils.join(ip, ":", port));
return session;
}
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBObjectType.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBObjectType.java
index 7b2de36182..caeaa8f612 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBObjectType.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBObjectType.java
@@ -24,6 +24,7 @@ public enum DBObjectType {
*/
SCHEMA("SCHEMA"),
TABLE("TABLE"),
+ EXTERNAL_TABLE("EXTERNAL TABLE"),
LOGICAL_TABLE("LOGICAL TABLE"),
COLUMN("COLUMN"),
INDEX("INDEX"),
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTable.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTable.java
index 605363d4b0..debb2f6ddb 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTable.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTable.java
@@ -58,6 +58,8 @@ public class DBTable implements DBObject, DBObjectWarningDescriptor {
private String warning;
+ private DBObjectType type;
+
@Data
public static class DBTableOptions {
private String charsetName;
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableColumn.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableColumn.java
index fe019fa42f..65865fdc1f 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableColumn.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTableColumn.java
@@ -122,7 +122,7 @@ public class DBTableColumn implements DBObject, DBObjectWarningDescriptor {
private String collationName;
/**
- * MySQL special
+ * The generation column's expression
*/
private String genExpression;
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTablePartitionDefinition.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTablePartitionDefinition.java
index 75851e560d..6879a7f437 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTablePartitionDefinition.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/model/DBTablePartitionDefinition.java
@@ -19,4 +19,5 @@
@Data
public class DBTablePartitionDefinition extends DBTableAbstractPartitionDefinition {
+ private DBTablePartitionDefinition parentPartitionDefinition;
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/ParserUtil.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/ParserUtil.java
index 5611084cbf..118b4c4caa 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/ParserUtil.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/ParserUtil.java
@@ -55,6 +55,7 @@ public static GeneralSqlType getGeneralSqlType(BasicResult result) {
case DROP:
case TRUNCATE:
case ALTER:
+ case COMMENT_ON:
return GeneralSqlType.DDL;
case UNKNOWN:
default:
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/constant/SqlType.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/constant/SqlType.java
index f7148310fe..56e743f5e8 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/constant/SqlType.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/constant/SqlType.java
@@ -19,25 +19,39 @@
* Created by mogao.zj
*/
public enum SqlType {
- SELECT,
- DELETE,
- INSERT,
- REPLACE,
- UPDATE,
- SET,
- USE_DB,
- EXPLAIN,
- SHOW,
- HELP,
- START_TRANS,
- COMMIT,
- ROLLBACK,
- SORT,
- DESC,
- DROP,
- ALTER,
- TRUNCATE,
- CREATE,
- OTHERS,
- UNKNOWN
+ SELECT(null),
+ DELETE(null),
+ INSERT(null),
+ REPLACE(null),
+ UPDATE(null),
+ SET(null),
+ SET_SESSION(SET),
+ USE_DB(null),
+ EXPLAIN(null),
+ SHOW(null),
+ HELP(null),
+ START_TRANS(null),
+ COMMIT(null),
+ ROLLBACK(null),
+ SORT(null),
+ DESC(null),
+ DROP(null),
+ ALTER(null),
+ ALTER_SESSION(ALTER),
+ TRUNCATE(null),
+ CREATE(null),
+ CALL(null),
+ COMMENT_ON(null),
+ OTHERS(null),
+ UNKNOWN(null);
+
+ private final SqlType parentType;
+
+ SqlType(SqlType parentType) {
+ this.parentType = parentType;
+ }
+
+ public SqlType getParentType() {
+ return parentType;
+ }
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModePLParserListener.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModePLParserListener.java
index 8c59c2ad68..5fd374b743 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModePLParserListener.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModePLParserListener.java
@@ -159,4 +159,11 @@ public void enterSp_decl(Sp_declContext ctx) {
varibale.setVarType(type);
this.varibaleList.add(varibale);
}
+
+ @Override
+ public void enterCall_sp_stmt(PLParser.Call_sp_stmtContext ctx) {
+ this.sqlType = SqlType.CALL;
+ this.dbObjectType = DBObjectType.PROCEDURE;
+ }
+
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModeSqlParserListener.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModeSqlParserListener.java
index 40f3745470..f5ab1727db 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModeSqlParserListener.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/MysqlModeSqlParserListener.java
@@ -228,6 +228,7 @@ public void enterScope_or_scope_alias(Scope_or_scope_aliasContext ctx) {
if (scopeToken.getType() == OBLexer.GLOBAL || scopeToken.getType() == OBLexer.GLOBAL_ALIAS) {
setDbObjectType(DBObjectType.GLOBAL_VARIABLE);
} else if (scopeToken.getType() == OBLexer.SESSION || scopeToken.getType() == OBLexer.SESSION_ALIAS) {
+ this.sqlType = SqlType.SET_SESSION;
setDbObjectType(DBObjectType.SESSION_VARIABLE);
}
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModePLParserListener.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModePLParserListener.java
index 7568f3da48..77474ec04d 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModePLParserListener.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModePLParserListener.java
@@ -555,6 +555,12 @@ public void enterAlter_package_stmt(Alter_package_stmtContext ctx) {
}
}
+ @Override
+ public void enterCall_spec(PLParser.Call_specContext ctx) {
+ this.sqlType = sqlType.CALL;
+ this.dbObjectType = DBObjectType.PROCEDURE;
+ }
+
private String getDdl(ParserRuleContext ctx) {
Token start = ctx.getStart();
Token stop = ctx.getStop();
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeParserListener.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeParserListener.java
index d0dc419617..e20bb82060 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeParserListener.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeParserListener.java
@@ -68,7 +68,6 @@
import com.oceanbase.tools.sqlparser.oracle.PlSqlParser.Procedure_bodyContext;
import com.oceanbase.tools.sqlparser.oracle.PlSqlParser.Procedure_nameContext;
import com.oceanbase.tools.sqlparser.oracle.PlSqlParser.Procedure_specContext;
-import com.oceanbase.tools.sqlparser.oracle.PlSqlParser.Rollback_statementContext;
import com.oceanbase.tools.sqlparser.oracle.PlSqlParser.Type_declarationContext;
import com.oceanbase.tools.sqlparser.oracle.PlSqlParser.Variable_declarationContext;
import com.oceanbase.tools.sqlparser.oracle.PlSqlParserBaseListener;
@@ -418,6 +417,28 @@ public void enterRollback_statement(PlSqlParser.Rollback_statementContext ctx) {
doRecord(SqlType.ROLLBACK, DBObjectType.OTHERS, null);
}
+ @Override
+ public void enterComment_on_column(PlSqlParser.Comment_on_columnContext ctx) {
+ doRecord(SqlType.COMMENT_ON, DBObjectType.COLUMN, null);
+ }
+
+ @Override
+ public void enterComment_on_table(PlSqlParser.Comment_on_tableContext ctx) {
+ doRecord(SqlType.COMMENT_ON, DBObjectType.TABLE, null);
+ }
+
+ @Override
+ public void enterComment_on_materialized(PlSqlParser.Comment_on_materializedContext ctx) {
+ doRecord(SqlType.COMMENT_ON, DBObjectType.OTHERS, null);
+ }
+
+ @Override
+ public void enterProcedure_call(PlSqlParser.Procedure_callContext ctx) {
+ if (ctx.CALL() != null) {
+ doRecord(SqlType.CALL, DBObjectType.PROCEDURE, null);
+ }
+ }
+
private void doRecord(SqlType sqlType, DBObjectType dbObjectType, String rawPlName) {
if (Objects.nonNull(sqlType) && Objects.isNull(this.sqlType)) {
this.sqlType = sqlType;
@@ -431,6 +452,18 @@ private void doRecord(SqlType sqlType, DBObjectType dbObjectType, String rawPlNa
}
}
+ @Override
+ public void enterAlter_session(PlSqlParser.Alter_sessionContext ctx) {
+ doRecord(SqlType.ALTER_SESSION, DBObjectType.OTHERS, null);
+ }
+
+ @Override
+ public void enterScope_or_scope_alias(PlSqlParser.Scope_or_scope_aliasContext ctx) {
+ if (ctx.SESSION() != null) {
+ doRecord(SqlType.SET_SESSION, DBObjectType.OTHERS, null);
+ }
+ }
+
private String getDdl(ParserRuleContext ctx) {
Token start = ctx.getStart();
Token stop = ctx.getStop();
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeSqlParserListener.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeSqlParserListener.java
index 0ef7c736ac..e6274c7ea4 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeSqlParserListener.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/parser/listener/OracleModeSqlParserListener.java
@@ -284,6 +284,7 @@ public void enterScope_or_scope_alias(Scope_or_scope_aliasContext ctx) {
if (scopeToken.getType() == OBLexer.GLOBAL || scopeToken.getType() == OBLexer.GLOBAL_ALIAS) {
setDbObjectType(DBObjectType.GLOBAL_VARIABLE);
} else if (scopeToken.getType() == OBLexer.SESSION || scopeToken.getType() == OBLexer.SESSION_ALIAS) {
+ sqlType = sqlType.SET_SESSION;
setDbObjectType(DBObjectType.SESSION_VARIABLE);
}
}
@@ -601,7 +602,7 @@ public void enterAlter_sequence_stmt(Alter_sequence_stmtContext ctx) {
@Override
public void enterAlter_session_stmt(Alter_session_stmtContext ctx) {
- setSqlType(SqlType.ALTER);
+ setSqlType(SqlType.ALTER_SESSION);
this.dbObjectType = DBObjectType.OTHERS;
}
@@ -700,4 +701,25 @@ public void enterRollback_stmt(Rollback_stmtContext ctx) {
this.dbObjectType = DBObjectType.OTHERS;
}
+ @Override
+ public void enterSet_comment_stmt(OBParser.Set_comment_stmtContext ctx) {
+ // comment on xxx
+ setSqlType(SqlType.COMMENT_ON);
+ if (ctx.TABLE() != null) {
+ this.dbObjectType = DBObjectType.TABLE;
+ return;
+ }
+ if (ctx.COLUMN() != null) {
+ this.dbObjectType = DBObjectType.COLUMN;
+ return;
+ }
+ this.dbObjectType = DBObjectType.OTHERS;
+ }
+
+ @Override
+ public void enterCall_stmt(OBParser.Call_stmtContext ctx) {
+ setSqlType(SqlType.CALL);
+ this.dbObjectType = DBObjectType.PROCEDURE;
+ }
+
}
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 21d68f020f..eb9bac6ab5 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
@@ -81,6 +81,32 @@ default List showTables(String schemaName) {
*/
List listTables(String schemaName, String tableNameLike);
+ /**
+ * Show all external table names list in the specified schema
+ */
+ default List showExternalTables(String schemaName) {
+ return showExternalTablesLike(schemaName, null);
+ }
+
+ List showExternalTablesLike(String schemaName, String tableNameLike);
+
+ /**
+ * List all external table as BObjectIdentity in the specified schema
+ */
+ List listExternalTables(String schemaName, String tableNameLike);
+
+ /**
+ * Judge whether the table is an external table. If the current data source does not support
+ * external table feature,return false
+ */
+ boolean isExternalTable(String schemaName, String tableName);
+
+ /**
+ * Synchronize the associated files of external table
+ */
+ boolean syncExternalTableFiles(String schemaName, String tableName);
+
+
/**
* Show all view names list in the specified schema
*/
@@ -198,6 +224,16 @@ default List showTables(String schemaName) {
*/
List listBasicViewColumns(String schemaName, String viewName);
+ /**
+ * Get all external table columns(hold only basic info) in the specified schema
+ */
+ Map> listBasicExternalTableColumns(String schemaName);
+
+ /**
+ * Get all external table columns(hold only basic info) in the specified schema and view
+ */
+ List listBasicExternalTableColumns(String schemaName, String externalTableName);
+
/**
* Get all table and view columns info (hold only basic info: schema, table and column name) in the
* specified schema
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorFactory.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorFactory.java
index fd0bbbd6a0..616bf55b01 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorFactory.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorFactory.java
@@ -30,10 +30,12 @@
import com.oceanbase.tools.dbbrowser.schema.mysql.OBMySQLBetween220And225XSchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.mysql.OBMySQLBetween2260And2276SchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.mysql.OBMySQLBetween2277And3XSchemaAccessor;
+import com.oceanbase.tools.dbbrowser.schema.mysql.OBMySQLBetween400And432SchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.mysql.OBMySQLNoGreaterThan1479SchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.mysql.OBMySQLSchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.mysql.ODPOBMySQLSchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.oracle.OBOracleBetween4000And4100SchemaAccessor;
+import com.oceanbase.tools.dbbrowser.schema.oracle.OBOracleBetween410And432SchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.oracle.OBOracleLessThan2270SchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.oracle.OBOracleLessThan400SchemaAccessor;
import com.oceanbase.tools.dbbrowser.schema.oracle.OBOracleSchemaAccessor;
@@ -72,9 +74,12 @@ public DBSchemaAccessor buildForMySQL() {
@Override
public DBSchemaAccessor buildForOBMySQL() {
Validate.notNull(this.dbVersion, "DBVersion can not be null");
- if (VersionUtils.isGreaterThanOrEqualsTo(this.dbVersion, "4.0.0")) {
- // OB version >= 4.0.0
+ if (VersionUtils.isGreaterThanOrEqualsTo(this.dbVersion, "4.3.2")) {
+ // OB version >= 4.3.2
return new OBMySQLSchemaAccessor(getJdbcOperations());
+ } else if (VersionUtils.isGreaterThan(this.dbVersion, "4.0.0")) {
+ // OB version between [4.0.0, 4.3.2)
+ return new OBMySQLBetween400And432SchemaAccessor(getJdbcOperations());
} else if (VersionUtils.isGreaterThan(this.dbVersion, "2.2.76")) {
// OB version between [2.2.77, 4.0.0)
return new OBMySQLBetween2277And3XSchemaAccessor(getJdbcOperations());
@@ -105,9 +110,12 @@ public DBSchemaAccessor buildForOBMySQL() {
@Override
public DBSchemaAccessor buildForOBOracle() {
Validate.notNull(this.dbVersion, "DBVersion can not be null");
- if (VersionUtils.isGreaterThanOrEqualsTo(this.dbVersion, "4.1.0")) {
- // OB version >= 4.1.0
+ if (VersionUtils.isGreaterThanOrEqualsTo(this.dbVersion, "4.3.2")) {
+ // OB version >= 4.3.2
return new OBOracleSchemaAccessor(getJdbcOperations(), new ALLDataDictTableNames());
+ } else if (VersionUtils.isGreaterThanOrEqualsTo(this.dbVersion, "4.1.0")) {
+ // OB version between [4.1.0, 4.3.2)
+ return new OBOracleBetween410And432SchemaAccessor(getJdbcOperations(), new ALLDataDictTableNames());
} else if (VersionUtils.isGreaterThanOrEqualsTo(this.dbVersion, "4.0.0")) {
// OB version between [4.0.0, 4.1.0)
return new OBOracleBetween4000And4100SchemaAccessor(getJdbcOperations(), new ALLDataDictTableNames());
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorSqlMappers.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorSqlMappers.java
index f2c9dc8473..eab8b54a3f 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorSqlMappers.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/DBSchemaAccessorSqlMappers.java
@@ -46,7 +46,7 @@ public class DBSchemaAccessorSqlMappers {
static {
SQL_MAPPER_FILE_PATHS.addAll(Arrays.asList(
- StatementsFiles.OBMYSQL_40X,
+ StatementsFiles.OBMYSQL_432x,
StatementsFiles.OBMYSQL_3X,
StatementsFiles.OBMYSQL_2276,
StatementsFiles.OBMYSQL_225X,
@@ -56,6 +56,7 @@ public class DBSchemaAccessorSqlMappers {
StatementsFiles.OBORACLE_3_x,
StatementsFiles.OBORACLE_4_0_x,
StatementsFiles.OBORACLE_4_1_x,
+ StatementsFiles.OBORACLE_4_3_2_x,
StatementsFiles.ORACLE_11_g));
for (String path : SQL_MAPPER_FILE_PATHS) {
URL url = DBSchemaAccessorSqlMappers.class.getClassLoader().getResource(path);
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 edacfc2a80..61521e4982 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
@@ -21,6 +21,8 @@
* @Description: []
*/
public final class Statements {
+ public static final String LIST_BASIC_EXTERNAL_TABLE_COLUMNS = "list-basic-external-table-columns";
+ public static final String LIST_BASIC_SCHEMA_EXTERNAL_TABLE_COLUMNS = "list-basic-schema-external-table-columns";
public static final String LIST_BASIC_TABLE_COLUMNS = "list-basic-table-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";
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/StatementsFiles.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/StatementsFiles.java
index b85ca26295..d5b2c63895 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/StatementsFiles.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/constant/StatementsFiles.java
@@ -21,7 +21,7 @@
* @Description: []
*/
public final class StatementsFiles {
- public static final String OBMYSQL_40X = "schema/sql/obmysql/obmysql_4_0_x.yaml";
+ public static final String OBMYSQL_432x = "schema/sql/obmysql/obmysql_4_3_2_x.yaml";
public static final String OBMYSQL_3X = "schema/sql/obmysql/obmysql_3_x.yaml";
@@ -35,6 +35,8 @@ public final class StatementsFiles {
public static final String MYSQL_5_6_x = "schema/sql/mysql/mysql_5_6_x.yaml";
+ public static final String OBORACLE_4_3_2_x = "schema/sql/oboracle/oboracle_4_3_2_x.yaml";
+
public static final String OBORACLE_4_1_x = "schema/sql/oboracle/oboracle_4_1_x.yaml";
public static final String OBORACLE_4_0_x = "schema/sql/oboracle/oboracle_4_0_x.yaml";
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/doris/DorisSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/doris/DorisSchemaAccessor.java
index 90ce3b070e..6ac4355a26 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/doris/DorisSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/doris/DorisSchemaAccessor.java
@@ -225,6 +225,26 @@ public List listTables(String schemaName, String tableNameLike
return results;
}
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public boolean isExternalTable(String schemaName, String tableName) {
+ return false;
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
protected List listBaseTables(String schemaName, String tableNameLike)
throws DataAccessException {
MySQLSqlBuilder sb = new MySQLSqlBuilder();
@@ -452,6 +472,16 @@ public List listBasicViewColumns(String schemaName, String viewNa
return jdbcOperations.query(sql, new Object[] {schemaName, viewName}, listBasicTableColumnRowMapper());
}
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
@Override
public Map> listBasicColumnsInfo(String schemaName) {
String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_COLUMNS_INFO);
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoLessThan5700SchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoLessThan5700SchemaAccessor.java
index 7301ab76e9..5fc03fca41 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoLessThan5700SchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/MySQLNoLessThan5700SchemaAccessor.java
@@ -233,6 +233,32 @@ public List listTables(String schemaName, String tableNameLike
return listBaseTables(schemaName, tableNameLike);
}
+ @Override
+ public List showExternalTables(String schemaName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public boolean isExternalTable(String schemaName, String tableName) {
+ return false;
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
protected List listBaseTables(String schemaName, String tableNameLike)
throws DataAccessException {
MySQLSqlBuilder sb = new MySQLSqlBuilder();
@@ -467,6 +493,16 @@ public List listBasicViewColumns(String schemaName, String viewNa
return jdbcOperations.query(sql, new Object[] {schemaName, viewName}, listBasicTableColumnRowMapper());
}
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
@Override
public Map> listBasicColumnsInfo(String schemaName) {
String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_COLUMNS_INFO);
@@ -1297,31 +1333,24 @@ public DBProcedure getProcedure(String schemaName, String procedureName) {
.value(schemaName)
.append(" and ROUTINE_TYPE = 'PROCEDURE' and ROUTINE_NAME=")
.value(procedureName);
-
- MySQLSqlBuilder queryForParameters = new MySQLSqlBuilder();
- queryForParameters.append(
- "select PARAMETER_MODE, PARAMETER_NAME, DTD_IDENTIFIER from `information_schema`.`parameters` where SPECIFIC_SCHEMA=")
- .value(schemaName)
- .append(" and SPECIFIC_NAME=")
- .value(procedureName)
- .append(" and ROUTINE_TYPE='PROCEDURE'");
DBProcedure procedure = new DBProcedure();
procedure.setProName(procedureName);
- MySQLSqlBuilder parameters = new MySQLSqlBuilder();
-
- jdbcOperations.query(queryForParameters.toString(), (rs) -> {
- parameters.append(rs.getString("PARAMETER_MODE")).space()
- .identifier(rs.getString("PARAMETER_NAME")).space()
- .append(rs.getString("DTD_IDENTIFIER")).append(",");
+ MySQLSqlBuilder getDDL = new MySQLSqlBuilder();
+ getDDL.append("show create procedure ");
+ if (schemaName == null) {
+ getDDL.identifier(procedureName);
+ } else {
+ getDDL.identifier(schemaName);
+ getDDL.append(".");
+ getDDL.identifier(procedureName);
+ }
+ jdbcOperations.query(getDDL.toString(), (rs) -> {
+ procedure.setDdl(rs.getString("Create Procedure"));
});
jdbcOperations.query(sql1.toString(), (rs) -> {
procedure.setDefiner(rs.getString("DEFINER"));
procedure.setCreateTime(Timestamp.valueOf(rs.getString("CREATED")));
procedure.setModifyTime(Timestamp.valueOf(rs.getString("LAST_ALTERED")));
- procedure.setDdl(String.format("create procedure %s (%s) %s;",
- StringUtils.quoteMysqlIdentifier(procedure.getProName()),
- StringUtils.substring(parameters.toString(), 0, parameters.length() - 1),
- rs.getString("ROUTINE_DEFINITION")));
});
return parseProcedureDDL(procedure);
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween400And432SchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween400And432SchemaAccessor.java
new file mode 100644
index 0000000000..650969ece9
--- /dev/null
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/mysql/OBMySQLBetween400And432SchemaAccessor.java
@@ -0,0 +1,72 @@
+/*
+ * 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.schema.mysql;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.jdbc.core.JdbcOperations;
+
+import com.oceanbase.tools.dbbrowser.model.DBObjectIdentity;
+import com.oceanbase.tools.dbbrowser.model.DBTableColumn;
+
+/**
+ * @description: applicable to OB [4.0.0,4.3.2)
+ * @author: zijia.cj
+ * @date: 2024/8/27 14:55
+ * @since: 4.3.3
+ */
+public class OBMySQLBetween400And432SchemaAccessor extends OBMySQLSchemaAccessor {
+
+
+ public OBMySQLBetween400And432SchemaAccessor(JdbcOperations jdbcOperations) {
+ super(jdbcOperations);
+ }
+
+ @Override
+ public List showExternalTables(String schemaName) {
+ throw new UnsupportedOperationException(
+ "External table is supported by odc after the 432 version of oceanbase");
+ }
+
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException(
+ "External table is supported by odc after the 432 version of oceanbase");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException(
+ "External table is supported by odc after the 432 version of oceanbase");
+ }
+
+ @Override
+ public boolean isExternalTable(String schemaName, String tableName) {
+ return false;
+ }
+
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+}
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 658d8f2dca..bc5720e892 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
@@ -25,6 +25,7 @@
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcOperations;
import com.oceanbase.tools.dbbrowser.model.DBColumnGroupElement;
@@ -41,6 +42,7 @@
import com.oceanbase.tools.dbbrowser.parser.SqlParser;
import com.oceanbase.tools.dbbrowser.parser.result.ParseSqlResult;
import com.oceanbase.tools.dbbrowser.schema.DBSchemaAccessorSqlMappers;
+import com.oceanbase.tools.dbbrowser.schema.constant.Statements;
import com.oceanbase.tools.dbbrowser.schema.constant.StatementsFiles;
import com.oceanbase.tools.dbbrowser.util.DBSchemaAccessorUtil;
import com.oceanbase.tools.dbbrowser.util.MySQLSqlBuilder;
@@ -52,14 +54,14 @@
import lombok.extern.slf4j.Slf4j;
/**
- * 适用 OB 版本:[4.0.0, ~)
+ * 适用 OB 版本:[4.3.2, ~)
*
* @author jingtian
*/
@Slf4j
public class OBMySQLSchemaAccessor extends MySQLNoLessThan5700SchemaAccessor {
- protected static final Set ESCAPE_SCHEMA_SET = new HashSet<>(3);
+ protected static final Set ESCAPE_SCHEMA_SET = new HashSet<>(4);
static {
ESCAPE_SCHEMA_SET.add("PUBLIC");
@@ -76,7 +78,7 @@ public List showDatabases() {
public OBMySQLSchemaAccessor(JdbcOperations jdbcOperations) {
super(jdbcOperations);
- this.sqlMapper = DBSchemaAccessorSqlMappers.get(StatementsFiles.OBMYSQL_40X);
+ this.sqlMapper = DBSchemaAccessorSqlMappers.get(StatementsFiles.OBMYSQL_432x);
}
@Override
@@ -287,16 +289,21 @@ private void parseDdlToSetIndexInfo(String ddl, List indexList) {
fillWarning(indexList, DBObjectType.INDEX, "table ddl is blank, can not set index range by parse ddl");
return;
}
- ParseSqlResult result = SqlParser.parseMysql(ddl);
- if (CollectionUtils.isEmpty(result.getIndexes())) {
- fillWarning(indexList, DBObjectType.INDEX, "parse index DDL failed");
- } else {
- indexList.forEach(index -> result.getIndexes().forEach(dbIndex -> {
- if (StringUtils.equals(index.getName(), dbIndex.getName())) {
- index.setGlobal("GLOBAL".equalsIgnoreCase(dbIndex.getRange().name()));
- index.setColumnGroups(dbIndex.getColumnGroups());
- }
- }));
+ try {
+ ParseSqlResult result = SqlParser.parseMysql(ddl);
+ if (CollectionUtils.isEmpty(result.getIndexes())) {
+ fillWarning(indexList, DBObjectType.INDEX, "parse index DDL failed");
+ } else {
+ indexList.forEach(index -> result.getIndexes().forEach(dbIndex -> {
+ if (StringUtils.equals(index.getName(), dbIndex.getName())) {
+ index.setGlobal("GLOBAL".equalsIgnoreCase(dbIndex.getRange().name()));
+ index.setColumnGroups(dbIndex.getColumnGroups());
+ }
+ }));
+ }
+ } catch (Exception e) {
+ fillWarning(indexList, DBObjectType.INDEX, "failed to set index info by parse ddl");
+ log.warn("failed to set index info by parse ddl:{}", ddl, e);
}
}
@@ -361,6 +368,90 @@ public Map getTables(@NonNull String schemaName, List t
return returnVal;
}
+ @Override
+ public List showExternalTables(String schemaName) {
+ return showExternalTablesLike(schemaName, null);
+ }
+
+
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ MySQLSqlBuilder sb = new MySQLSqlBuilder();
+ sb.append("SELECT table_name FROM information_schema.tables WHERE TABLE_TYPE = 'EXTERNAL TABLE'");
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" AND table_schema=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND table_name LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY table_name");
+ return jdbcOperations.queryForList(sb.toString(), String.class);
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ MySQLSqlBuilder sb = new MySQLSqlBuilder();
+ sb.append("select table_schema as schema_name, 'EXTERNAL_TABLE' as type, table_name as name ");
+ sb.append("from information_schema.tables where table_type = 'EXTERNAL TABLE'");
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" AND table_schema=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND table_name LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY schema_name, table_name");
+ return jdbcOperations.query(sb.toString(), new BeanPropertyRowMapper<>(DBObjectIdentity.class));
+ }
+
+ @Override
+ public boolean isExternalTable(String schemaName, String tableName) {
+ MySQLSqlBuilder sb = new MySQLSqlBuilder();
+ sb.append("SELECT table_type FROM information_schema.tables");
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" Where table_schema=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableName)) {
+ sb.append(" AND table_name = ");
+ sb.value(tableName);
+ }
+ String tableType = jdbcOperations.queryForObject(sb.toString(), String.class);
+ if (tableType == null) {
+ throw new IllegalArgumentException("table name: " + tableName + " is not exist");
+ }
+ if (StringUtils.equalsIgnoreCase(tableType, "EXTERNAL TABLE")) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ MySQLSqlBuilder sb = new MySQLSqlBuilder();
+ sb.append("ALTER EXTERNAL TABLE ").identifier(schemaName, tableName).append(" REFRESH");
+ jdbcOperations.execute(sb.toString());
+ return true;
+ }
+
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_EXTERNAL_TABLE_COLUMNS);
+ List tableColumns = jdbcOperations.query(sql, new Object[] {schemaName, schemaName},
+ listBasicTableColumnRowMapper());
+ return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_EXTERNAL_TABLE_COLUMNS);
+ return jdbcOperations.query(sql, new Object[] {schemaName, externalTableName}, listBasicTableColumnRowMapper());
+ }
+
@Override
protected void correctColumnPrecisionIfNeed(List tableColumns) {}
}
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 5b341587c0..8ad6f47f37 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
@@ -162,4 +162,19 @@ public DBProcedure getProcedure(String schemaName, String procedureName) {
throw new UnsupportedOperationException("Not supported yet");
}
+ @Override
+ public List showExternalTables(String schemaName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween4000And4100SchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween4000And4100SchemaAccessor.java
index f88aec2d4c..0a9e5a4894 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween4000And4100SchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween4000And4100SchemaAccessor.java
@@ -27,7 +27,7 @@
* @author jingtian
* @date 2024/4/15
*/
-public class OBOracleBetween4000And4100SchemaAccessor extends OBOracleSchemaAccessor {
+public class OBOracleBetween4000And4100SchemaAccessor extends OBOracleBetween410And432SchemaAccessor {
public OBOracleBetween4000And4100SchemaAccessor(JdbcOperations jdbcOperations,
OracleDataDictTableNames dataDictTableNames) {
super(jdbcOperations, dataDictTableNames);
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween410And432SchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween410And432SchemaAccessor.java
new file mode 100644
index 0000000000..c5467643d5
--- /dev/null
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleBetween410And432SchemaAccessor.java
@@ -0,0 +1,116 @@
+/*
+ * 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.schema.oracle;
+
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
+import org.springframework.jdbc.core.JdbcOperations;
+
+import com.oceanbase.tools.dbbrowser.model.DBObjectIdentity;
+import com.oceanbase.tools.dbbrowser.model.DBTableColumn;
+import com.oceanbase.tools.dbbrowser.schema.DBSchemaAccessorSqlMappers;
+import com.oceanbase.tools.dbbrowser.schema.constant.StatementsFiles;
+import com.oceanbase.tools.dbbrowser.util.OracleDataDictTableNames;
+import com.oceanbase.tools.dbbrowser.util.OracleSqlBuilder;
+import com.oceanbase.tools.dbbrowser.util.StringUtils;
+
+/**
+ * @description: applicable to OB [4.1.0,4.3.2)
+ * @author: zijia.cj
+ * @date: 2024/8/27 15:13
+ * @since: 4.3.3
+ */
+public class OBOracleBetween410And432SchemaAccessor extends OBOracleSchemaAccessor {
+
+ public OBOracleBetween410And432SchemaAccessor(JdbcOperations jdbcOperations,
+ OracleDataDictTableNames dataDictTableNames) {
+ super(jdbcOperations, dataDictTableNames);
+ this.sqlMapper = DBSchemaAccessorSqlMappers.get(StatementsFiles.OBORACLE_4_1_x);
+ }
+
+ @Override
+ public List showExternalTables(String schemaName) {
+ throw new UnsupportedOperationException(
+ "External table is supported by odc after the 432 version of oceanbase");
+ }
+
+
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException(
+ "External table is supported by odc after the 432 version of oceanbase");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException(
+ "External table is supported by odc after the 432 version of oceanbase");
+ }
+
+ @Override
+ public List showTablesLike(String schemaName, String tableNameLike) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("SELECT TABLE_NAME FROM ");
+ sb.append(dataDictTableNames.TABLES());
+ sb.append(" WHERE OWNER=");
+ sb.value(schemaName);
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND TABLE_NAME LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY TABLE_NAME ASC");
+ return jdbcOperations.queryForList(sb.toString(), String.class);
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List listTables(String schemaName, String tableNameLike) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("select OWNER as schema_name, 'TABLE' as type,TABLE_NAME as name");
+ sb.append(" from ");
+ sb.append(dataDictTableNames.TABLES());
+ sb.append(" where 1=1 ");
+
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" AND OWNER=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND TABLE_NAME LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY schema_name, type, name");
+ return jdbcOperations.query(sb.toString(), new BeanPropertyRowMapper<>(DBObjectIdentity.class));
+ }
+
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+
+}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleSchemaAccessor.java
index 8d57ebd5f0..4ca56d6f6e 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/oracle/OBOracleSchemaAccessor.java
@@ -71,6 +71,7 @@
import com.oceanbase.tools.dbbrowser.parser.result.ParseOraclePLResult;
import com.oceanbase.tools.dbbrowser.parser.result.ParseSqlResult;
import com.oceanbase.tools.dbbrowser.schema.DBSchemaAccessorSqlMappers;
+import com.oceanbase.tools.dbbrowser.schema.constant.Statements;
import com.oceanbase.tools.dbbrowser.schema.constant.StatementsFiles;
import com.oceanbase.tools.dbbrowser.util.DBSchemaAccessorUtil;
import com.oceanbase.tools.dbbrowser.util.OracleDataDictTableNames;
@@ -85,7 +86,7 @@
import lombok.extern.slf4j.Slf4j;
/**
- * 适用于的 DB 版本:[4.1.0, ~)
+ * 适用于的 DB 版本:[4.3.2, ~)
*
* @author jingtian
*/
@@ -103,7 +104,7 @@ public class OBOracleSchemaAccessor extends OracleSchemaAccessor {
public OBOracleSchemaAccessor(JdbcOperations jdbcOperations,
OracleDataDictTableNames dataDictTableNames) {
super(jdbcOperations, dataDictTableNames);
- this.sqlMapper = DBSchemaAccessorSqlMappers.get(StatementsFiles.OBORACLE_4_1_x);
+ this.sqlMapper = DBSchemaAccessorSqlMappers.get(StatementsFiles.OBORACLE_4_3_2_x);
}
@Override
@@ -1035,4 +1036,113 @@ public Map getTables(@NonNull String schemaName, List t
}
return returnVal;
}
+
+ @Override
+ public List showExternalTables(String schemaName) {
+ return showExternalTablesLike(schemaName, null);
+ }
+
+
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ return commonShowTablesLike(schemaName, tableNameLike, DBObjectType.EXTERNAL_TABLE);
+ }
+
+
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("select OWNER as schema_name, 'EXTERNAL_TABLE' as type,TABLE_NAME as name");
+ sb.append(" from ");
+ sb.append(dataDictTableNames.TABLES());
+ sb.append(" where EXTERNAL = 'YES'");
+
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" AND OWNER=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND TABLE_NAME LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY schema_name, type, name");
+ return jdbcOperations.query(sb.toString(), new BeanPropertyRowMapper<>(DBObjectIdentity.class));
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("ALTER EXTERNAL TABLE ").identifier(schemaName, tableName).append(" REFRESH");
+ jdbcOperations.execute(sb.toString());
+ return true;
+ }
+
+ // After ob version 4.3.2, oracle model displaying table list needs to exclude external tables
+ @Override
+ public List showTablesLike(String schemaName, String tableNameLike) {
+ return commonShowTablesLike(schemaName, tableNameLike, DBObjectType.TABLE);
+ }
+
+ // After ob version 4.3.2, oracle model displaying table list needs to exclude external tables
+ @Override
+ public List listTables(String schemaName, String tableNameLike) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("select OWNER as schema_name, 'TABLE' as type,TABLE_NAME as name");
+ sb.append(" from ");
+ sb.append(dataDictTableNames.TABLES());
+ sb.append(" where EXTERNAL = 'NO'");
+
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" AND OWNER=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND TABLE_NAME LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY schema_name, type, name");
+ return jdbcOperations.query(sb.toString(), new BeanPropertyRowMapper<>(DBObjectIdentity.class));
+ }
+
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_EXTERNAL_TABLE_COLUMNS);
+ List tableColumns =
+ jdbcOperations.query(sql, new Object[] {schemaName, schemaName}, listBasicColumnsRowMapper());
+ return tableColumns.stream().collect(Collectors.groupingBy(DBTableColumn::getTableName));
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ String sql = sqlMapper.getSql(Statements.LIST_BASIC_EXTERNAL_TABLE_COLUMNS);
+ return jdbcOperations.query(sql, new Object[] {schemaName, externalTableName}, listBasicColumnsRowMapper());
+ }
+
+ private List commonShowTablesLike(String schemaName, String tableNameLike,
+ @NonNull DBObjectType tableType) {
+ OracleSqlBuilder sb = new OracleSqlBuilder();
+ sb.append("SELECT TABLE_NAME FROM ");
+ sb.append(dataDictTableNames.TABLES());
+ switch (tableType) {
+ case TABLE:
+ sb.append(" WHERE EXTERNAL = 'NO'");
+ break;
+ case EXTERNAL_TABLE:
+ sb.append(" WHERE EXTERNAL = 'YES'");
+ break;
+ default:
+ throw new UnsupportedOperationException("Not supported table type");
+ }
+ if (StringUtils.isNotBlank(schemaName)) {
+ sb.append(" AND OWNER=");
+ sb.value(schemaName);
+ }
+ if (StringUtils.isNotBlank(tableNameLike)) {
+ sb.append(" AND TABLE_NAME LIKE ");
+ sb.value(tableNameLike);
+ }
+ sb.append(" ORDER BY TABLE_NAME ASC");
+ return jdbcOperations.queryForList(sb.toString(), String.class);
+ }
}
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 35bba2e82d..d3c2de4b8d 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
@@ -247,6 +247,26 @@ public List listTables(String schemaName, String tableNameLike
return jdbcOperations.query(sb.toString(), new BeanPropertyRowMapper<>(DBObjectIdentity.class));
}
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not support yet");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not support yet");
+ }
+
+ @Override
+ public boolean isExternalTable(String schemaName, String tableName) {
+ return false;
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
@Override
public List listViews(String schemaName) {
OracleSqlBuilder sb = new OracleSqlBuilder();
@@ -624,6 +644,16 @@ public List listBasicViewColumns(String schemaName, String viewNa
return jdbcOperations.query(sql, new Object[] {schemaName, viewName}, listBasicColumnsRowMapper());
}
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
@Override
public Map> listBasicColumnsInfo(String schemaName) {
String sql = sqlMapper.getSql(Statements.LIST_BASIC_SCHEMA_COLUMNS_INFO);
@@ -839,7 +869,7 @@ protected RowMapper listColumnsRowMapper() {
tableColumn.setVirtual("YES".equalsIgnoreCase(rs.getString(OracleConstants.COL_VIRTUAL_COLUMN)));
tableColumn.setDefaultValue("NULL".equals(defaultValue) ? null : defaultValue);
if (tableColumn.getVirtual()) {
- tableColumn.setGenExpression(rs.getString(OracleConstants.COL_DATA_DEFAULT));
+ tableColumn.setGenExpression(defaultValue);
}
return tableColumn;
};
@@ -1835,5 +1865,4 @@ protected String getSynonymOwnerSymbol(DBSynonymType synonymType, String schemaN
throw new UnsupportedOperationException("Not supported Synonym type");
}
}
-
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/postgre/PostgresSchemaAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/postgre/PostgresSchemaAccessor.java
index a4aa3be576..c76721fd57 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/postgre/PostgresSchemaAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/schema/postgre/PostgresSchemaAccessor.java
@@ -137,6 +137,26 @@ public List listTables(String schemaName, String tableNameLike
throw new UnsupportedOperationException("Not supported yet");
}
+ @Override
+ public List showExternalTablesLike(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public List listExternalTables(String schemaName, String tableNameLike) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
+ @Override
+ public boolean isExternalTable(String schemaName, String tableName) {
+ return false;
+ }
+
+ @Override
+ public boolean syncExternalTableFiles(String schemaName, String tableName) {
+ throw new UnsupportedOperationException("Not supported yet");
+ }
+
@Override
public List listViews(String schemaName) {
throw new UnsupportedOperationException("Not supported yet");
@@ -261,6 +281,16 @@ public List listBasicViewColumns(String schemaName, String viewNa
throw new UnsupportedOperationException("Not supported yet");
}
+ @Override
+ public Map> listBasicExternalTableColumns(String schemaName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
+ @Override
+ public List listBasicExternalTableColumns(String schemaName, String externalTableName) {
+ throw new UnsupportedOperationException("not support yet");
+ }
+
@Override
public Map> listBasicColumnsInfo(String schemaName) {
throw new UnsupportedOperationException("Not supported yet");
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLNoLessThan400StatsAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLNoLessThan400StatsAccessor.java
index a219659da4..35fe77a72b 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLNoLessThan400StatsAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLNoLessThan400StatsAccessor.java
@@ -41,7 +41,7 @@ public class OBMySQLNoLessThan400StatsAccessor extends OBMySQLStatsAccessor {
+ " STATE, "
+ " `USER_CLIENT_IP` as HOST, "
+ " HOST as PROXY_HOST, "
- + " CONCAT(SVR_IP, ':', SVR_PORT) AS SVR_IP, "
+ + " CONCAT(SVR_IP, ':', SQL_PORT) AS SVR_IP, "
+ " TIME as EXECUTE_TIME, "
+ " CASE "
+ " WHEN `TRANS_STATE` IS NULL OR `TRANS_STATE` IN ('', 'IDLE', 'IN_TERMINATE', 'ABORTED', "
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLStatsAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLStatsAccessor.java
index 4483190185..ec105f1fe4 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLStatsAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/mysql/OBMySQLStatsAccessor.java
@@ -15,8 +15,15 @@
*/
package com.oceanbase.tools.dbbrowser.stats.mysql;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.springframework.jdbc.core.JdbcOperations;
+import com.oceanbase.tools.dbbrowser.model.DBSession;
+import com.oceanbase.tools.dbbrowser.util.StringUtils;
+
import lombok.NonNull;
/**
@@ -28,8 +35,25 @@
*/
public class OBMySQLStatsAccessor extends MySQLNoLessThan5700StatsAccessor {
+ private static final String LIST_SESSIONS_BY_SHOW_PROCESSLIST = "SHOW FULL PROCESSLIST";
+
public OBMySQLStatsAccessor(@NonNull JdbcOperations jdbcOperations) {
super(jdbcOperations);
}
+ @Override
+ public List listAllSessions() {
+ List sessions = super.listAllSessions();
+ Map sessionId2SvrIp = new HashMap<>();
+ jdbcOperations.query(LIST_SESSIONS_BY_SHOW_PROCESSLIST, rs -> {
+ if (rs.getMetaData().getColumnCount() == 11) {
+ String id = rs.getString("Id");
+ String svrIp = StringUtils.join(rs.getString("Ip"), ":", rs.getString("Port"));
+ sessionId2SvrIp.put(id, svrIp);
+ }
+ });
+ sessions.forEach(session -> session.setSvrIp(sessionId2SvrIp.get(session.getId())));
+ return sessions;
+ }
+
}
diff --git a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/oracle/OBOracleNoLessThan400StatsAccessor.java b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/oracle/OBOracleNoLessThan400StatsAccessor.java
index cb727753a4..6ce9432dcf 100644
--- a/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/oracle/OBOracleNoLessThan400StatsAccessor.java
+++ b/libs/db-browser/src/main/java/com/oceanbase/tools/dbbrowser/stats/oracle/OBOracleNoLessThan400StatsAccessor.java
@@ -38,7 +38,7 @@ public class OBOracleNoLessThan400StatsAccessor extends BaseOBOracleStatsAccesso
+ " STATE, "
+ " USER_CLIENT_IP as HOST, "
+ " HOST as PROXY_HOST, "
- + " SVR_IP || ':' || TO_CHAR(SVR_PORT) AS SVR_IP, "
+ + " SVR_IP || ':' || TO_CHAR(SQL_PORT) AS SVR_IP, "
+ " TIME as EXECUTE_TIME, "
+ " CASE "
+ " WHEN TRANS_STATE IS NULL OR TRANS_STATE IN ('', 'IDLE', 'IN_TERMINATE', 'ABORTED', "
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_3_2_x.yaml
similarity index 86%
rename from libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_4_0_x.yaml
rename to libs/db-browser/src/main/resources/schema/sql/obmysql/obmysql_4_3_2_x.yaml
index bb8fe23387..601d4e6d92 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_3_2_x.yaml
@@ -34,6 +34,41 @@ sqls:
ORDER BY
TABLE_NAME ASC,
ORDINAL_POSITION ASC
+ list-basic-external-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-external-table-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 = 'EXTERNAL TABLE'
+ )
+ ORDER BY
+ TABLE_NAME ASC,
+ ORDINAL_POSITION ASC
list-basic-view-columns: |-
SELECT
TABLE_SCHEMA,
diff --git a/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_3_2_x.yaml b/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_3_2_x.yaml
new file mode 100644
index 0000000000..98dfe4076a
--- /dev/null
+++ b/libs/db-browser/src/main/resources/schema/sql/oboracle/oboracle_4_3_2_x.yaml
@@ -0,0 +1,324 @@
+sqls:
+ list-basic-table-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 = ? AND USER_GENERATED='YES'
+ ORDER BY
+ COLUMN_ID ASC
+ list-basic-schema-table-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
+ TABLE_NAME
+ FROM
+ SYS.ALL_TABLES
+ WHERE
+ OWNER = ? AND EXTERNAL='NO'
+ ) AND USER_GENERATED='YES'
+ ORDER BY
+ TABLE_NAME ASC,
+ COLUMN_ID ASC
+ list-basic-external-table-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 = ? AND USER_GENERATED='YES'
+ ORDER BY
+ COLUMN_ID ASC
+ list-basic-schema-external-table-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
+ TABLE_NAME
+ FROM
+ SYS.ALL_TABLES
+ WHERE
+ OWNER = ? AND EXTERNAL='YES'
+ ) AND USER_GENERATED='YES'
+ ORDER BY
+ 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 = ? AND USER_GENERATED='YES'
+ 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 = ?
+ ) AND USER_GENERATED='YES'
+ ORDER BY
+ TABLE_NAME ASC,
+ COLUMN_ID ASC
+ list-basic-schema-columns-info: |-
+ SELECT
+ OWNER,
+ TABLE_NAME,
+ COLUMN_NAME
+ FROM
+ SYS.ALL_TAB_COLS
+ WHERE
+ OWNER = ?
+ ORDER BY
+ TABLE_NAME ASC,
+ COLUMN_ID ASC
+ list-table-columns: |-
+ SELECT
+ OWNER,
+ TABLE_NAME,
+ COLUMN_ID,
+ COLUMN_NAME,
+ DATA_TYPE,
+ DATA_SCALE,
+ DATA_PRECISION,
+ DATA_LENGTH,
+ CHAR_LENGTH,
+ DATA_TYPE_MOD,
+ CHAR_USED,
+ NULLABLE,
+ DATA_DEFAULT,
+ HIDDEN_COLUMN,
+ VIRTUAL_COLUMN
+ FROM
+ SYS.ALL_TAB_COLS
+ WHERE
+ OWNER = ? AND TABLE_NAME = ? and USER_GENERATED='YES'
+ ORDER BY
+ COLUMN_ID ASC
+ list-schema-columns: |-
+ SELECT
+ OWNER,
+ TABLE_NAME,
+ COLUMN_ID,
+ COLUMN_NAME,
+ DATA_TYPE,
+ DATA_SCALE,
+ DATA_PRECISION,
+ DATA_LENGTH,
+ CHAR_LENGTH,
+ DATA_TYPE_MOD,
+ CHAR_USED,
+ NULLABLE,
+ DATA_DEFAULT,
+ HIDDEN_COLUMN,
+ VIRTUAL_COLUMN
+ FROM
+ SYS.ALL_TAB_COLS
+ WHERE
+ OWNER = ? and USER_GENERATED='YES'
+ ORDER BY
+ COLUMN_ID ASC
+ list-table-indexes: |-
+ SELECT
+ IDX.OWNER,
+ IDX.TABLE_OWNER,
+ IDX.TABLE_NAME,
+ IDX.INDEX_NAME,
+ IDX_COL.COLUMN_NAME,
+ IDX_COL.COLUMN_POSITION,
+ IDX.INDEX_TYPE,
+ IDX.UNIQUENESS,
+ IDX.COMPRESSION,
+ IDX.VISIBILITY,
+ IDX.STATUS
+ FROM
+ SYS.ALL_IND_COLUMNS IDX_COL
+ LEFT JOIN
+ SYS.ALL_INDEXES IDX ON IDX_COL.TABLE_OWNER = IDX.TABLE_OWNER
+ AND IDX_COL.TABLE_NAME = IDX.TABLE_NAME
+ AND IDX_COL.INDEX_NAME = IDX.INDEX_NAME
+ WHERE
+ IDX.TABLE_OWNER = ? AND IDX.TABLE_NAME = ?
+ ORDER BY
+ IDX.INDEX_NAME,
+ IDX_COL.COLUMN_POSITION ASC
+ list-schema-index: |-
+ SELECT
+ IDX.OWNER,
+ IDX.TABLE_OWNER,
+ IDX.TABLE_NAME,
+ IDX.INDEX_NAME,
+ IDX_COL.COLUMN_NAME,
+ IDX_COL.COLUMN_POSITION,
+ IDX.INDEX_TYPE,
+ IDX.UNIQUENESS,
+ IDX.COMPRESSION,
+ IDX.VISIBILITY,
+ IDX.STATUS
+ FROM
+ SYS.ALL_IND_COLUMNS IDX_COL
+ LEFT JOIN
+ SYS.ALL_INDEXES IDX ON IDX_COL.TABLE_OWNER = IDX.TABLE_OWNER
+ AND IDX_COL.TABLE_NAME = IDX.TABLE_NAME
+ AND IDX_COL.INDEX_NAME = IDX.INDEX_NAME
+ WHERE
+ IDX.TABLE_OWNER = ?
+ ORDER BY
+ IDX.TABLE_NAME,
+ IDX.INDEX_NAME,
+ IDX_COL.COLUMN_POSITION ASC
+ list-table-constraints: |-
+ SELECT
+ t1.OWNER,
+ t1.CONSTRAINT_NAME,
+ t1.CONSTRAINT_TYPE,
+ t1.TABLE_NAME,
+ t1.SEARCH_CONDITION,
+ t1.R_OWNER,
+ t1.R_CONSTRAINT_NAME,
+ t1.DELETE_RULE,
+ t1.STATUS,
+ t1.DEFERRABLE,
+ t1.DEFERRED,
+ t1.VALIDATED,
+ t2.TABLE_NAME as R_TABLE_NAME,
+ t2.COLUMN_NAME as R_COLUMN_NAME,
+ t3.position as POSITION,
+ t3.COLUMN_NAME as COLUMN_NAME
+ FROM
+ SYS.ALL_CONSTRAINTS t1
+ JOIN SYS.ALL_CONS_COLUMNS t3 on t1.CONSTRAINT_NAME = t3.CONSTRAINT_NAME and t1.OWNER = t3.OWNER
+ LEFT JOIN SYS.ALL_CONS_COLUMNS t2 on t2.CONSTRAINT_NAME = t1.R_CONSTRAINT_NAME
+ AND t2.OWNER = t1.R_OWNER
+ WHERE
+ t1.OWNER = ? and t1.TABLE_NAME = ?
+ ORDER BY
+ t1.CONSTRAINT_NAME,
+ t3.position ASC
+ list-schema-constraints: |-
+ SELECT
+ t1.OWNER,
+ t1.CONSTRAINT_NAME,
+ t1.CONSTRAINT_TYPE,
+ t1.TABLE_NAME,
+ t1.SEARCH_CONDITION,
+ t1.R_OWNER,
+ t1.R_CONSTRAINT_NAME,
+ t1.DELETE_RULE,
+ t1.STATUS,
+ t1.DEFERRABLE,
+ t1.DEFERRED,
+ t1.VALIDATED,
+ t2.TABLE_NAME as R_TABLE_NAME,
+ t2.COLUMN_NAME as R_COLUMN_NAME,
+ t3.position as POSITION,
+ t3.COLUMN_NAME as COLUMN_NAME
+ FROM
+ SYS.ALL_CONSTRAINTS t1
+ JOIN SYS.ALL_CONS_COLUMNS t3 on t1.CONSTRAINT_NAME = t3.CONSTRAINT_NAME and t1.OWNER = t3.OWNER
+ LEFT JOIN SYS.ALL_CONS_COLUMNS t2 on t2.CONSTRAINT_NAME = t1.R_CONSTRAINT_NAME
+ AND t2.OWNER = t1.R_OWNER
+ WHERE
+ t1.OWNER = ?
+ ORDER BY
+ t1.TABLE_NAME,
+ t1.CONSTRAINT_NAME,
+ t3.position ASC
+ get-partition-option: |-
+ SELECT
+ PARTITIONING_TYPE
+ FROM
+ SYS.ALL_PART_TABLES
+ WHERE
+ OWNER = ?
+ AND TABLE_NAME = ?
+ list-partitions-options: |-
+ SELECT
+ TABLE_NAME,
+ PARTITIONING_TYPE
+ FROM
+ SYS.ALL_PART_TABLES
+ WHERE
+ OWNER = ?
+ list-partition-definitions: |-
+ SELECT
+ PARTITION_NAME,
+ PARTITION_POSITION,
+ HIGH_VALUE
+ FROM
+ SYS.ALL_TAB_PARTITIONS
+ WHERE
+ TABLE_OWNER = ?
+ AND TABLE_NAME = ?
+ ORDER BY
+ PARTITION_POSITION ASC
+ list-partitions-definitions: |-
+ SELECT
+ TABLE_NAME,
+ PARTITION_NAME,
+ PARTITION_POSITION,
+ HIGH_VALUE
+ FROM
+ SYS.ALL_TAB_PARTITIONS
+ WHERE
+ TABLE_OWNER = ?
+ ORDER BY
+ PARTITION_POSITION ASC
+ list-database: |-
+ select
+ USERNAME,
+ USERID
+ from
+ ALL_USERS
+ get-database: |-
+ SELECT
+ USERNAME,
+ USERID
+ from
+ SYS.ALL_USERS
+ WHERE
+ USERNAME = ?
\ No newline at end of file
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/PLParserTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/PLParserTest.java
index 5aded51d8a..63390a1a23 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/PLParserTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/PLParserTest.java
@@ -57,6 +57,172 @@ public void testParseMysqlProcedure() {
Assert.assertEquals(1, result.getParamList().size());
}
+ @Test
+ public void testParseMysqlProcedureContainsDefiner() {
+ String pl = "create DEFINER = `root`@`%` PROCEDURE testProduce (out p1 int) \n" + "BEGIN \n"
+ + "DECLARE Eno INT DEFAULT 10000;\n"
+ + "DECLARE En VARCHAR(20);\n" + "DECLARE J VARCHAR(20);\n" + "DECLARE M INT DEFAULT 80000;\n"
+ + "DECLARE H YEAR;\n" + "DECLARE Dno INT;\n" + "DECLARE i INT DEFAULT 1; \n" + "RETURN;\n" + "END;";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(7, result.getVaribaleList().size());
+ Assert.assertEquals("testProduce", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(1, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerWithoutParams() {
+ String pl = "CREATE DEFINER = `root`@`%` PROCEDURE simple_procedure()\n" +
+ "BEGIN\n" +
+ " SELECT 'Hello, World!';\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(0, result.getVaribaleList().size());
+ Assert.assertEquals("simple_procedure", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(0, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerWithInput() {
+ String pl = "CREATE DEFINER = `root`@`%` PROCEDURE greet_user(IN user_name VARCHAR(50))\n" +
+ "BEGIN\n" +
+ " SELECT CONCAT('Hello, ', user_name, '!');\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(0, result.getVaribaleList().size());
+ Assert.assertEquals("greet_user", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(1, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerWithInputAndOutput() {
+ String pl = "CREATE DEFINER = `root`@`%` PROCEDURE get_user_name(IN user_id INT, OUT user_name VARCHAR(50))\n" +
+ "BEGIN\n" +
+ " SELECT name INTO user_name FROM users WHERE id = user_id;\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(0, result.getVaribaleList().size());
+ Assert.assertEquals("get_user_name", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(2, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerAndCondition() {
+ String pl =
+ "CREATE DEFINER = `root`@`%` PROCEDURE check_user_status(IN user_id INT, OUT user_status VARCHAR(20))\n"
+ +
+ "BEGIN\n" +
+ " DECLARE user_count INT;\n" +
+ "\n" +
+ " SELECT COUNT(*) INTO user_count FROM users WHERE id = user_id;\n" +
+ "\n" +
+ " IF user_count > 0 THEN\n" +
+ " SELECT status INTO user_status FROM users WHERE id = user_id;\n" +
+ " ELSE\n" +
+ " SET user_status = 'User not found';\n" +
+ " END IF;\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(1, result.getVaribaleList().size());
+ Assert.assertEquals("check_user_status", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(2, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerAndFunction() {
+ String pl = "CREATE DEFINER = `root`@`%` PROCEDURE calculate_user_average_age(OUT average_age FLOAT)\n" +
+ "BEGIN\n" +
+ " SELECT AVG(age) INTO average_age FROM users;\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(0, result.getVaribaleList().size());
+ Assert.assertEquals("calculate_user_average_age", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(1, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerAndCursor() {
+ String pl = "CREATE DEFINER = `root`@`%` PROCEDURE list_all_users()\n" +
+ "BEGIN\n" +
+ " DECLARE done INT DEFAULT 0;\n" +
+ " DECLARE user_id INT;\n" +
+ " DECLARE user_name VARCHAR(50);\n" +
+ "\n" +
+ " DECLARE user_cursor CURSOR FOR SELECT id, name FROM users;\n" +
+ " DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;\n" +
+ "\n" +
+ " OPEN user_cursor;\n" +
+ "\n" +
+ " read_loop: LOOP\n" +
+ " FETCH user_cursor INTO user_id, user_name;\n" +
+ " IF done THEN\n" +
+ " LEAVE read_loop;\n" +
+ " END IF;\n" +
+ " SELECT CONCAT('User ID: ', user_id, ', User Name: ', user_name);\n" +
+ " END LOOP;\n" +
+ "\n" +
+ " CLOSE user_cursor;\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(5, result.getVaribaleList().size());
+ Assert.assertEquals("list_all_users", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(0, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerAndException() {
+ String pl =
+ "CREATE DEFINER = `root`@`%` PROCEDURE safe_update_user_email(IN user_id INT, IN new_email VARCHAR(100), OUT result_message VARCHAR(100))\n"
+ +
+ "BEGIN\n" +
+ " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION\n" +
+ " BEGIN\n" +
+ " SET result_message = 'An error occurred while updating the email.';\n" +
+ " END;\n" +
+ "\n" +
+ " UPDATE users SET email = new_email WHERE id = user_id;\n" +
+ " IF ROW_COUNT() = 0 THEN\n" +
+ " SET result_message = 'No user found with the provided ID.';\n" +
+ " ELSE\n" +
+ " SET result_message = 'Email updated successfully.';\n" +
+ " END IF;\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(1, result.getVaribaleList().size());
+ Assert.assertEquals("safe_update_user_email", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(3, result.getParamList().size());
+ }
+
+ @Test
+ public void testParseMysqlProcedureContainsDefinerAndMultipleTables() {
+ String pl =
+ "CREATE DEFINER = `root`@`%` PROCEDURE activate_user_and_log(IN user_id INT, OUT result_message VARCHAR(100))\n"
+ +
+ "BEGIN\n" +
+ " UPDATE users SET status = 'active' WHERE id = user_id;\n" +
+ " \n" +
+ " IF ROW_COUNT() > 0 THEN\n" +
+ " INSERT INTO logs (user_id, action, created_at) VALUES (user_id, 'Activated user', NOW());\n"
+ +
+ " SET result_message = 'User activated and logged.';\n" +
+ " ELSE\n" +
+ " SET result_message = 'User not found for activation.';\n" +
+ " END IF;\n" +
+ "END";
+ ParseMysqlPLResult result = PLParser.parseObMysql(pl);
+ Assert.assertEquals(0, result.getVaribaleList().size());
+ Assert.assertEquals("activate_user_and_log", result.getPlName());
+ Assert.assertEquals("PROCEDURE", result.getPlType());
+ Assert.assertEquals(2, result.getParamList().size());
+ }
+
@Test
public void testParseOracleProcedure() {
String pl = "create procedure pl_test(p1 in int default 1, p2 in varchar2) \n" + "is \n" + "v1 number;\n"
@@ -1183,4 +1349,54 @@ public void parseOracle_rollbackStmt_getSqlTypeSucceed() {
Assert.assertEquals(SqlType.ROLLBACK, actual.getSqlType());
}
+ @Test
+ public void parseOracle_commentOnTable_getSqlTypeSucceed() {
+ ParseOraclePLResult actual = PLParser.parseOracle("comment on table a is 'xxx'");
+ Assert.assertEquals(DBObjectType.TABLE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.COMMENT_ON, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_commentOnColumn_getSqlTypeSucceed() {
+ ParseOraclePLResult actual = PLParser.parseOracle("comment on column a is 'xxx'");
+ Assert.assertEquals(DBObjectType.COLUMN, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.COMMENT_ON, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_commentOnMaterialized_getSqlTypeSucceed() {
+ ParseOraclePLResult actual = PLParser.parseOracle("comment on materialized a is 'xxx'");
+ Assert.assertEquals(DBObjectType.OTHERS, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.COMMENT_ON, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_call_getSqlTypeSucceed() {
+ ParseOraclePLResult actual = PLParser.parseOracle("call proc()");
+ Assert.assertEquals(DBObjectType.PROCEDURE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.CALL, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOBMysql_call_getSqlTypeSucceed() {
+ ParseMysqlPLResult actual = PLParser.parseObMysql("call proc()");
+ Assert.assertEquals(DBObjectType.PROCEDURE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.CALL, actual.getSqlType());
+ }
+
+ @Test
+ public void test_oracle_alter_session() {
+ String sql = "alter SESSION set ob_query_timeout=6000000000;";
+ ParseOraclePLResult result = PLParser.parseOracle(sql);
+ Assert.assertEquals(SqlType.ALTER_SESSION, result.getSqlType());
+ Assert.assertEquals(DBObjectType.OTHERS, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_set_session() {
+ String sql = "SET SESSION ob_query_timeout=6000000000;";
+ ParseOraclePLResult result = PLParser.parseOracle(sql);
+ Assert.assertEquals(SqlType.SET_SESSION, result.getSqlType());
+ Assert.assertEquals(DBObjectType.OTHERS, result.getDbObjectType());
+ }
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/ParserUtilTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/ParserUtilTest.java
index 06d00c1d56..4a51bb61c2 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/ParserUtilTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/ParserUtilTest.java
@@ -288,4 +288,96 @@ public void test_mysql_pl_syntax_error() {
BasicResult result = ParserUtil.parseOracleType(sql);
Assert.assertTrue(result.getSyntaxError());
}
+
+ @Test
+ public void test_mysql_set_session() {
+ String sql = "SET SESSION time_zone = '+00:00';";
+ BasicResult result = ParserUtil.parseMysqlType(sql);
+ Assert.assertEquals(SqlType.SET_SESSION, result.getSqlType());
+ Assert.assertEquals(SqlType.SET, result.getSqlType().getParentType());
+ Assert.assertEquals(DBObjectType.SESSION_VARIABLE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_mysql_set_global() {
+ String sql = "SET GLOBAL time_zone = '+00:00';";
+ BasicResult result = ParserUtil.parseMysqlType(sql);
+ Assert.assertEquals(SqlType.SET, result.getSqlType());
+ Assert.assertEquals(DBObjectType.GLOBAL_VARIABLE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_set_global() {
+ String sql = "SET GLOBAL time_zone = '+00:00';";
+ BasicResult result = ParserUtil.parseMysqlType(sql);
+ Assert.assertEquals(SqlType.SET, result.getSqlType());
+ Assert.assertEquals(DBObjectType.GLOBAL_VARIABLE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_alter_system() {
+ String sql = "ALTER SYSTEM SET time_zone = '+00:00';";
+ BasicResult result = ParserUtil.parseOracleType(sql);
+ Assert.assertEquals(SqlType.ALTER, result.getSqlType());
+ Assert.assertEquals(DBObjectType.OTHERS, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_mysql_set() {
+ String sql = "SET time_zone = '+00:00';";
+ BasicResult result = ParserUtil.parseMysqlType(sql);
+ Assert.assertEquals(SqlType.SET, result.getSqlType());
+ Assert.assertEquals(DBObjectType.SYSTEM_VARIABLE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_mysql_call() {
+ String sql = "call proc()";
+ BasicResult result = ParserUtil.parseMysqlType(sql);
+ Assert.assertEquals(SqlType.CALL, result.getSqlType());
+ Assert.assertEquals(DBObjectType.PROCEDURE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_call() {
+ String sql = "call proc()";
+ BasicResult result = ParserUtil.parseOracleType(sql);
+ Assert.assertEquals(SqlType.CALL, result.getSqlType());
+ Assert.assertEquals(DBObjectType.PROCEDURE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_alterSession() {
+ String sql = "alter SESSION set ob_query_timeout=6000000000;";
+ BasicResult result = ParserUtil.parseOracleType(sql);
+ Assert.assertEquals(SqlType.ALTER_SESSION, result.getSqlType());
+ Assert.assertEquals(SqlType.ALTER, result.getSqlType().getParentType());
+ Assert.assertEquals(DBObjectType.OTHERS, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_setSession() {
+ String sql = "set SESSION ob_query_timeout=6000000000;";
+ BasicResult result = ParserUtil.parseOracleType(sql);
+ Assert.assertEquals(SqlType.SET_SESSION, result.getSqlType());
+ Assert.assertEquals(SqlType.SET, result.getSqlType().getParentType());
+ Assert.assertEquals(DBObjectType.SESSION_VARIABLE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_comment_on_table() {
+ String sql = "comment on table t is 'abc'";
+ BasicResult result = ParserUtil.parseOracleType(sql);
+ Assert.assertEquals(SqlType.COMMENT_ON, result.getSqlType());
+ Assert.assertEquals(DBObjectType.TABLE, result.getDbObjectType());
+ }
+
+ @Test
+ public void test_oracle_comment_on_column() {
+ String sql = "comment on column t is 'abc'";
+ BasicResult result = ParserUtil.parseOracleType(sql);
+ Assert.assertEquals(SqlType.COMMENT_ON, result.getSqlType());
+ Assert.assertEquals(DBObjectType.COLUMN, result.getDbObjectType());
+ }
+
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/SqlParserTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/SqlParserTest.java
index 006996da61..07057790cc 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/SqlParserTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/parser/SqlParserTest.java
@@ -224,7 +224,7 @@ public void test_parse_mysql_fulltext_index_range() {
+ " `title` varchar(200) DEFAULT NULL,\n"
+ " `content` text DEFAULT NULL,\n"
+ " PRIMARY KEY (`id`), \n"
- + " FULLTEXT KEY `title` (`title`, `content`) CTXCAT(`title`, `content`) WITH PARSER 'TAOBAO_CHN' BLOCK_SIZE 16384\n"
+ + " FULLTEXT KEY `title` (`title`, `content`) CTXCAT(`title`, `content`) WITH PARSER TAOBAO_CHN BLOCK_SIZE 16384\n"
+ ") ";
ParseSqlResult result = SqlParser.parseMysql(sql);
Assert.assertEquals(1, result.getIndexes().size());
@@ -284,4 +284,79 @@ public void parseOracle_rollbackStmt_getSqlTypeSucceed() {
Assert.assertEquals(SqlType.ROLLBACK, actual.getSqlType());
}
+ @Test
+ public void parseOracle_commentOnTable_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("comment on table a is 'xxx'");
+ Assert.assertEquals(DBObjectType.TABLE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.COMMENT_ON, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_commentOnColumn_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("comment on column a is 'xxx'");
+ Assert.assertEquals(DBObjectType.COLUMN, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.COMMENT_ON, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_call_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("call proc()");
+ Assert.assertEquals(DBObjectType.PROCEDURE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.CALL, actual.getSqlType());
+ }
+
+
+ @Test
+ public void parseMysql_setSession_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseMysql("SET SESSION time_zone = '+00:00';");
+ Assert.assertEquals(DBObjectType.SESSION_VARIABLE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.SET_SESSION, actual.getSqlType());
+ Assert.assertEquals(SqlType.SET, actual.getSqlType().getParentType());
+ }
+
+ @Test
+ public void parseMysql_setGlobal_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseMysql("SET GLOBAL time_zone = '+00:00';");
+ Assert.assertEquals(DBObjectType.GLOBAL_VARIABLE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.SET, actual.getSqlType());
+ }
+
+ @Test
+ public void parseMysql_set_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseMysql("SET time_zone = '+00:00';");
+ Assert.assertEquals(DBObjectType.SYSTEM_VARIABLE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.SET, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_alterSession_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("alter SESSION set ob_query_timeout=6000000000;");
+ Assert.assertEquals(SqlType.ALTER_SESSION, actual.getSqlType());
+ Assert.assertEquals(SqlType.ALTER, actual.getSqlType().getParentType());
+ Assert.assertEquals(DBObjectType.OTHERS, actual.getDbObjectType());
+ }
+
+ @Test
+ public void parseOracle_setSession_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("set SESSION ob_query_timeout=6000000000;");
+ Assert.assertEquals(SqlType.SET_SESSION, actual.getSqlType());
+ Assert.assertEquals(SqlType.SET, actual.getSqlType().getParentType());
+ Assert.assertEquals(DBObjectType.SESSION_VARIABLE, actual.getDbObjectType());
+ }
+
+ @Test
+ public void parseOracle_setGlobal_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("SET GLOBAL time_zone = '+00:00';");
+ Assert.assertEquals(DBObjectType.GLOBAL_VARIABLE, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.SET, actual.getSqlType());
+ }
+
+ @Test
+ public void parseOracle_alterSystem_getSqlTypeSucceed() {
+ ParseSqlResult actual = SqlParser.parseOracle("alter system set time_zone = '+00:00';");
+ Assert.assertEquals(DBObjectType.OTHERS, actual.getDbObjectType());
+ Assert.assertEquals(SqlType.ALTER, actual.getSqlType());
+ }
+
+
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OracleSchemaAccessorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OracleSchemaAccessorTest.java
index 87f98a3e1c..4e867b4f1c 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OracleSchemaAccessorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/schema/OracleSchemaAccessorTest.java
@@ -137,6 +137,16 @@ public void listTableColumns_Success() {
Assert.assertEquals(13, columns.size());
}
+ @Test
+ public void listTableColumns_TestCreateExtendedStats_Success() {
+ String sql = "SELECT DBMS_STATS.CREATE_EXTENDED_STATS('" + getOracleSchema()
+ + "', 'TEST_EXTENDED_STATS_COL', '(X, Y)') FROM DUAL";
+ jdbcTemplate.execute(sql);
+ List columns =
+ accessor.listTableColumns(getOracleSchema(), "TEST_EXTENDED_STATS_COL");
+ Assert.assertEquals(3, columns.size());
+ }
+
@Test
public void listTableConstraint_TestPrimaryKey_Success() {
List constraintListList =
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBMySQLStatsAccessorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBMySQLStatsAccessorTest.java
index 3a52ee29f8..1ea11da4fd 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBMySQLStatsAccessorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBMySQLStatsAccessorTest.java
@@ -45,8 +45,9 @@ public void currentSession() {
@Test
public void listAllSessions() {
DBStatsAccessor accessor = new OBMySQLStatsAccessor(new JdbcTemplate(getOBMySQLDataSource()));
- List session = accessor.listAllSessions();
- Assert.assertTrue(session.size() > 0);
+ List sessions = accessor.listAllSessions();
+ Assert.assertTrue(sessions.size() > 0);
+ sessions.stream().forEach(s -> Assert.assertNotNull(s.getSvrIp()));
}
}
diff --git a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBOracleNoLessThan2270StatsAccessorTest.java b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBOracleNoLessThan2270StatsAccessorTest.java
index 82feec931a..740110649e 100644
--- a/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBOracleNoLessThan2270StatsAccessorTest.java
+++ b/libs/db-browser/src/test/java/com/oceanbase/tools/dbbrowser/stats/OBOracleNoLessThan2270StatsAccessorTest.java
@@ -50,5 +50,6 @@ public void listAllSessions_Succeed() {
DBStatsAccessor accessor = new OBOracleNoLessThan2270StatsAccessor(new JdbcTemplate(getOBOracleDataSource()));
List sessions = accessor.listAllSessions();
Assert.assertTrue(sessions.size() > 0);
+ sessions.stream().forEach(s -> Assert.assertNotNull(s.getSvrIp()));
}
}
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 a492143ad2..abc60f8e79 100644
--- a/libs/db-browser/src/test/resources/table/oracle/drop.sql
+++ b/libs/db-browser/src/test/resources/table/oracle/drop.sql
@@ -26,6 +26,8 @@ call DROPIFEXISTS_TABLE('TEST_INDEX_TYPE')
call DROPIFEXISTS_TABLE('TEST_VIEW_TABLE')
/
call DROPIFEXISTS_TABLE('PART_HASH_TEST')
+/
+call DROPIFEXISTS_TABLE('TEST_EXTENDED_STATS_COL')
diff --git a/libs/db-browser/src/test/resources/table/oracle/testTableColumnDDL.sql b/libs/db-browser/src/test/resources/table/oracle/testTableColumnDDL.sql
index 228f8c78b9..5fa93ab5ef 100644
--- a/libs/db-browser/src/test/resources/table/oracle/testTableColumnDDL.sql
+++ b/libs/db-browser/src/test/resources/table/oracle/testTableColumnDDL.sql
@@ -13,4 +13,10 @@ create table TEST_COL_DATA_TYPE(
col12 interval year to month,
col13 interval day to second
)
+/
+
+CREATE TABLE TEST_EXTENDED_STATS_COL(
+ "X" NUMBER(*,0),
+ "Y" NUMBER(*,0)
+)
/
\ No newline at end of file
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 96502b8838..6526049e79 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
@@ -15,18 +15,18 @@
*/
package com.oceanbase.tools.sqlparser.adapter.mysql;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Add_external_table_partition_actionsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_column_behaviorContext;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_column_group_optionContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_column_group_actionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_column_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_constraint_optionContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_external_table_actionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_index_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_partition_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_table_actionContext;
@@ -35,6 +35,7 @@
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.OBParserBaseVisitor;
+import com.oceanbase.tools.sqlparser.statement.Expression;
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.ColumnGroupElement;
@@ -63,10 +64,14 @@ public MySQLAlterTableActionFactory(@NonNull Alter_table_actionContext alterTabl
this.parserRuleContext = alterTableActionContext;
}
- public MySQLAlterTableActionFactory(@NonNull Alter_column_group_optionContext alterTableActionContext) {
+ public MySQLAlterTableActionFactory(@NonNull Alter_column_group_actionContext alterTableActionContext) {
this.parserRuleContext = alterTableActionContext;
}
+ public MySQLAlterTableActionFactory(@NonNull Alter_external_table_actionContext alterExternalTableActionContext) {
+ this.parserRuleContext = alterExternalTableActionContext;
+ }
+
@Override
public AlterTableAction generate() {
return visit(this.parserRuleContext);
@@ -95,6 +100,20 @@ public AlterTableAction visitAlter_table_action(Alter_table_actionContext ctx) {
return visitChildren(ctx);
}
+ @Override
+ public AlterTableAction visitAlter_external_table_action(Alter_external_table_actionContext ctx) {
+ AlterTableAction action = new AlterTableAction(ctx);
+ action.setExternalTableLocation(ctx.STRING_VALUE().getText());
+ if (ctx.DROP() != null && ctx.PARTITION() != null) {
+ action.setDropExternalTablePartition(true);
+ } else if (ctx.ADD() != null && ctx.PARTITION() != null) {
+ Map externalTablePartition = new HashMap<>();
+ visitAddExternalTablePartitionActions(externalTablePartition, ctx.add_external_table_partition_actions());
+ action.setAddExternalTablePartition(externalTablePartition);
+ }
+ return action;
+ }
+
@Override
public AlterTableAction visitAlter_column_option(Alter_column_optionContext ctx) {
AlterTableAction alterTableAction = new AlterTableAction(ctx);
@@ -108,6 +127,10 @@ public AlterTableAction visitAlter_column_option(Alter_column_optionContext ctx)
.collect(Collectors.toList());
}
alterTableAction.setAddColumns(addColumns);
+ if (ctx.lob_storage_clause() != null) {
+ alterTableAction.setLobStorageOption(
+ MySQLTableOptionsFactory.getLobStorageOption(ctx.lob_storage_clause()));
+ }
} else if (ctx.DROP() != null) {
String option = null;
if (ctx.CASCADE() != null) {
@@ -131,6 +154,8 @@ public AlterTableAction visitAlter_column_option(Alter_column_optionContext ctx)
AlterColumnBehavior behavior = new AlterColumnBehavior(aCtx);
if (aCtx.signed_literal() != null) {
behavior.setDefaultValue(MySQLTableElementFactory.getSignedLiteral(aCtx.signed_literal()));
+ } else if (aCtx.expr() != null) {
+ behavior.setDefaultValue(new MySQLExpressionFactory(aCtx.expr()).generate());
}
alterTableAction.alterColumnBehavior(colRef, behavior);
} else if (ctx.RENAME() != null) {
@@ -211,6 +236,9 @@ public AlterTableAction visitAlter_partition_option(Alter_partition_optionContex
getPartitionElements(ctx.opt_partition_range_or_list()));
} else if (ctx.REMOVE() != null && ctx.PARTITIONING() != null) {
alterTableAction.setRemovePartitioning(true);
+ } else if (ctx.EXCHANGE() != null && ctx.PARTITION() != null) {
+ alterTableAction.setExchangePartition(ctx.relation_name().getText(),
+ MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor()));
}
return alterTableAction;
}
@@ -241,7 +269,7 @@ public AlterTableAction visitAlter_constraint_option(Alter_constraint_optionCont
}
@Override
- public AlterTableAction visitAlter_column_group_option(Alter_column_group_optionContext ctx) {
+ public AlterTableAction visitAlter_column_group_action(Alter_column_group_actionContext ctx) {
AlterTableAction action = new AlterTableAction(ctx);
List columnGroupElements = ctx.column_group_list().column_group_element()
.stream().map(c -> new MySQLColumnGroupElementFactory(c).generate()).collect(Collectors.toList());
@@ -273,4 +301,15 @@ private List getPartitionElements(Opt_partition_range_or_listC
.map(c -> new MySQLPartitionElementFactory(c).generate()).collect(Collectors.toList());
}
+ private void visitAddExternalTablePartitionActions(Map externalTablePartition,
+ Add_external_table_partition_actionsContext context) {
+ if (context == null) {
+ return;
+ }
+ Expression value = new MySQLExpressionFactory()
+ .visit(context.add_external_table_partition_action().expr_const());
+ externalTablePartition.put(context.add_external_table_partition_action().column_name().getText(), value);
+ visitAddExternalTablePartitionActions(externalTablePartition, context.add_external_table_partition_actions());
+ }
+
}
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 415eede3e2..1f0d6cd107 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
@@ -22,7 +22,8 @@
import org.antlr.v4.runtime.ParserRuleContext;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
-import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_column_group_optionContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_column_group_actionContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_external_table_actionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_table_actionsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_table_stmtContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
@@ -58,8 +59,10 @@ public AlterTable visitAlter_table_stmt(Alter_table_stmtContext ctx) {
List actions = null;
if (ctx.alter_table_actions() != null) {
actions = getAlterTableActions(ctx.alter_table_actions());
- } else if (ctx.alter_column_group_option() != null) {
- actions = getAlterTableActions(ctx.alter_column_group_option());
+ } else if (ctx.alter_column_group_action() != null) {
+ actions = getAlterTableActions(ctx.alter_column_group_action());
+ } else if (ctx.alter_external_table_action() != null) {
+ actions = getAlterTableActions(ctx.alter_external_table_action());
}
AlterTable alterTable = new AlterTable(ctx, factor, actions);
if (ctx.EXTERNAL() != null) {
@@ -83,7 +86,11 @@ private List getAlterTableActions(Alter_table_actionsContext c
return actions;
}
- private List getAlterTableActions(Alter_column_group_optionContext context) {
+ private List getAlterTableActions(Alter_column_group_actionContext context) {
+ return Collections.singletonList(new MySQLAlterTableActionFactory(context).generate());
+ }
+
+ private List getAlterTableActions(Alter_external_table_actionContext context) {
return Collections.singletonList(new MySQLAlterTableActionFactory(context).generate());
}
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 35bb5c5e52..4f23429d73 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
@@ -69,8 +69,7 @@ public CreateTable visitCreate_table_like_stmt(Create_table_like_stmtContext ctx
createTable.setIfNotExists(true);
}
createTable.setUserVariable(factor.getUserVariable());
- RelationFactor likeFactor = MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor(1));
- createTable.setLikeTable(likeFactor);
+ createTable.setLikeTable(MySQLFromReferenceFactory.getRelationFactor(ctx.relation_factor(1)));
return createTable;
}
@@ -86,7 +85,6 @@ public CreateTable visitCreate_table_stmt(Create_table_stmtContext ctx) {
createTable.setTemporary(true);
}
}
-
if (ctx.IF() != null && ctx.not() != null && ctx.EXISTS() != null) {
createTable.setIfNotExists(true);
}
@@ -112,6 +110,10 @@ public CreateTable visitCreate_table_stmt(Create_table_stmtContext ctx) {
.map(c -> new MySQLColumnGroupElementFactory(c).generate()).collect(Collectors.toList());
createTable.setColumnGroupElements(columnGroupElements);
}
+ if (ctx.ignore_or_replace() != null) {
+ createTable.setIgnore(ctx.ignore_or_replace().IGNORE() != null);
+ createTable.setReplace(ctx.ignore_or_replace().REPLACE() != null);
+ }
return createTable;
}
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 f46fb7cb16..8ece4121bd 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
@@ -90,7 +90,7 @@ public DataType visitData_type(Data_typeContext ctx) {
if (ctx.STRING_VALUE() != null) {
return new GeneralDataType(ctx, ctx.STRING_VALUE().getText(), null);
} else if (ctx.data_type() != null) {
- return new ArrayType(visitData_type(ctx.data_type()));
+ return new ArrayType(ctx, visitData_type(ctx.data_type()));
}
return visitChildren(ctx);
}
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 0f072f42ea..d9d1d60b1b 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
@@ -45,6 +45,7 @@
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_query_exprContext;
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;
@@ -56,7 +57,11 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Mock_jt_on_error_on_emptyContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Mvt_paramContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_emptyContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_empty_queryContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_errorContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_error_queryContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.On_mismatch_queryContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Opt_response_queryContext;
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;
@@ -68,8 +73,10 @@
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Ttl_exprContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Utc_time_funcContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Utc_timestamp_funcContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Vector_distance_exprContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Win_fun_first_last_paramsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Window_functionContext;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Wrapper_optsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Ws_nweightsContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParserBaseVisitor;
import com.oceanbase.tools.sqlparser.statement.Expression;
@@ -79,24 +86,7 @@
import com.oceanbase.tools.sqlparser.statement.common.CharacterType;
import com.oceanbase.tools.sqlparser.statement.common.GeneralDataType;
import com.oceanbase.tools.sqlparser.statement.common.WindowSpec;
-import com.oceanbase.tools.sqlparser.statement.expression.ArrayExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.BoolValue;
-import com.oceanbase.tools.sqlparser.statement.expression.CaseWhen;
-import com.oceanbase.tools.sqlparser.statement.expression.CollectionExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
-import com.oceanbase.tools.sqlparser.statement.expression.CompoundExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
-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.FunctionCall;
-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.*;
import lombok.NonNull;
@@ -223,6 +213,9 @@ public Expression visitBool_pri(Bool_priContext ctx) {
} else if (ctx.bool_pri() != null && ctx.any_expr() != null) {
left = visit(ctx.bool_pri());
right = visit(ctx.any_expr());
+ } else if (ctx.bool_pri() != null && ctx.select_with_parens() != null) {
+ left = visit(ctx.bool_pri());
+ right = new MySQLSelectBodyFactory(ctx.select_with_parens()).generate();
}
if (left == null || right == null || operator == null) {
throw new IllegalStateException("Unable to build expression, some syntax modules are missing");
@@ -389,6 +382,9 @@ public Expression visitSimple_expr(Simple_exprContext ctx) {
}
FullTextSearch f = new FullTextSearch(ctx, params, ctx.STRING_VALUE().getText());
f.setSearchMode(searchMode);
+ if (ctx.WITH() != null && ctx.QUERY() != null && ctx.EXPANSION() != null) {
+ f.setWithQueryExpansion(true);
+ }
return f;
} else if (ctx.func_expr() != null) {
return visit(ctx.func_expr());
@@ -477,6 +473,8 @@ public Expression visitSimple_func_expr(Simple_func_exprContext ctx) {
p.addOption(new ConstExpression(e.STRING_VALUE()));
return p;
}).collect(Collectors.toList()));
+ } else if (ctx.INTNUM() != null) {
+ params.add(new ExpressionParam(new ConstExpression(ctx.INTNUM())));
} else if (ctx.column_ref() != null) {
params.add(new ExpressionParam(new MySQLColumnRefFactory(ctx.column_ref()).generate()));
if (CollectionUtils.isNotEmpty(ctx.mvt_param())) {
@@ -533,6 +531,9 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
} else if (ctx.CAST() != null) {
FunctionParam p = wrap(ctx.expr());
p.addOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
+ if (ctx.ARRAY() != null) {
+ p.addOption(new ConstExpression(ctx.ARRAY()));
+ }
return new FunctionCall(ctx, ctx.CAST().getText(), Collections.singletonList(p));
} else if (ctx.CONVERT() != null) {
FunctionParam p = wrap(ctx.expr());
@@ -635,36 +636,11 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
}
return fCall;
} else if (ctx.json_value_expr() != null) {
- Json_value_exprContext jsonValue = ctx.json_value_expr();
- List params = new ArrayList<>();
- params.add(new ExpressionParam(visit(jsonValue.simple_expr())));
- params.add(new ExpressionParam(visit(jsonValue.complex_string_literal())));
- FunctionCall fCall = new FunctionCall(ctx, jsonValue.JSON_VALUE().getText(), params);
- 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;
+ return visit(ctx.json_value_expr());
+ } else if (ctx.json_query_expr() != null) {
+ return visit(ctx.json_query_expr());
+ } else if (ctx.vector_distance_expr() != null) {
+ return visit(ctx.vector_distance_expr());
}
String funcName = null;
List params = new ArrayList<>();
@@ -711,10 +687,6 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
} else if (ctx.sys_interval_func().CHECK() != null) {
funcName = ctx.sys_interval_func().CHECK().getText();
}
- } else if (ctx.vector_distance_expr() != null) {
- params = ctx.vector_distance_expr().expr()
- .stream().map(this::wrap).collect(Collectors.toList());
- funcName = ctx.vector_distance_expr().VECTOR_DISTANCE().getText();
}
if (funcName == null) {
throw new IllegalStateException("Missing function name");
@@ -722,11 +694,93 @@ public Expression visitComplex_func_expr(Complex_func_exprContext ctx) {
return new FunctionCall(ctx, funcName, params);
}
+ @Override
+ public Expression visitJson_query_expr(Json_query_exprContext ctx) {
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(visit(ctx.simple_expr())));
+ params.add(new ExpressionParam(visit(ctx.complex_string_literal())));
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_QUERY().getText(), params);
+ if (ctx.cast_data_type() != null) {
+ fCall.addOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
+ }
+ if (ctx.json_query_opt() != null) {
+ JsonOption jsonOpt = new JsonOption(ctx.json_query_opt());
+ fCall.addOption(jsonOpt);
+ if (ctx.json_query_opt().TRUNCATE() != null) {
+ jsonOpt.setTruncate(true);
+ }
+ if (ctx.json_query_opt().scalars_opt() != null) {
+ if (ctx.json_query_opt().scalars_opt().ALLOW() != null) {
+ jsonOpt.setScalarsMode(JsonOption.ScalarsMode.ALLOW_SCALARS);
+ } else {
+ jsonOpt.setScalarsMode(JsonOption.ScalarsMode.DISALLOW_SCALARS);
+ }
+ }
+ if (ctx.json_query_opt().PRETTY() != null) {
+ jsonOpt.setPretty(true);
+ }
+ if (ctx.json_query_opt().ASCII() != null) {
+ jsonOpt.setAscii(true);
+ }
+ setWrapperMode(jsonOpt, ctx.json_query_opt().wrapper_opts());
+ if (ctx.json_query_opt().ASIS() != null) {
+ jsonOpt.setAsis(true);
+ }
+ if (ctx.json_query_opt().json_query_on_opt() != null) {
+ JsonOnOption jsonOnOption = new JsonOnOption(ctx.json_query_opt().json_query_on_opt());
+ jsonOpt.setOnOption(jsonOnOption);
+ setOnError(jsonOnOption, ctx.json_query_opt().json_query_on_opt().on_error_query());
+ setOnEmpty(jsonOnOption, ctx.json_query_opt().json_query_on_opt().on_empty_query());
+ setOnMismatch(jsonOnOption, ctx.json_query_opt().json_query_on_opt().on_mismatch_query());
+ }
+ if (ctx.json_query_opt().MULTIVALUE() != null) {
+ jsonOpt.setMultiValue(true);
+ }
+ }
+ return fCall;
+ }
+
+ @Override
+ public Expression visitVector_distance_expr(Vector_distance_exprContext ctx) {
+ List params = ctx.expr().stream().map(this::wrap).collect(Collectors.toList());
+ if (ctx.vector_distance_metric() != null) {
+ params.add(new ExpressionParam(new ConstExpression(ctx.vector_distance_metric())));
+ }
+ return new FunctionCall(ctx, ctx.VECTOR_DISTANCE().getText(), params);
+ }
+
+ @Override
+ public Expression visitJson_value_expr(Json_value_exprContext ctx) {
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(visit(ctx.simple_expr())));
+ params.add(new ExpressionParam(visit(ctx.complex_string_literal())));
+ FunctionCall fCall = new FunctionCall(ctx, ctx.JSON_VALUE().getText(), params);
+ if (ctx.cast_data_type() != null) {
+ fCall.addOption(new MySQLDataTypeFactory(ctx.cast_data_type()).generate());
+ }
+ if (ctx.json_value_opt() != null) {
+ JsonOption jsonOpt = new JsonOption(ctx.json_value_opt());
+ fCall.addOption(jsonOpt);
+ if (ctx.json_value_opt().TRUNCATE() != null) {
+ jsonOpt.setTruncate(true);
+ }
+ if (ctx.json_value_opt().ASCII() != null) {
+ jsonOpt.setAscii(true);
+ }
+ if (ctx.json_value_opt().json_value_on_opt() != null) {
+ JsonOnOption jsonOnOption = new JsonOnOption(ctx.json_value_opt().json_value_on_opt());
+ jsonOpt.setOnOption(jsonOnOption);
+ setOnError(jsonOnOption, ctx.json_value_opt().json_value_on_opt().on_error());
+ setOnEmpty(jsonOnOption, ctx.json_value_opt().json_value_on_opt().on_empty());
+ }
+ }
+ return fCall;
+ }
+
@Override
public Expression visitTtl_expr(Ttl_exprContext ctx) {
Expression right = new IntervalExpression(ctx.INTERVAL(), ctx.ttl_unit(),
new ConstExpression(ctx.INTNUM()), ctx.ttl_unit().getText());
-
return new CompoundExpression(ctx,
new MySQLColumnRefFactory(ctx.column_definition_ref()).generate(), right, Operator.ADD);
}
@@ -881,7 +935,7 @@ 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()));
+ fCall.addOption(getJsonOption(ctx.mock_jt_on_error_on_empty()));
ctx.jt_column_list().json_table_column_def().forEach(c -> fCall.addOption(visitJsonTableColumnDef(c)));
return fCall;
}
@@ -894,7 +948,12 @@ public Expression visitAny_expr(Any_exprContext ctx) {
return visit(ctx.expr_list());
}
- private JsonOnOption getJsonOnOption(Mock_jt_on_error_on_emptyContext ctx) {
+ @Override
+ public Expression visitOpt_response_query(Opt_response_queryContext ctx) {
+ return ctx.NULLX() != null ? new ConstExpression(ctx.NULLX()) : new ConstExpression(ctx.ERROR_P());
+ }
+
+ private JsonOnOption getJsonOption(Mock_jt_on_error_on_emptyContext ctx) {
return null;
}
@@ -924,6 +983,53 @@ private void setOnError(JsonOnOption jsonOnOption, On_errorContext ctx) {
jsonOnOption.setOnError(visit(ctx.json_on_response()));
}
+ private void setOnEmpty(JsonOnOption jsonOnOption, On_empty_queryContext ctx) {
+ if (ctx == null) {
+ return;
+ }
+ if (ctx.opt_response_query() != null) {
+ jsonOnOption.setOnEmpty(visit(ctx.opt_response_query()));
+ } else if (ctx.EMPTY().size() == 2) {
+ TerminalNode endNode = ctx.EMPTY(0);
+ if (ctx.ARRAY() != null) {
+ endNode = ctx.ARRAY();
+ } else if (ctx.OBJECT() != null) {
+ endNode = ctx.OBJECT();
+ }
+ jsonOnOption.setOnEmpty(new ConstExpression(ctx.EMPTY(0), endNode));
+ }
+ }
+
+ private void setOnError(JsonOnOption jsonOnOption, On_error_queryContext ctx) {
+ if (ctx == null) {
+ return;
+ }
+ if (ctx.opt_response_query() != null) {
+ jsonOnOption.setOnError(visit(ctx.opt_response_query()));
+ } else if (ctx.EMPTY() != null) {
+ TerminalNode endNode = ctx.EMPTY();
+ if (ctx.ARRAY() != null) {
+ endNode = ctx.ARRAY();
+ } else if (ctx.OBJECT() != null) {
+ endNode = ctx.OBJECT();
+ }
+ jsonOnOption.setOnError(new ConstExpression(ctx.EMPTY(), endNode));
+ }
+ }
+
+ private void setOnMismatch(JsonOnOption jsonOnOption, On_mismatch_queryContext ctx) {
+ if (ctx == null) {
+ return;
+ }
+ Expression opt;
+ if (ctx.DOT() != null) {
+ opt = new ConstExpression(ctx.DOT());
+ } else {
+ opt = visit(ctx.opt_response_query());
+ }
+ jsonOnOption.setOnMismatches(Collections.singletonList(new JsonOnOption.OnMismatch(ctx, opt, null)));
+ }
+
private FunctionParam visitJsonTableColumnDef(Json_table_column_defContext ctx) {
if (ctx.json_table_ordinality_column_def() != null) {
return visitJsonTableOrdinalityColumnDef(ctx.json_table_ordinality_column_def());
@@ -951,7 +1057,7 @@ private FunctionParam visitJsonTableExistsColumnDef(Json_table_exists_column_def
}
param.addOption(new ConstExpression(ctx.EXISTS()));
param.addOption(visit(ctx.literal()));
- param.addOption(getJsonOnOption(ctx.mock_jt_on_error_on_empty()));
+ param.addOption(getJsonOption(ctx.mock_jt_on_error_on_empty()));
return param;
}
@@ -963,7 +1069,11 @@ private FunctionParam visitJsonTableValueColumnDef(Json_table_value_column_defCo
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()));
+ if (ctx.opt_value_on_empty_or_error_or_mismatch() != null) {
+ JsonOption jsonOpt = new JsonOption(ctx.opt_value_on_empty_or_error_or_mismatch());
+ param.addOption(jsonOpt);
+ jsonOpt.setOnOption(getJsonOnOption(ctx.opt_value_on_empty_or_error_or_mismatch()));
+ }
return param;
}
@@ -1004,4 +1114,35 @@ private ConstExpression getAggregator(Complex_func_exprContext ctx) {
return null;
}
+ private void setWrapperMode(JsonOption c, Wrapper_optsContext ctx) {
+ if (ctx == null) {
+ return;
+ }
+ if (ctx.WITH() != null) {
+ if (ctx.ARRAY() != null) {
+ if (ctx.CONDITIONAL() != null) {
+ c.setWrapperMode(JsonOption.WrapperMode.WITH_CONDITIONAL_ARRAY_WRAPPER);
+ } else if (ctx.UNCONDITIONAL() != null) {
+ c.setWrapperMode(JsonOption.WrapperMode.WITH_UNCONDITIONAL_ARRAY_WRAPPER);
+ } else {
+ c.setWrapperMode(JsonOption.WrapperMode.WITH_ARRAY_WRAPPER);
+ }
+ } else {
+ if (ctx.CONDITIONAL() != null) {
+ c.setWrapperMode(JsonOption.WrapperMode.WITH_CONDITIONAL_WRAPPER);
+ } else if (ctx.UNCONDITIONAL() != null) {
+ c.setWrapperMode(JsonOption.WrapperMode.WITH_UNCONDITIONAL_WRAPPER);
+ } else {
+ c.setWrapperMode(JsonOption.WrapperMode.WITH_WRAPPER);
+ }
+ }
+ } else {
+ if (ctx.ARRAY() != null) {
+ c.setWrapperMode(JsonOption.WrapperMode.WITHOUT_ARRAY_WRAPPER);
+ } else {
+ c.setWrapperMode(JsonOption.WrapperMode.WITHOUT_WRAPPER);
+ }
+ }
+ }
+
}
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 75b330b7ca..2701e02480 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
@@ -15,9 +15,7 @@
*/
package com.oceanbase.tools.sqlparser.adapter.mysql;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
@@ -108,7 +106,11 @@ public FromReference visitTable_factor(Table_factorContext ctx) {
if (ctx.tbl_name() != null) {
return visit(ctx.tbl_name());
} else if (ctx.table_subquery() != null) {
- return visit(ctx.table_subquery());
+ ExpressionReference reference = (ExpressionReference) visit(ctx.table_subquery());
+ if (ctx.LATERAL() != null) {
+ reference.setLateral(true);
+ }
+ return reference;
} else if (ctx.table_reference() != null) {
FromReference from = visit(ctx.table_reference());
if (ctx.LeftBrace() == null || ctx.OJ() == null || ctx.RightBrace() == null) {
@@ -123,6 +125,9 @@ public FromReference visitTable_factor(Table_factorContext ctx) {
}
StatementFactory factory = new MySQLSelectBodyFactory(ctx.select_with_parens());
ExpressionReference reference = new ExpressionReference(ctx, factory.generate(), null);
+ if (ctx.LATERAL() != null) {
+ reference.setLateral(true);
+ }
if (ctx.use_flashback() != null) {
reference.setFlashbackUsage(visitFlashbackUsage(ctx.use_flashback()));
}
@@ -193,7 +198,7 @@ public FromReference visitTbl_name(Tbl_nameContext ctx) {
}
NameReference nameReference = new NameReference(ctx, factor.getSchema(), factor.getRelation(), alias);
if (ctx.use_partition() != null) {
- nameReference.setPartitionUsage(visitPartitonUsage(ctx.use_partition()));
+ nameReference.setPartitionUsage(visitPartitionUsage(ctx.use_partition()));
}
if (ctx.use_flashback() != null) {
nameReference.setFlashbackUsage(visitFlashbackUsage(ctx.use_flashback()));
@@ -296,10 +301,17 @@ private FlashbackUsage visitFlashbackUsage(Use_flashbackContext ctx) {
return new FlashbackUsage(ctx, FlashBackType.AS_OF_SNAPSHOT, factory.generate());
}
- public static PartitionUsage visitPartitonUsage(Use_partitionContext usePartition) {
- List nameList = new ArrayList<>();
- visitNameList(usePartition.name_list(), nameList);
- return new PartitionUsage(usePartition, PartitionType.PARTITION, nameList);
+ public static PartitionUsage visitPartitionUsage(Use_partitionContext usePartition) {
+ if (usePartition.name_list() != null) {
+ List nameList = new ArrayList<>();
+ visitNameList(usePartition.name_list(), nameList);
+ return new PartitionUsage(usePartition, PartitionType.PARTITION, nameList);
+ }
+ Map externalTablePartition = new HashMap<>();
+ usePartition.external_table_partitions().external_table_partition()
+ .forEach(ctx -> externalTablePartition.put(ctx.relation_name().getText(),
+ new MySQLExpressionFactory().visit(ctx.expr_const())));
+ return new PartitionUsage(usePartition, PartitionType.PARTITION, externalTablePartition);
}
private static void visitNameList(Name_listContext ctx, List nameList) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLIndexOptionsFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLIndexOptionsFactory.java
index bcc5217006..1ba44cf805 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLIndexOptionsFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLIndexOptionsFactory.java
@@ -15,7 +15,9 @@
*/
package com.oceanbase.tools.sqlparser.adapter.mysql;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
@@ -61,6 +63,8 @@ public IndexOptions visitOpt_index_options(Opt_index_optionsContext ctx) {
indexOptions.setGlobal(false);
} else if (option.BLOCK_SIZE() != null) {
indexOptions.setBlockSize(getInteger(option));
+ } else if (option.KEY_BLOCK_SIZE() != null) {
+ indexOptions.setKeyBlockSize(getInteger(option));
} else if (option.DATA_TABLE_ID() != null) {
indexOptions.setDataTableId(getInteger(option));
} else if (option.INDEX_TABLE_ID() != null) {
@@ -76,9 +80,14 @@ public IndexOptions visitOpt_index_options(Opt_index_optionsContext ctx) {
} else if (option.CTXCAT() != null) {
indexOptions.setCtxcat(getReference(option));
} else if (option.WITH() != null && option.PARSER() != null) {
- indexOptions.setWithParser(option.STRING_VALUE().getText());
+ indexOptions.setWithParser(option.relation_name().getText());
} else if (option.WITH() != null && option.ROWID() != null) {
indexOptions.setWithRowId(true);
+ } else if (option.WITH() != null && option.vec_index_params() != null) {
+ Map params = new HashMap<>();
+ option.vec_index_params().vec_index_param()
+ .forEach(i -> params.put(i.relation_name().getText(), i.vec_index_param_value().getText()));
+ indexOptions.setVectorIndexParams(params);
} else if (option.index_using_algorithm() != null) {
indexOptions.merge(visit(option.index_using_algorithm()));
} else if (option.visibility_option() != null) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLInsertFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLInsertFactory.java
index 597e97f07d..4c5b491fe4 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLInsertFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/mysql/MySQLInsertFactory.java
@@ -67,6 +67,14 @@ public Insert visitInsert_stmt(Insert_stmtContext ctx) {
if (ctx.IGNORE() != null) {
insert.setIgnore(true);
}
+ if (ctx.HIGH_PRIORITY() != null) {
+ insert.setHighPriority(true);
+ } else if (ctx.LOW_PRIORITY() != null) {
+ insert.setLowPriority(true);
+ }
+ if (ctx.OVERWRITE() != null) {
+ insert.setOverwrite(true);
+ }
if (ctx.update_asgn_list() != null) {
insert.setOnDuplicateKeyUpdateColumns(getSetColumns(ctx.update_asgn_list()));
}
@@ -79,7 +87,7 @@ public Insert visitSingle_table_insert(Single_table_insertContext ctx) {
.getRelationFactor(ctx.dml_table_name().relation_factor()));
if (ctx.dml_table_name().use_partition() != null) {
insertTable.setPartitionUsage(MySQLFromReferenceFactory
- .visitPartitonUsage(ctx.dml_table_name().use_partition()));
+ .visitPartitionUsage(ctx.dml_table_name().use_partition()));
}
if (ctx.column_list() != null) {
insertTable.setColumns(ctx.column_list().column_definition_ref().stream()
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 9b4f351fe0..865ad6c677 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
@@ -231,12 +231,13 @@ private RelationType getRelationType(Set_typeContext setType) {
public SelectBody visitSimple_select_with_order_and_limit(Simple_select_with_order_and_limitContext ctx) {
SelectBody select = new SelectBody(ctx, visit(ctx.simple_select()));
if (ctx.order_by() != null) {
- StatementFactory factory = new MySQLOrderByFactory(ctx.order_by());
- select.setOrderBy(factory.generate());
+ select.setOrderBy(new MySQLOrderByFactory(ctx.order_by()).generate());
+ }
+ if (ctx.opt_approx() != null) {
+ select.setApproximate(true);
}
if (ctx.limit_clause() != null) {
- StatementFactory factory = new MySQLLimitFactory(ctx.limit_clause());
- select.setLimit(factory.generate());
+ select.setLimit(new MySQLLimitFactory(ctx.limit_clause()).generate());
}
return select;
}
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 17f63470df..3460a75e3f 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
@@ -243,6 +243,12 @@ public TableElement visitColumn_definition(Column_definitionContext ctx) {
ColumnAttributes attributes = visitGeneratedColumnAttributeList(ctx.opt_generated_column_attribute_list());
definition.setColumnAttributes(attributes);
}
+ if (ctx.references_clause() != null) {
+ definition.setForeignReference(visitForeignReference(ctx.references_clause()));
+ }
+ if (ctx.SERIAL() != null) {
+ definition.setSerial(true);
+ }
if (ctx.FIRST() != null) {
definition.setLocation(new Location(ctx.FIRST().getText(), null));
} else if (ctx.BEFORE() != null) {
@@ -422,8 +428,14 @@ private ColumnAttributes visitColumnAttribute(Column_attributeContext ctx) {
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) {
- Expression expr = visitNowOrSignedLiteral(ctx.now_or_signed_literal());
+ } else if ((ctx.DEFAULT() != null || ctx.ORIG_DEFAULT() != null)
+ && (ctx.now_or_signed_literal() != null || ctx.expr() != null)) {
+ Expression expr = null;
+ if (ctx.now_or_signed_literal() != null) {
+ expr = visitNowOrSignedLiteral(ctx.now_or_signed_literal());
+ } else if (ctx.expr() != null) {
+ expr = new MySQLExpressionFactory(ctx.expr()).generate();
+ }
if (ctx.DEFAULT() != null) {
attributes.setDefaultValue(expr);
} else {
@@ -450,6 +462,16 @@ private ColumnAttributes visitColumnAttribute(Column_attributeContext ctx) {
skipIndexTypes.add(ctx.skip_index_type().getText());
}
attributes.setSkipIndexTypes(skipIndexTypes);
+ } else if (ctx.lob_chunk_size() != null) {
+ if (ctx.lob_chunk_size().STRING_VALUE() != null) {
+ attributes.setLobChunkSize(ctx.lob_chunk_size().STRING_VALUE().getText());
+ } else if (ctx.lob_chunk_size().INTNUM() != null) {
+ attributes.setLobChunkSize(ctx.lob_chunk_size().INTNUM().getText());
+ }
+ } else if (ctx.COLUMN_FORMAT() != null) {
+ attributes.setColumnFormat(ctx.col_attri_value.getText());
+ } else if (ctx.STORAGE() != null) {
+ attributes.setStorage(ctx.col_attri_value.getText());
}
return attributes;
}
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 325b9da697..863599ddeb 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,7 @@
package com.oceanbase.tools.sqlparser.adapter.mysql;
import java.math.BigDecimal;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -24,12 +25,14 @@
import org.antlr.v4.runtime.ParserRuleContext;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.obmysql.OBParser.Lob_storage_clauseContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Parallel_optionContext;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Table_optionContext;
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.common.mysql.LobStorageOption;
import com.oceanbase.tools.sqlparser.statement.createtable.TableOptions;
import com.oceanbase.tools.sqlparser.statement.expression.BoolValue;
import com.oceanbase.tools.sqlparser.statement.expression.CollectionExpression;
@@ -172,6 +175,8 @@ public TableOptions visitTable_option(Table_optionContext ctx) {
.map(ex -> new MySQLExpressionFactory(ex).generate())
.collect(Collectors.toList());
value = new CollectionExpression(e.expr_list(), exprs);
+ } else if (e.compression_name() != null) {
+ value = new ConstExpression(e.compression_name());
}
formatMap.put(e.format_key.getText().toUpperCase(), value);
});
@@ -187,6 +192,60 @@ public TableOptions visitTable_option(Table_optionContext ctx) {
target.setDefaultLobInRowThreshold(Integer.valueOf(ctx.INTNUM().getText()));
} else if (ctx.LOB_INROW_THRESHOLD() != null) {
target.setLobInRowThreshold(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.KEY_BLOCK_SIZE() != null) {
+ target.setKeyBlockSize(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.AUTO_INCREMENT_CACHE_SIZE() != null) {
+ target.setAutoIncrementCacheSize(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.PARTITION_TYPE() != null) {
+ target.setPartitionType(ctx.USER_SPECIFIED().getText());
+ } else if (ctx.PROPERTIES() != null) {
+ Map externalProperties = new HashMap<>();
+ ctx.external_properties_list().external_properties().forEach(e -> {
+ externalProperties.put(e.external_properties_key().getText(), e.STRING_VALUE().getText());
+ });
+ target.setExternalProperties(externalProperties);
+ } else if (ctx.lob_storage_clause() != null) {
+ target.setLobStorageOption(getLobStorageOption(ctx.lob_storage_clause()));
+ } else if (ctx.MICRO_INDEX_CLUSTERED() != null) {
+ target.setMicroIndexClustered(Boolean.valueOf(ctx.BOOL_VALUE().getText()));
+ } else if (ctx.AUTO_REFRESH() != null) {
+ if (ctx.OFF() != null) {
+ target.setAutoRefresh(ctx.OFF().getText());
+ } else if (ctx.IMMEDIATE() != null) {
+ target.setAutoRefresh(ctx.IMMEDIATE().getText());
+ } else if (ctx.INTERVAL() != null) {
+ target.setAutoRefresh(ctx.INTERVAL().getText());
+ }
+ } else if (ctx.MIN_ROWS() != null) {
+ target.setMinRows(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.MAX_ROWS() != null) {
+ target.setMaxRows(Integer.valueOf(ctx.INTNUM().getText()));
+ } else if (ctx.PASSWORD() != null) {
+ target.setPassword(ctx.STRING_VALUE().getText());
+ } else if (ctx.PACK_KEYS() != null) {
+ target.setPackKeys(ctx.INTNUM() != null ? ctx.INTNUM().getText() : ctx.DEFAULT().getText());
+ } else if (ctx.CONNECTION() != null) {
+ target.setConnection(ctx.STRING_VALUE().getText());
+ } else if (ctx.DATA() != null && ctx.DIRECTORY() != null) {
+ target.setDataDirectory(ctx.STRING_VALUE().getText());
+ } else if (ctx.INDEX() != null && ctx.DIRECTORY() != null) {
+ target.setIndexDirectory(ctx.STRING_VALUE().getText());
+ } else if (ctx.ENCRYPTION() != null) {
+ target.setEncryption(ctx.STRING_VALUE().getText());
+ } else if (ctx.STATS_AUTO_RECALC() != null) {
+ target.setStatsAutoRecalc(ctx.INTNUM() != null ? ctx.INTNUM().getText() : ctx.DEFAULT().getText());
+ } else if (ctx.STATS_PERSISTENT() != null) {
+ target.setStatsPersistent(ctx.INTNUM() != null ? ctx.INTNUM().getText() : ctx.DEFAULT().getText());
+ } else if (ctx.STATS_SAMPLE_PAGES() != null) {
+ target.setStatsSamplePages(ctx.INTNUM() != null ? ctx.INTNUM().getText() : ctx.DEFAULT().getText());
+ } else if (ctx.UNION() != null) {
+ target.setUnion(Collections.emptyList());
+ if (ctx.table_list() != null) {
+ target.setUnion(ctx.table_list().relation_factor().stream()
+ .map(MySQLFromReferenceFactory::getRelationFactor).collect(Collectors.toList()));
+ }
+ } else if (ctx.INSERT_METHOD() != null) {
+ target.setInsertMethod(ctx.merge_insert_types().getText());
}
return target;
}
@@ -202,4 +261,15 @@ public TableOptions visitParallel_option(Parallel_optionContext ctx) {
return tableOptions;
}
+ public static LobStorageOption getLobStorageOption(Lob_storage_clauseContext ctx) {
+ List lobStorageSizes = ctx.lob_storage_parameters().lob_storage_parameter()
+ .stream().map(i -> {
+ if (i.lob_chunk_size().INTNUM() != null) {
+ return i.lob_chunk_size().INTNUM().getText();
+ }
+ return i.lob_chunk_size().STRING_VALUE().getText();
+ }).collect(Collectors.toList());
+ return new LobStorageOption(ctx, ctx.column_name().getText(), lobStorageSizes);
+ }
+
}
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 3736972307..c77af1ee78 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
@@ -15,9 +15,7 @@
*/
package com.oceanbase.tools.sqlparser.adapter.oracle;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.CharStream;
@@ -25,10 +23,12 @@
import org.antlr.v4.runtime.misc.Interval;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Add_external_table_partition_actionsContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Add_range_or_list_partitionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Add_range_or_list_subpartitionContext;
-import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_column_group_optionContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_column_group_actionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_column_optionContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_external_table_actionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_index_optionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_partition_optionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Alter_table_actionContext;
@@ -43,6 +43,7 @@
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Split_list_partitionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Split_range_partitionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParserBaseVisitor;
+import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.alter.table.AlterTableAction;
import com.oceanbase.tools.sqlparser.statement.alter.table.PartitionSplitActions;
import com.oceanbase.tools.sqlparser.statement.common.ColumnGroupElement;
@@ -56,6 +57,7 @@
import com.oceanbase.tools.sqlparser.statement.createtable.SubPartitionElement;
import com.oceanbase.tools.sqlparser.statement.createtable.TableOptions;
import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
+import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
import lombok.NonNull;
@@ -75,10 +77,14 @@ public OracleAlterTableActionFactory(@NonNull Alter_table_actionContext alterTab
this.parserRuleContext = alterTableActionContext;
}
- public OracleAlterTableActionFactory(@NonNull Alter_column_group_optionContext alterColumnGroupOptionContext) {
+ public OracleAlterTableActionFactory(@NonNull Alter_column_group_actionContext alterColumnGroupOptionContext) {
this.parserRuleContext = alterColumnGroupOptionContext;
}
+ public OracleAlterTableActionFactory(@NonNull Alter_external_table_actionContext alterExternalTableActionContext) {
+ this.parserRuleContext = alterExternalTableActionContext;
+ }
+
@Override
public AlterTableAction generate() {
return visit(this.parserRuleContext);
@@ -130,6 +136,20 @@ public AlterTableAction visitOpt_alter_compress_option(Opt_alter_compress_option
return alterTableAction;
}
+ @Override
+ public AlterTableAction visitAlter_external_table_action(Alter_external_table_actionContext ctx) {
+ AlterTableAction action = new AlterTableAction(ctx);
+ action.setExternalTableLocation(ctx.STRING_VALUE().getText());
+ if (ctx.DROP() != null && ctx.PARTITION() != null) {
+ action.setDropExternalTablePartition(true);
+ } else if (ctx.ADD() != null && ctx.PARTITION() != null) {
+ Map externalTablePartition = new HashMap<>();
+ visitAddExternalTablePartitionActions(externalTablePartition, ctx.add_external_table_partition_actions());
+ action.setAddExternalTablePartition(externalTablePartition);
+ }
+ return action;
+ }
+
@Override
public AlterTableAction visitAlter_column_option(Alter_column_optionContext ctx) {
AlterTableAction alterTableAction = new AlterTableAction(ctx);
@@ -248,6 +268,9 @@ public AlterTableAction visitAlter_partition_option(Alter_partition_optionContex
.collect(Collectors.toList());
}
alterTableAction.addSubpartitionElements(getRelationFactor(ctx.relation_factor()), subElts);
+ } else if (ctx.EXCHANGE() != null && ctx.PARTITION() != null) {
+ alterTableAction.setExchangePartition(ctx.relation_name(0).getText(),
+ OracleFromReferenceFactory.getRelationFactor(ctx.relation_factor()));
} else if (ctx.add_range_or_list_partition() != null) {
Add_range_or_list_partitionContext pCtx = ctx.add_range_or_list_partition();
List elts;
@@ -329,7 +352,7 @@ public AlterTableAction visitModify_partition_info(Modify_partition_infoContext
}
@Override
- public AlterTableAction visitAlter_column_group_option(Alter_column_group_optionContext ctx) {
+ public AlterTableAction visitAlter_column_group_action(Alter_column_group_actionContext ctx) {
AlterTableAction action = new AlterTableAction(ctx);
List columnGroupElements = ctx.column_group_list().column_group_element()
.stream().map(c -> new OracleColumnGroupElementFactory(c).generate()).collect(Collectors.toList());
@@ -379,4 +402,14 @@ private List getSpecialPartitionElement(Special_partition_list
}).collect(Collectors.toList());
}
+ private void visitAddExternalTablePartitionActions(Map externalTablePartition,
+ Add_external_table_partition_actionsContext context) {
+ if (context == null) {
+ return;
+ }
+ Expression value = new ConstExpression(context.add_external_table_partition_action().expr_const());
+ externalTablePartition.put(context.add_external_table_partition_action().column_name().getText(), value);
+ visitAddExternalTablePartitionActions(externalTablePartition, context.add_external_table_partition_actions());
+ }
+
}
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 e3c3bc5851..580ddb5ba6 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
@@ -58,9 +58,12 @@ public AlterTable visitAlter_table_stmt(Alter_table_stmtContext ctx) {
List actions = ctx.alter_table_actions().alter_table_action().stream()
.map(c -> new OracleAlterTableActionFactory(c).generate()).collect(Collectors.toList());
alterTable = new AlterTable(ctx, relationFactor, actions);
+ } else if (ctx.alter_external_table_action() != null) {
+ alterTable = new AlterTable(ctx, relationFactor, Collections.singletonList(
+ new OracleAlterTableActionFactory(ctx.alter_external_table_action()).generate()));
} else {
alterTable = new AlterTable(ctx, relationFactor, Collections.singletonList(
- new OracleAlterTableActionFactory(ctx.alter_column_group_option()).generate()));
+ new OracleAlterTableActionFactory(ctx.alter_column_group_action()).generate()));
}
if (ctx.EXTERNAL() != null) {
alterTable.setExternal(true);
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateIndexFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateIndexFactory.java
index 8b85428350..64638fe736 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateIndexFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleCreateIndexFactory.java
@@ -57,6 +57,9 @@ public CreateIndex visitCreate_index_stmt(Create_index_stmtContext ctx) {
CreateIndex index = new CreateIndex(ctx,
OracleFromReferenceFactory.getRelationFactor(ctx.normal_relation_factor()),
OracleFromReferenceFactory.getRelationFactor(ctx.relation_factor()), columns);
+ if (ctx.INDEXTYPE() != null && ctx.MDSYS() != null && ctx.SPATIAL_INDEX() != null) {
+ index.setMdSysDotSpatialIndex(true);
+ }
if (ctx.opt_index_options() != null) {
IndexOptions options = new OracleIndexOptionsFactory(ctx.opt_index_options()).generate();
Index_using_algorithmContext context = ctx.index_using_algorithm();
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 137c18e030..2ff47c98cc 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
@@ -255,6 +255,8 @@ public boolean isBinary() {
public DataType visitTreat_data_type(Treat_data_typeContext ctx) {
if (ctx.JSON() != null) {
return new GeneralDataType(ctx, ctx.JSON().getText(), null);
+ } else if (ctx.obj_access_ref_cast() != null) {
+ return new GeneralDataType(ctx, ctx.obj_access_ref_cast().getText(), null);
}
return visitChildren(ctx);
}
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 0166b88715..75bc21a2a4 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
@@ -51,11 +51,14 @@
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.Environment_id_functionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Evalname_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.ExprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Extract_functionContext;
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.Hierarchical_functionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.In_exprContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Insert_child_xmlContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Is_json_constrainContext;
@@ -87,6 +90,7 @@
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.Numeric_functionContext;
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;
@@ -103,9 +107,12 @@
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.Sdo_relate_exprContext;
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.Spatial_cellid_exprContext;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.Spatial_mbr_exprContext;
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;
@@ -150,14 +157,14 @@
import com.oceanbase.tools.sqlparser.statement.expression.FullTextSearch;
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.JsonOption;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOption.ScalarsMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOption.StrictMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOption.UniqueMode;
+import com.oceanbase.tools.sqlparser.statement.expression.JsonOption.WrapperMode;
import com.oceanbase.tools.sqlparser.statement.expression.NullExpression;
import com.oceanbase.tools.sqlparser.statement.expression.ParamWithAssign;
import com.oceanbase.tools.sqlparser.statement.expression.RelationReference;
@@ -666,7 +673,7 @@ public Expression visitBool_pri_in_pl_func(Bool_pri_in_pl_funcContext ctx) {
@Override
public Expression visitIs_json_constrain(Is_json_constrainContext ctx) {
- JsonConstraint constraint = new JsonConstraint(ctx);
+ JsonOption constraint = new JsonOption(ctx);
if (ctx.strict_opt() != null) {
constraint.setStrictMode(ctx.strict_opt().LAX() != null ? StrictMode.LAX : StrictMode.STRICT);
}
@@ -699,42 +706,49 @@ public Expression visitJson_object_expr(Json_object_exprContext ctx) {
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();
+ JsonOption jsonOpt = null;
+ if (oCtx.STRICT() != null || oCtx.json_obj_unique_key() != null) {
+ jsonOpt = getJsonOption(oCtx.STRICT(), oCtx.json_obj_unique_key());
+ }
if (oCtx.js_on_null() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(oCtx.js_on_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);
+ jsonOpt.setOnOption(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()));
+ if (jsonOpt != null) {
+ fCall.addOption(jsonOpt);
}
} else if (ctx.opt_json_object_content().STRICT() != null) {
- fCall.addOption(getJsonConstraint(ctx.opt_json_object_content().STRICT(),
+ fCall.addOption(getJsonOption(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()));
+ fCall.addOption(getJsonOption(null, ctx.opt_json_object_content().json_obj_unique_key()));
}
return fCall;
}
- private JsonConstraint getJsonConstraint(TerminalNode strict, Json_obj_unique_keyContext ctx) {
- JsonConstraint jc;
+ private JsonOption getJsonOption(TerminalNode strict, Json_obj_unique_keyContext ctx) {
+ JsonOption jc;
if (strict != null && ctx != null) {
- jc = new JsonConstraint(strict, ctx);
+ jc = new JsonOption(strict, ctx);
jc.setStrictMode(StrictMode.STRICT);
jc.setUniqueMode(UniqueMode.WITH_UNIQUE_KEYS);
} else if (strict != null) {
- jc = new JsonConstraint(strict);
+ jc = new JsonOption(strict);
jc.setStrictMode(StrictMode.STRICT);
} else {
- jc = new JsonConstraint(ctx);
+ jc = new JsonOption(ctx);
jc.setUniqueMode(UniqueMode.WITH_UNIQUE_KEYS);
}
return jc;
@@ -781,23 +795,28 @@ public Expression visitJson_query_expr(Json_query_exprContext ctx) {
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);
+ if (ctx.json_query_opt() != null) {
+ JsonOption jsonOpt = new JsonOption(ctx.json_query_opt());
+ fCall.addOption(jsonOpt);
+ if (ctx.json_query_opt().TRUNCATE() != null) {
+ jsonOpt.setTruncate(true);
+ }
+ if (ctx.json_query_opt().PRETTY() != null) {
+ jsonOpt.setPretty(true);
+ }
+ if (ctx.json_query_opt().ASCII() != null) {
+ jsonOpt.setAscii(true);
+ }
+ setScalarsMode(jsonOpt, ctx.json_query_opt().scalars_opt());
+ setWrapperMode(jsonOpt, ctx.json_query_opt().wrapper_opts());
+ if (ctx.json_query_opt().ASIS() != null) {
+ jsonOpt.setAsis(true);
+ }
+ jsonOpt.setOnOption(getJsonOnOption(ctx.json_query_opt().json_query_on_opt()));
+ if (ctx.json_query_opt().MULTIVALUE() != null) {
+ jsonOpt.setMultiValue(true);
+ }
}
- fCall.addOption(getJsonOnOption(ctx.json_query_on_opt()));
return fCall;
}
@@ -809,24 +828,27 @@ public Expression visitJson_mergepatch_expr(Json_mergepatch_exprContext ctx) {
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();
+ JsonOption jsonOpt = new JsonOption(ctx.json_mergepatch_opt());
+ fCall.addOption(jsonOpt);
+ Opt_json_mergepatchContext oCtx = ctx.json_mergepatch_opt().opt_json_mergepatch();
if (oCtx.TRUNCATE() != null) {
- fCall.addOption(new ConstExpression(oCtx.TRUNCATE()));
+ jsonOpt.setTruncate(true);
}
if (oCtx.PRETTY() != null) {
- fCall.addOption(new ConstExpression(oCtx.PRETTY()));
+ jsonOpt.setPretty(true);
}
if (oCtx.ASCII() != null) {
- fCall.addOption(new ConstExpression(oCtx.ASCII()));
+ jsonOpt.setAscii(true);
}
- 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()));
+ if (ctx.json_mergepatch_opt().json_mergepatch_on_error() != null) {
+ OBParser.Json_mergepatch_on_errorContext jCtx = ctx.json_mergepatch_opt().json_mergepatch_on_error();
+ JsonOnOption jsonOnOption = new JsonOnOption(jCtx);
+ if (jCtx.NULLX() != null) {
+ jsonOnOption.setOnError(new NullExpression(jCtx.NULLX()));
} else {
- jsonOnOption.setOnError(new ConstExpression(ctx.json_mergepatch_on_error().ERROR_P(0)));
+ jsonOnOption.setOnError(new ConstExpression(jCtx.ERROR_P(0)));
}
- fCall.addOption(jsonOnOption);
+ jsonOpt.setOnOption(jsonOnOption);
}
return fCall;
}
@@ -846,22 +868,28 @@ public Expression visitJson_array_expr(Json_array_exprContext ctx) {
return p;
}).collect(Collectors.toList());
FunctionCall fCall = new FunctionCall(ctx, "json_array", params);
+ JsonOption jsonOpt = null;
if (jCtx.json_array_on_null() != null) {
+ jsonOpt = new JsonOption(jCtx.json_array_on_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);
+ jsonOpt.setOnOption(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);
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(jCtx.STRICT());
+ }
+ jsonOpt.setStrictMode(StrictMode.STRICT);
+ }
+ if (jsonOpt != null) {
+ fCall.addOption(jsonOpt);
}
return fCall;
}
@@ -878,13 +906,17 @@ public Expression visitJson_value_expr(Json_value_exprContext ctx) {
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()));
+ if (ctx.json_value_opt() != null) {
+ JsonOption jsonOpt = new JsonOption(ctx.json_value_opt());
+ fCall.addOption(jsonOpt);
+ if (ctx.json_value_opt().TRUNCATE() != null) {
+ jsonOpt.setTruncate(true);
+ }
+ if (ctx.json_value_opt().ASCII() != null) {
+ jsonOpt.setAscii(true);
+ }
+ jsonOpt.setOnOption(getJsonOnOption(ctx.json_value_opt().json_value_on_opt()));
}
- fCall.addOption(getJsonOnOption(ctx.json_value_on_opt()));
return fCall;
}
@@ -912,7 +944,7 @@ public Expression visitJson_table_expr(Json_table_exprContext ctx) {
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()));
+ fCall.addOption(getJsonOption(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;
@@ -927,7 +959,7 @@ public Expression visitJson_equal_expr(Json_equal_exprContext ctx) {
}
FunctionCall fCall = new FunctionCall(ctx, ctx.getChild(0).getText(), params);
if (ctx.json_equal_option() != null) {
- fCall.addOption(getJsonOnOption(ctx.json_equal_option()));
+ fCall.addOption(getJsonOption(ctx.json_equal_option()));
}
return fCall;
}
@@ -1230,7 +1262,7 @@ public FunctionCall getFunctionCall(Access_func_exprContext ctx) {
}
setJsonExistOpt(fCall, ctx.opt_json_exist());
if (ctx.json_equal_option() != null) {
- fCall.addOption(getJsonOnOption(ctx.json_equal_option()));
+ fCall.addOption(getJsonOption(ctx.json_equal_option()));
}
return fCall;
}
@@ -1280,88 +1312,115 @@ public Expression visitObj_access_ref_normal(Obj_access_ref_normalContext ctx) {
}
@Override
- public Expression visitSingle_row_function(Single_row_functionContext ctx) {
+ public Expression visitNumeric_function(Numeric_functionContext ctx) {
+ return new FunctionCall(ctx, ctx.MOD().getText(), ctx.bit_expr().stream()
+ .map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
+ }
+
+ @Override
+ public Expression visitCharacter_function(Character_functionContext ctx) {
String funcName = null;
List functionOpts = new ArrayList<>();
List params = new ArrayList<>();
- if (ctx.numeric_function() != null) {
- funcName = ctx.numeric_function().MOD().getText();
- params.addAll(ctx.numeric_function().bit_expr().stream()
- .map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
- } else if (ctx.character_function() != null) {
- Character_functionContext characterFunc = ctx.character_function();
- if (characterFunc.TRANSLATE() != null) {
- funcName = characterFunc.TRANSLATE().getText();
- } else if (characterFunc.TRIM() != null) {
- funcName = characterFunc.TRIM().getText();
- } else if (characterFunc.ASCII() != null) {
- funcName = characterFunc.ASCII().getText();
- }
- if (characterFunc.parameterized_trim() != null) {
- Parameterized_trimContext trim = characterFunc.parameterized_trim();
- 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) {
- 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 (params.size() > 0) {
- params.get(params.size() - 1).addOption(new ConstExpression(characterFunc.translate_charset()));
+ if (ctx.TRANSLATE() != null) {
+ funcName = ctx.TRANSLATE().getText();
+ } else if (ctx.TRIM() != null) {
+ funcName = ctx.TRIM().getText();
+ } else if (ctx.ASCII() != null) {
+ funcName = ctx.ASCII().getText();
+ }
+ if (funcName == null) {
+ throw new IllegalStateException("Missing function name");
+ }
+ if (ctx.parameterized_trim() != null) {
+ Parameterized_trimContext trim = ctx.parameterized_trim();
+ 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) {
+ functionOpts.add(new ConstExpression((TerminalNode) p));
+ } else {
+ break;
}
}
- } else if (ctx.extract_function() != null) {
- funcName = ctx.extract_function().EXTRACT().getText();
- 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();
- 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)))
+ } else {
+ params.addAll(ctx.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());
+ if (params.size() > 0) {
+ params.get(params.size() - 1).addOption(new ConstExpression(ctx.translate_charset()));
}
- 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);
functionOpts.forEach(fCall::addOption);
return fCall;
}
+ @Override
+ public Expression visitExtract_function(Extract_functionContext ctx) {
+ FunctionParam p = new ExpressionParam(new ConstExpression(ctx.date_unit_for_extract()));
+ p.addOption(visit(ctx.bit_expr()));
+ return new FunctionCall(ctx, ctx.EXTRACT().getText(), Collections.singletonList(p));
+ }
+
+ @Override
+ public Expression visitConversion_function(Conversion_functionContext ctx) {
+ if (ctx.CAST() != null) {
+ FunctionParam functionParam = new ExpressionParam(visit(ctx.bit_expr()));
+ functionParam.addOption(new OracleDataTypeFactory(ctx.cast_data_type()).generate());
+ return new FunctionCall(ctx, ctx.CAST().getText(), Collections.singletonList(functionParam));
+ }
+ FunctionParam functionParam = new ExpressionParam(visit(ctx.bit_expr()));
+ functionParam.addOption(new OracleDataTypeFactory(ctx.treat_data_type()).generate());
+ return new FunctionCall(ctx, ctx.TREAT().getText(), Collections.singletonList(functionParam));
+ }
+
+ @Override
+ public Expression visitHierarchical_function(Hierarchical_functionContext ctx) {
+ return new FunctionCall(ctx, ctx.SYS_CONNECT_BY_PATH().getText(), ctx.bit_expr()
+ .stream().map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
+ }
+
+ @Override
+ public Expression visitEnvironment_id_function(Environment_id_functionContext ctx) {
+ return new FunctionCall(ctx, ctx.getText(), Collections.emptyList());
+ }
+
+ @Override
+ public Expression visitSpatial_cellid_expr(Spatial_cellid_exprContext ctx) {
+ return new FunctionCall(ctx, ctx.SPATIAL_CELLID().getText(),
+ Collections.singletonList(new ExpressionParam(visit(ctx.bit_expr()))));
+ }
+
+ @Override
+ public Expression visitSpatial_mbr_expr(Spatial_mbr_exprContext ctx) {
+ return new FunctionCall(ctx, ctx.SPATIAL_MBR().getText(),
+ Collections.singletonList(new ExpressionParam(visit(ctx.bit_expr()))));
+ }
+
+ @Override
+ public Expression visitSdo_relate_expr(Sdo_relate_exprContext ctx) {
+ return new FunctionCall(ctx, ctx.SDO_RELATE().getText(), ctx.bit_expr()
+ .stream().map(e -> new ExpressionParam(visit(e))).collect(Collectors.toList()));
+ }
+
+ @Override
+ public Expression visitSingle_row_function(Single_row_functionContext ctx) {
+ if (ctx.xml_function() == null) {
+ return visitChildren(ctx);
+ }
+ 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;
+ }
+
@Override
public Expression visitAggregate_function(Aggregate_functionContext ctx) {
if (ctx.funcName == null) {
@@ -1452,6 +1511,9 @@ public Expression visitSpecial_func_expr(Special_func_exprContext ctx) {
funcName = ctx.VALUES() == null ? ctx.DEFAULT().getText() : ctx.VALUES().getText();
StatementFactory factory = new OracleColumnRefFactory(ctx.column_definition_ref());
params.add(new ExpressionParam(factory.generate()));
+ } else if (ctx.LAST_REFRESH_SCN() != null) {
+ funcName = ctx.LAST_REFRESH_SCN().getText();
+ params.add(new ExpressionParam(new ConstExpression(ctx.INTNUM())));
} else {
funcName = ctx.getChild(0).getText();
params.add(new ExpressionParam(visit(ctx.bit_expr(0))));
@@ -1676,14 +1738,14 @@ public boolean isBinary() {
return new GeneralDataType(ctx, ctx.RAW().getText(), null);
}
- private void setScalarsMode(JsonConstraint c, Scalars_optContext ctx) {
+ private void setScalarsMode(JsonOption c, Scalars_optContext ctx) {
if (ctx == null) {
return;
}
c.setScalarsMode(ctx.ALLOW() != null ? ScalarsMode.ALLOW_SCALARS : ScalarsMode.DISALLOW_SCALARS);
}
- private void setWrapperMode(JsonConstraint c, Wrapper_optsContext ctx) {
+ private void setWrapperMode(JsonOption c, Wrapper_optsContext ctx) {
if (ctx == null) {
return;
}
@@ -1812,28 +1874,32 @@ private JsonOnOption getJsonOnOption(Js_agg_on_nullContext ctx) {
return jsonOnOption;
}
- private JsonOnOption getJsonOnOption(Opt_json_table_on_error_on_emptyContext ctx) {
+ private JsonOption getJsonOption(Opt_json_table_on_error_on_emptyContext ctx) {
if (ctx == null) {
return null;
}
+ JsonOption jsonOpt = new JsonOption(ctx);
JsonOnOption jsonOnOption = new JsonOnOption(ctx);
+ jsonOpt.setOnOption(jsonOnOption);
if (ctx.json_table_on_error() != null) {
jsonOnOption.setOnError(visit(ctx.json_table_on_error().json_table_on_response()));
}
if (ctx.json_table_on_empty() != null) {
jsonOnOption.setOnEmpty(visit(ctx.json_table_on_empty().json_table_on_response()));
}
- return jsonOnOption;
+ return jsonOpt;
}
- private JsonOnOption getJsonOnOption(Json_equal_optionContext ctx) {
+ private JsonOption getJsonOption(Json_equal_optionContext ctx) {
+ JsonOption jsonOpt = new JsonOption(ctx);
JsonOnOption jsonOnOption = new JsonOnOption(ctx);
+ jsonOpt.setOnOption(jsonOnOption);
if (ctx.BOOL_VALUE() != null) {
jsonOnOption.setOnError(new BoolValue(ctx.BOOL_VALUE()));
} else {
jsonOnOption.setOnError(new ConstExpression(ctx.ERROR_P(0)));
}
- return jsonOnOption;
+ return jsonOpt;
}
private FunctionParam visitJsonTableColumnDef(Json_table_column_defContext ctx) {
@@ -1860,12 +1926,28 @@ private FunctionParam visitJsonTableExistsColumnDef(Json_table_exists_column_def
FunctionParam param = new ExpressionParam(new ColumnReference(
ctx.column_name(), null, null, ctx.column_name().getText()));
param.addOption(new OracleDataTypeFactory(ctx.opt_jt_value_type()).generate());
+ JsonOption jsonOpt = null;
if (ctx.TRUNCATE() != null) {
- param.addOption(new ConstExpression(ctx.TRUNCATE()));
+ jsonOpt = new JsonOption(ctx.TRUNCATE());
+ jsonOpt.setTruncate(true);
}
param.addOption(new ConstExpression(ctx.EXISTS()));
param.addOption(visit(ctx.json_table_column_def_path()));
- param.addOption(getJsonOnOption(ctx.opt_json_exists_on_error_on_empty()));
+ if (ctx.ASIS() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.ASIS());
+ }
+ jsonOpt.setAsis(true);
+ }
+ if (ctx.opt_json_exists_on_error_on_empty() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.opt_json_exists_on_error_on_empty());
+ }
+ jsonOpt.setOnOption(getJsonOnOption(ctx.opt_json_exists_on_error_on_empty()));
+ }
+ if (jsonOpt != null) {
+ param.addOption(jsonOpt);
+ }
return param;
}
@@ -1880,24 +1962,40 @@ private FunctionParam visitJsonTableQueryColumnDef(Json_table_query_column_defCo
} else if (ctx.JSON() != null) {
param.addOption(new GeneralDataType(ctx.JSON(), ctx.JSON().getText(), null));
}
+ JsonOption jsonOpt = null;
if (ctx.TRUNCATE() != null) {
- param.addOption(new ConstExpression(ctx.TRUNCATE()));
+ jsonOpt = new JsonOption(ctx.TRUNCATE());
+ jsonOpt.setTruncate(true);
}
if (ctx.scalars_opt() != null || ctx.wrapper_opts() != null) {
- JsonConstraint jsonConstraint;
- if (ctx.scalars_opt() != null && ctx.wrapper_opts() != null) {
- jsonConstraint = new JsonConstraint(ctx.scalars_opt(), ctx.wrapper_opts());
- } else if (ctx.wrapper_opts() != null) {
- jsonConstraint = new JsonConstraint(ctx.wrapper_opts());
- } else {
- jsonConstraint = new JsonConstraint(ctx.scalars_opt());
+ if (jsonOpt == null) {
+ if (ctx.scalars_opt() != null && ctx.wrapper_opts() != null) {
+ jsonOpt = new JsonOption(ctx.scalars_opt(), ctx.wrapper_opts());
+ } else if (ctx.wrapper_opts() != null) {
+ jsonOpt = new JsonOption(ctx.wrapper_opts());
+ } else {
+ jsonOpt = new JsonOption(ctx.scalars_opt());
+ }
}
- setScalarsMode(jsonConstraint, ctx.scalars_opt());
- setWrapperMode(jsonConstraint, ctx.wrapper_opts());
- param.addOption(jsonConstraint);
+ setScalarsMode(jsonOpt, ctx.scalars_opt());
+ setWrapperMode(jsonOpt, ctx.wrapper_opts());
}
param.addOption(visit(ctx.json_table_column_def_path()));
- param.addOption(getJsonOnOption(ctx.json_query_on_opt()));
+ if (ctx.ASIS() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.ASIS());
+ }
+ jsonOpt.setAsis(true);
+ }
+ if (ctx.json_query_on_opt() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.json_query_on_opt());
+ }
+ jsonOpt.setOnOption(getJsonOnOption(ctx.json_query_on_opt()));
+ }
+ if (jsonOpt != null) {
+ param.addOption(jsonOpt);
+ }
return param;
}
@@ -1905,11 +2003,27 @@ private FunctionParam visitJsonTableValueColumnDef(Json_table_value_column_defCo
FunctionParam param = new ExpressionParam(new ColumnReference(
ctx.column_name(), null, null, ctx.column_name().getText()));
param.addOption(new OracleDataTypeFactory(ctx.opt_jt_value_type()).generate());
+ JsonOption jsonOpt = null;
if (ctx.TRUNCATE() != null) {
- param.addOption(new ConstExpression(ctx.TRUNCATE()));
+ jsonOpt = new JsonOption(ctx.TRUNCATE());
+ jsonOpt.setTruncate(true);
}
param.addOption(visit(ctx.json_table_column_def_path()));
- param.addOption(getJsonOnOption(ctx.json_value_on_opt()));
+ if (ctx.ASIS() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.ASIS());
+ }
+ jsonOpt.setAsis(true);
+ }
+ if (ctx.json_value_on_opt() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.json_value_on_opt());
+ }
+ jsonOpt.setOnOption(getJsonOnOption(ctx.json_value_on_opt()));
+ }
+ if (jsonOpt != null) {
+ param.addOption(jsonOpt);
+ }
return param;
}
@@ -1930,7 +2044,11 @@ private void setJsonExistOpt(@NonNull FunctionCall functionCall, Opt_json_existC
.map(c -> new ExpressionParam(visit(c.bit_expr()), c.sql_var_name().getText()))
.forEach(functionCall::addOption);
}
- functionCall.addOption(getJsonOnOption(ctx.opt_json_exists_on_error_on_empty()));
+ if (ctx.opt_json_exists_on_error_on_empty() != null) {
+ JsonOption jsonOpt = new JsonOption(ctx.opt_json_exists_on_error_on_empty());
+ functionCall.addOption(jsonOpt);
+ jsonOpt.setOnOption(getJsonOnOption(ctx.opt_json_exists_on_error_on_empty()));
+ }
}
private void setFunctionOptions(FunctionCall functionCall, Aggregate_functionContext ctx) {
@@ -1947,7 +2065,16 @@ private void setFunctionOptions(FunctionCall functionCall, Aggregate_functionCon
if (ctx.WITHIN() == null && ctx.DENSE_RANK() == null && ctx.order_by() != null) {
functionCall.addOption(new OracleOrderByFactory(ctx.order_by()).generate());
}
- functionCall.addOption(getJsonOnOption(ctx.js_agg_on_null()));
+ JsonOption jsonOpt = null;
+ if (ctx.STRICT() != null || ctx.json_obj_unique_key() != null) {
+ jsonOpt = getJsonOption(ctx.STRICT(), ctx.json_obj_unique_key());
+ }
+ if (ctx.js_agg_on_null() != null) {
+ if (jsonOpt == null) {
+ jsonOpt = new JsonOption(ctx.js_agg_on_null());
+ }
+ jsonOpt.setOnOption(getJsonOnOption(ctx.js_agg_on_null()));
+ }
if (ctx.js_agg_returning_type_opt() != null) {
Js_agg_returning_type_optContext jCtx = ctx.js_agg_returning_type_opt();
if (jCtx.js_return_type() != null) {
@@ -1956,8 +2083,8 @@ private void setFunctionOptions(FunctionCall functionCall, Aggregate_functionCon
functionCall.addOption(new OracleDataTypeFactory(jCtx.js_agg_returning_type()).generate());
}
}
- if (ctx.STRICT() != null || ctx.json_obj_unique_key() != null) {
- functionCall.addOption(getJsonConstraint(ctx.STRICT(), ctx.json_obj_unique_key()));
+ if (jsonOpt != null) {
+ functionCall.addOption(jsonOpt);
}
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleFromReferenceFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleFromReferenceFactory.java
index 64ed4ead8c..244a97507c 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleFromReferenceFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleFromReferenceFactory.java
@@ -165,7 +165,11 @@ public FromReference visitTable_factor(Table_factorContext ctx) {
if (ctx.tbl_name() != null) {
return visit(ctx.tbl_name());
} else if (ctx.table_subquery() != null) {
- return visit(ctx.table_subquery());
+ ExpressionReference reference = (ExpressionReference) visit(ctx.table_subquery());
+ if (ctx.LATERAL() != null) {
+ reference.setLateral(true);
+ }
+ return reference;
} else if (ctx.table_reference() != null) {
return visit(ctx.table_reference());
} else if (ctx.simple_expr() != null) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleInsertFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleInsertFactory.java
index 5cf2e67530..ee9eebda35 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleInsertFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleInsertFactory.java
@@ -20,6 +20,8 @@
import java.util.List;
import java.util.stream.Collectors;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Condition_insert_clauseContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Conditional_insert_clauseContext;
@@ -130,15 +132,16 @@ public Insert visitConditional_insert_clause(Conditional_insert_clauseContext ct
public Insert visitSingle_table_insert(Single_table_insertContext ctx) {
InsertTable insertTable;
Insert_table_clauseContext iCtx = ctx.insert_table_clause();
+ TerminalNode beginNode = ctx.INTO() == null ? ctx.OVERWRITE() : ctx.INTO();
if (iCtx.dml_table_name() != null) {
Dml_table_nameContext dCtx = iCtx.dml_table_name();
- insertTable = new InsertTable(ctx.INTO(), ctx.values_clause(), OracleFromReferenceFactory
+ insertTable = new InsertTable(beginNode, ctx.values_clause(), OracleFromReferenceFactory
.getRelationFactor(dCtx.relation_factor()));
if (dCtx.use_partition() != null) {
insertTable.setPartitionUsage(new OraclePartitionUsageFactory(dCtx.use_partition()).generate());
}
} else if (iCtx.select_with_parens() != null) {
- insertTable = new InsertTable(ctx.INTO(), ctx.values_clause(),
+ insertTable = new InsertTable(beginNode, ctx.values_clause(),
new OracleSelectBodyFactory(iCtx.select_with_parens()).generate());
} else {
OracleSelectBodyFactory factory = new OracleSelectBodyFactory(iCtx.subquery());
@@ -153,7 +156,7 @@ public Insert visitSingle_table_insert(Single_table_insertContext ctx) {
if (oCtx.with_check_option() != null) {
select.getLastSelectBody().setWithCheckOption(true);
}
- insertTable = new InsertTable(ctx.INTO(), ctx.values_clause(), select);
+ insertTable = new InsertTable(beginNode, ctx.values_clause(), select);
}
if (iCtx.relation_name() != null) {
insertTable.setAlias(iCtx.relation_name().getText());
@@ -192,6 +195,9 @@ public Insert visitSingle_table_insert(Single_table_insertContext ctx) {
insert.setLogErrors(new OracleLogErrorsFactory(rCtx.log_error_clause()).generate());
}
}
+ if (ctx.OVERWRITE() != null) {
+ insert.setOverwrite(true);
+ }
return insert;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OraclePartitionUsageFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OraclePartitionUsageFactory.java
index 196671830a..239a31843c 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OraclePartitionUsageFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OraclePartitionUsageFactory.java
@@ -16,12 +16,17 @@
package com.oceanbase.tools.sqlparser.adapter.oracle;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import com.oceanbase.tools.sqlparser.adapter.StatementFactory;
+import com.oceanbase.tools.sqlparser.oboracle.OBParser.External_table_partitionsContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Name_listContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParser.Use_partitionContext;
import com.oceanbase.tools.sqlparser.oboracle.OBParserBaseVisitor;
+import com.oceanbase.tools.sqlparser.statement.Expression;
+import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
import com.oceanbase.tools.sqlparser.statement.select.PartitionType;
import com.oceanbase.tools.sqlparser.statement.select.PartitionUsage;
@@ -54,9 +59,24 @@ public PartitionUsage visitUse_partition(Use_partitionContext ctx) {
if (ctx.SUBPARTITION() != null) {
type = PartitionType.SUB_PARTITION;
}
- List nameList = new ArrayList<>();
- visitNameList(ctx.name_list(), nameList);
- return new PartitionUsage(ctx, type, nameList);
+ if (ctx.name_list() != null) {
+ List nameList = new ArrayList<>();
+ visitNameList(ctx.name_list(), nameList);
+ return new PartitionUsage(ctx, type, nameList);
+ }
+ Map externalTablePartition = new HashMap<>();
+ visitExternalTablePartitions(ctx.external_table_partitions(), externalTablePartition);
+ return new PartitionUsage(ctx, type, externalTablePartition);
+ }
+
+ private void visitExternalTablePartitions(External_table_partitionsContext ctx,
+ Map externalTablePartition) {
+ if (ctx == null) {
+ return;
+ }
+ externalTablePartition.put(ctx.external_table_partition().relation_name().getText(),
+ new ConstExpression(ctx.external_table_partition().expr_const()));
+ visitExternalTablePartitions(ctx.external_table_partitions(), externalTablePartition);
}
private void visitNameList(Name_listContext ctx, List nameList) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableElementFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableElementFactory.java
index 86bc36bf41..4b23b1c30f 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableElementFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableElementFactory.java
@@ -387,6 +387,8 @@ private ColumnAttributes visitColumnAttribute(Column_attributeContext ctx) {
attributes.setOrigDefault(visitNowOrSignedLiteral(ctx.now_or_signed_literal()));
} 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.SKIP_INDEX() != null) {
List skipIndexTypes = new ArrayList<>();
if (ctx.opt_skip_index_type_list() != null) {
@@ -459,6 +461,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 {
String name = null;
if (ctx.constraint_and_name() != null) {
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableOptionsFactory.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableOptionsFactory.java
index 8ce7cd3b93..875d7ae3e3 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableOptionsFactory.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/adapter/oracle/OracleTableOptionsFactory.java
@@ -160,12 +160,32 @@ public TableOptions visitTable_option(Table_optionContext ctx) {
.map(ex -> new OracleExpressionFactory(ex).generate())
.collect(Collectors.toList());
value = new CollectionExpression(e.expr_list(), exprs);
+ } else if (e.compression_name() != null) {
+ value = new ConstExpression(e.compression_name());
}
formatMap.put(e.format_key.getText().toUpperCase(), value);
});
target.setFormat(formatMap);
} else if (ctx.PATTERN() != null) {
target.setPattern(ctx.STRING_VALUE().getText());
+ } else if (ctx.PROPERTIES() != null) {
+ Map externalProperties = new HashMap<>();
+ ctx.external_properties_list().external_properties().forEach(e -> {
+ externalProperties.put(e.external_properties_key().getText(), e.STRING_VALUE().getText());
+ });
+ target.setExternalProperties(externalProperties);
+ } else if (ctx.PARTITION_TYPE() != null) {
+ target.setPartitionType(ctx.USER_SPECIFIED().getText());
+ } else if (ctx.MICRO_INDEX_CLUSTERED() != null) {
+ target.setMicroIndexClustered(Boolean.valueOf(ctx.BOOL_VALUE().getText()));
+ } else if (ctx.AUTO_REFRESH() != null) {
+ if (ctx.OFF() != null) {
+ target.setAutoRefresh(ctx.OFF().getText());
+ } else if (ctx.IMMEDIATE() != null) {
+ target.setAutoRefresh(ctx.IMMEDIATE().getText());
+ } else if (ctx.INTERVAL() != null) {
+ target.setAutoRefresh(ctx.INTERVAL().getText());
+ }
}
return target;
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/alter/table/AlterTableAction.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/alter/table/AlterTableAction.java
index 9050193876..f1eb1d0379 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/alter/table/AlterTableAction.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/alter/table/AlterTableAction.java
@@ -17,6 +17,7 @@
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
@@ -26,6 +27,7 @@
import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.common.ColumnGroupElement;
import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
+import com.oceanbase.tools.sqlparser.statement.common.mysql.LobStorageOption;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition;
import com.oceanbase.tools.sqlparser.statement.createtable.ConstraintState;
import com.oceanbase.tools.sqlparser.statement.createtable.OutOfLineConstraint;
@@ -100,6 +102,9 @@ public class AlterTableAction extends BaseStatement {
private List dropPartitionNames;
private List dropSubPartitionNames;
private List addPartitionElements;
+ private Map addExternalTablePartition;
+ private String externalTableLocation;
+ private boolean dropExternalTablePartition;
@Setter(AccessLevel.NONE)
private RelationFactor addSubPartitionElementTo;
@Setter(AccessLevel.NONE)
@@ -147,11 +152,19 @@ public class AlterTableAction extends BaseStatement {
private String renameToSubPartitionName;
private List addColumnGroupElements;
private List dropColumnGroupElements;
+ private String exchangePartitionName;
+ private RelationFactor exchangePartitionTargetTable;
+ private LobStorageOption lobStorageOption;
public AlterTableAction(@NonNull ParserRuleContext context) {
super(context);
}
+ public void setExchangePartition(@NonNull String partitionName, @NonNull RelationFactor targetTable) {
+ this.exchangePartitionName = partitionName;
+ this.exchangePartitionTargetTable = targetTable;
+ }
+
public void setDropColumn(@NonNull ColumnReference dropColumn,
String dropColumnOption) {
this.dropColumns = Collections.singletonList(dropColumn);
@@ -249,6 +262,9 @@ public String toString() {
.map(ColumnDefinition::toString)
.collect(Collectors.joining(",")))
.append(")");
+ if (this.lobStorageOption != null) {
+ builder.append(" ").append(this.lobStorageOption);
+ }
}
}
if (CollectionUtils.isNotEmpty(this.dropColumns)) {
@@ -410,6 +426,10 @@ public String toString() {
if (Boolean.TRUE.equals(this.removePartitioning)) {
builder.append(" REMOVE PARTITIONING");
}
+ if (this.exchangePartitionTargetTable != null && this.exchangePartitionName != null) {
+ builder.append(" EXCHANGE PARTITION ").append(this.exchangePartitionName)
+ .append(" WITH TABLE ").append(this.exchangePartitionTargetTable).append(" WITHOUT VALIDATION");
+ }
if (addColumnGroupElements != null) {
builder.append(" ADD COLUMN GROUP(")
.append(addColumnGroupElements.stream().map(ColumnGroupElement::toString)
@@ -422,6 +442,16 @@ public String toString() {
.collect(Collectors.joining(",")))
.append(")");
}
+ if (this.dropExternalTablePartition) {
+ builder.append(" DROP PARTITION");
+ }
+ if (this.addExternalTablePartition != null) {
+ builder.append(" ADD PARTITION(").append(this.addExternalTablePartition.entrySet().stream()
+ .map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(", "))).append(")");
+ }
+ if (this.externalTableLocation != null) {
+ builder.append(" LOCATION ").append(this.externalTableLocation);
+ }
return builder.length() == 0 ? "" : builder.substring(1);
}
@@ -453,7 +483,7 @@ public boolean isSetDefault() {
@Override
public String toString() {
- return this.isSetDefault() ? "SET DEFAULT" + this.defaultValue : "DROP DEFAULT";
+ return this.isSetDefault() ? "SET DEFAULT (" + this.defaultValue + ")" : "DROP DEFAULT";
}
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/ArrayType.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/ArrayType.java
index d6567dca70..9f907d807c 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/ArrayType.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/ArrayType.java
@@ -37,7 +37,7 @@
@Setter
@EqualsAndHashCode(callSuper = false)
public class ArrayType extends BaseStatement implements DataType {
- private final String typeName = "ARRAY";
+
private final DataType elementType;
public ArrayType(@NonNull ParserRuleContext context, @NonNull DataType elementType) {
@@ -45,17 +45,23 @@ public ArrayType(@NonNull ParserRuleContext context, @NonNull DataType elementTy
this.elementType = elementType;
}
- public ArrayType(DataType elementType) {
+ public ArrayType(@NonNull DataType elementType) {
this.elementType = elementType;
}
@Override
public String getName() {
- return this.typeName;
+ return "ARRAY";
}
@Override
public List getArguments() {
return Collections.emptyList();
}
+
+ @Override
+ public String toString() {
+ return getName() + "(" + this.elementType + ")";
+ }
+
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/LobStorageOption.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/LobStorageOption.java
new file mode 100644
index 0000000000..e6b86c2a3f
--- /dev/null
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/LobStorageOption.java
@@ -0,0 +1,61 @@
+/*
+ * 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.sqlparser.statement.common.mysql;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+
+import com.oceanbase.tools.sqlparser.statement.BaseStatement;
+
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NonNull;
+
+/**
+ * {@link LobStorageOption}
+ *
+ * @author yh263208
+ * @date 2024-10-25 15:29
+ * @since ODC_release_4.3.2
+ */
+@Getter
+@EqualsAndHashCode(callSuper = false)
+public class LobStorageOption extends BaseStatement {
+
+ private final String columnName;
+ private final List lobChunkSizes;
+
+ public LobStorageOption(@NonNull ParserRuleContext context,
+ @NonNull String columnName, @NonNull List lobChunkSizes) {
+ super(context);
+ this.columnName = columnName;
+ this.lobChunkSizes = lobChunkSizes;
+ }
+
+ public LobStorageOption(@NonNull String columnName, @NonNull List lobChunkSizes) {
+ this.columnName = columnName;
+ this.lobChunkSizes = lobChunkSizes;
+ }
+
+ @Override
+ public String toString() {
+ String lobChunkSize = this.lobChunkSizes.stream().map(s -> "CHUNK " + s).collect(Collectors.joining(" "));
+ return "JSON(" + this.columnName + ")" + " STORE AS (" + lobChunkSize + ")";
+ }
+
+}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/VectorType.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/VectorType.java
index fe16933523..29a895291a 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/VectorType.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/common/mysql/VectorType.java
@@ -37,6 +37,7 @@
@Setter
@EqualsAndHashCode(callSuper = false)
public class VectorType extends BaseStatement implements DataType {
+
private final String typeName;
private final Integer dimension;
@@ -64,8 +65,7 @@ public List getArguments() {
@Override
public String toString() {
- StringBuilder builder = new StringBuilder(getName());
- builder.append("(").append(dimension).append(")");
- return builder.toString();
+ return getName() + "(" + this.dimension + ")";
}
+
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createindex/CreateIndex.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createindex/CreateIndex.java
index 0dd3035a70..156972b160 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createindex/CreateIndex.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createindex/CreateIndex.java
@@ -53,6 +53,7 @@ public class CreateIndex extends BaseStatement {
private RelationFactor relation;
private IndexOptions indexOptions;
private Partition partition;
+ private boolean mdSysDotSpatialIndex;
private final List columns;
private List columnGroupElements;
@@ -96,6 +97,9 @@ public String toString() {
.append(" (\n\t").append(this.columns.stream()
.map(SortColumn::toString).collect(Collectors.joining(",\n\t")))
.append("\n)");
+ if (this.mdSysDotSpatialIndex) {
+ builder.append(" INDEXTYPE IS MDSYS.SPATIAL_INDEX");
+ }
if (this.indexOptions != null) {
builder.append(" ").append(this.indexOptions);
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnAttributes.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnAttributes.java
index 7067779422..2ad06647f2 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnAttributes.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnAttributes.java
@@ -56,6 +56,9 @@ public class ColumnAttributes extends BaseOptions {
private Expression onUpdate;
private String collation;
private Integer srid;
+ private String lobChunkSize;
+ private String columnFormat;
+ private String storage;
private List constraints;
private List skipIndexTypes;
@@ -130,6 +133,15 @@ public String toString() {
.append(String.join(",", skipIndexTypes))
.append(")");
}
+ if (this.lobChunkSize != null) {
+ builder.append(" CHUNK ").append(this.lobChunkSize);
+ }
+ if (this.columnFormat != null) {
+ builder.append(" COLUMN_FORMAT ").append(this.columnFormat);
+ }
+ if (this.storage != null) {
+ builder.append(" STORAGE ").append(this.storage);
+ }
return builder.length() == 0 ? "" : builder.substring(1);
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnDefinition.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnDefinition.java
index e70bf9ac86..d9fcfcfcbb 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnDefinition.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/ColumnDefinition.java
@@ -43,7 +43,12 @@ public class ColumnDefinition extends BaseStatement implements TableElement {
private ColumnAttributes columnAttributes;
private Boolean visible;
private Location location;
+ /**
+ * if this field is true, means `BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE`
+ */
+ private boolean serial;
private GenerateOption generateOption;
+ private ForeignReference foreignReference;
private final DataType dataType;
private final ColumnReference columnReference;
@@ -64,6 +69,8 @@ public String toString() {
StringBuilder builder = new StringBuilder(this.columnReference.toString());
if (this.dataType != null) {
builder.append(" ").append(this.dataType.toString());
+ } else if (this.serial) {
+ builder.append(" SERIAL");
}
if (this.visible != null) {
if (this.visible) {
@@ -78,6 +85,9 @@ public String toString() {
if (this.columnAttributes != null) {
builder.append(" ").append(this.columnAttributes);
}
+ if (this.foreignReference != null) {
+ builder.append(" ").append(this.foreignReference);
+ }
if (this.location != null) {
builder.append(" ").append(this.location);
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/CreateTable.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/CreateTable.java
index 601229d1cc..a9a1f029e0 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/CreateTable.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/CreateTable.java
@@ -46,6 +46,8 @@
public class CreateTable extends BaseStatement {
private RelationFactor relation;
+ private boolean ignore;
+ private boolean replace;
private String userVariable;
private boolean global;
private boolean temporary;
@@ -178,6 +180,12 @@ public String toString() {
.map(ColumnGroupElement::toString).collect(Collectors.joining(",")))
.append(")");
}
+ if (this.ignore) {
+ builder.append(" IGNORE");
+ }
+ if (this.replace) {
+ builder.append(" REPLACE");
+ }
if (this.as != null) {
builder.append(" AS ").append(this.as);
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/IndexOptions.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/IndexOptions.java
index a480face47..a81fe01893 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/IndexOptions.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/IndexOptions.java
@@ -16,6 +16,7 @@
package com.oceanbase.tools.sqlparser.statement.createtable;
import java.util.List;
+import java.util.Map;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
@@ -66,6 +67,8 @@ public class IndexOptions extends BaseOptions {
private Boolean reverse;
private List storing;
private List ctxcat;
+ private Integer keyBlockSize;
+ private Map vectorIndexParams;
public IndexOptions(@NonNull ParserRuleContext context) {
super(context);
@@ -149,6 +152,13 @@ public String toString() {
if (this.tableSpace != null) {
builder.append(" TABLESPACE ").append(this.tableSpace);
}
+ if (this.keyBlockSize != null) {
+ builder.append(" KEY_BLOCK_SIZE ").append(this.keyBlockSize);
+ }
+ if (this.vectorIndexParams != null) {
+ builder.append(" WITH (").append(this.vectorIndexParams.entrySet().stream()
+ .map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(", "))).append(")");
+ }
return builder.length() == 0 ? "" : builder.substring(1);
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/OutOfLineIndex.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/OutOfLineIndex.java
index d794ee4812..24f6c671a6 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/OutOfLineIndex.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/OutOfLineIndex.java
@@ -69,6 +69,8 @@ public String toString() {
builder = new StringBuilder("FULLTEXT KEY");
} else if (this.spatial) {
builder = new StringBuilder("SPATIAL KEY");
+ } else if (this.vector) {
+ builder = new StringBuilder("VECTOR KEY");
} else {
builder = new StringBuilder("INDEX");
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/TableOptions.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/TableOptions.java
index 5ccebaa8a0..3c6a229e6a 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/TableOptions.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/createtable/TableOptions.java
@@ -26,6 +26,8 @@
import com.oceanbase.tools.sqlparser.statement.BaseStatement;
import com.oceanbase.tools.sqlparser.statement.Expression;
import com.oceanbase.tools.sqlparser.statement.common.BaseOptions;
+import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
+import com.oceanbase.tools.sqlparser.statement.common.mysql.LobStorageOption;
import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
import lombok.EqualsAndHashCode;
@@ -96,6 +98,26 @@ public class TableOptions extends BaseOptions {
private String kvAttributes;
private Integer defaultLobInRowThreshold;
private Integer lobInRowThreshold;
+ private Integer keyBlockSize;
+ private Integer autoIncrementCacheSize;
+ private String partitionType;
+ private Map externalProperties;
+ private LobStorageOption lobStorageOption;
+ private Boolean microIndexClustered;
+ private String autoRefresh;
+ private Integer maxRows;
+ private Integer minRows;
+ private String password;
+ private String packKeys;
+ private String connection;
+ private String dataDirectory;
+ private String indexDirectory;
+ private String encryption;
+ private String statsAutoRecalc;
+ private String statsPersistent;
+ private String statsSamplePages;
+ private List union;
+ private String insertMethod;
public TableOptions(@NonNull ParserRuleContext context) {
super(context);
@@ -255,6 +277,71 @@ public String toString() {
if (this.lobInRowThreshold != null) {
builder.append(" LOB_INROW_THRESHOLD=").append(this.lobInRowThreshold);
}
+ if (this.keyBlockSize != null) {
+ builder.append(" KEY_BLOCK_SIZE=").append(this.keyBlockSize);
+ }
+ if (this.autoIncrementCacheSize != null) {
+ builder.append(" AUTO_INCREMENT_CACHE_SIZE=").append(this.autoIncrementCacheSize);
+ }
+ if (this.partitionType != null) {
+ builder.append(" PARTITION_TYPE=").append(this.partitionType);
+ }
+ if (this.externalProperties != null) {
+ builder.append(" PROPERTIES=(")
+ .append(this.externalProperties.entrySet().stream()
+ .map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(",")))
+ .append(")");
+ }
+ if (this.lobStorageOption != null) {
+ builder.append(" ").append(this.lobStorageOption);
+ }
+ if (this.microIndexClustered != null) {
+ builder.append(" MICRO_INDEX_CLUSTERED=").append(
+ Boolean.TRUE.equals(this.microIndexClustered) ? "TRUE" : "FALSE");
+ }
+ if (this.autoRefresh != null) {
+ builder.append(" AUTO_REFRESH=").append(this.autoRefresh);
+ }
+ if (this.maxRows != null) {
+ builder.append(" MAX_ROWS=").append(this.maxRows);
+ }
+ if (this.minRows != null) {
+ builder.append(" MIN_ROWS=").append(this.minRows);
+ }
+ if (this.password != null) {
+ builder.append(" PASSWORD=").append(this.password);
+ }
+ if (this.packKeys != null) {
+ builder.append(" PACK_KEYS=").append(this.packKeys);
+ }
+ if (this.connection != null) {
+ builder.append(" CONNECTION=").append(this.connection);
+ }
+ if (this.dataDirectory != null) {
+ builder.append(" DATA DIRECTORY=").append(this.dataDirectory);
+ }
+ if (this.indexDirectory != null) {
+ builder.append(" INDEX DIRECTORY=").append(this.indexDirectory);
+ }
+ if (this.encryption != null) {
+ builder.append(" ENCRYPTION=").append(this.encryption);
+ }
+ if (this.statsAutoRecalc != null) {
+ builder.append(" STATS_AUTO_RECALC=").append(this.statsAutoRecalc);
+ }
+ if (this.statsPersistent != null) {
+ builder.append(" STATS_PERSISTENT=").append(this.statsPersistent);
+ }
+ if (this.statsSamplePages != null) {
+ builder.append(" STATS_SAMPLE_PAGES=").append(this.statsSamplePages);
+ }
+ if (this.union != null) {
+ builder.append(" UNION=(").append(this.union.stream()
+ .map(RelationFactor::toString).collect(Collectors.joining(", "))).append(")");
+ }
+ if (this.insertMethod != null) {
+ builder.append(" INSERT_METHOD=").append(this.insertMethod);
+ }
return builder.length() == 0 ? "" : builder.substring(1);
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/ArrayExpression.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/ArrayExpression.java
index 1fd49fce70..bbc7804d4c 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/ArrayExpression.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/ArrayExpression.java
@@ -15,7 +15,6 @@
*/
package com.oceanbase.tools.sqlparser.statement.expression;
-import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -35,7 +34,8 @@
@Getter
@EqualsAndHashCode(callSuper = true)
public class ArrayExpression extends BaseExpression {
- private List expressions = new ArrayList<>();
+
+ private final List expressions;
public ArrayExpression(@NonNull ParserRuleContext context, @NonNull List expressions) {
super(context);
@@ -50,4 +50,5 @@ public ArrayExpression(@NonNull List expressions) {
protected String doToString() {
return "[" + this.expressions.stream().map(Object::toString).collect(Collectors.joining(",")) + "]";
}
+
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/FullTextSearch.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/FullTextSearch.java
index 668c7b5212..aa2b56ec59 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/FullTextSearch.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/FullTextSearch.java
@@ -38,6 +38,8 @@ public class FullTextSearch extends FunctionCall {
private final String against;
@Setter
private TextSearchMode searchMode;
+ @Setter
+ private boolean withQueryExpansion;
public FullTextSearch(@NonNull ParserRuleContext context,
@NonNull List params, @NonNull String against) {
@@ -59,6 +61,9 @@ public String doToString() {
if (this.searchMode != null) {
builder.append(" ").append(this.searchMode.getValue());
}
+ if (this.withQueryExpansion) {
+ builder.append(" WITH QUERY EXPANSION");
+ }
return builder.append(")").toString();
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/JsonConstraint.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/JsonOption.java
similarity index 72%
rename from libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/JsonConstraint.java
rename to libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/JsonOption.java
index 4e045fe059..48997ec171 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/JsonConstraint.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/expression/JsonOption.java
@@ -26,7 +26,7 @@
import lombok.Setter;
/**
- * {@link JsonConstraint}
+ * {@link JsonOption}
*
* @author yh263208
* @date 2023-09-26 15:09
@@ -36,44 +36,68 @@
@Setter
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
-public class JsonConstraint extends BaseExpression {
+public class JsonOption extends BaseExpression {
+ private boolean truncate;
+ private boolean pretty;
+ private boolean ascii;
+ private boolean asis;
+ private boolean multiValue;
+ private JsonOnOption onOption;
private StrictMode strictMode;
private ScalarsMode scalarsMode;
private UniqueMode uniqueMode;
private WrapperMode wrapperMode;
- public JsonConstraint(@NonNull ParserRuleContext context) {
+ public JsonOption(@NonNull ParserRuleContext context) {
super(context);
}
- public JsonConstraint(@NonNull TerminalNode terminalNode) {
+ public JsonOption(@NonNull TerminalNode terminalNode) {
super(terminalNode);
}
- public JsonConstraint(@NonNull TerminalNode beginNode, @NonNull ParserRuleContext endRule) {
+ public JsonOption(@NonNull TerminalNode beginNode, @NonNull ParserRuleContext endRule) {
super(beginNode, endRule);
}
- public JsonConstraint(@NonNull ParserRuleContext beginRule, @NonNull ParserRuleContext endRule) {
+ public JsonOption(@NonNull ParserRuleContext beginRule, @NonNull ParserRuleContext endRule) {
super(beginRule, endRule);
}
@Override
protected String doToString() {
- StringBuilder builder = new StringBuilder("JSON");
+ StringBuilder builder = new StringBuilder();
if (this.strictMode != null) {
builder.append(" ").append(this.strictMode.name());
}
+ if (this.truncate) {
+ builder.append(" TRUNCATE");
+ }
if (this.scalarsMode != null) {
builder.append(" ").append(this.scalarsMode.name().replace("_", " "));
}
+ if (this.pretty) {
+ builder.append(" PRETTY");
+ }
+ if (this.ascii) {
+ builder.append(" ASCII");
+ }
if (this.uniqueMode != null) {
builder.append(" ").append(this.uniqueMode.name().replace("_", " "));
}
if (this.wrapperMode != null) {
builder.append(" ").append(this.wrapperMode.name().replace("_", " "));
}
+ if (this.asis) {
+ builder.append(" ASIS");
+ }
+ if (this.onOption != null) {
+ builder.append(" ").append(this.onOption);
+ }
+ if (this.multiValue) {
+ builder.append(" MULTIVALUE");
+ }
return builder.toString();
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/insert/Insert.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/insert/Insert.java
index 005fd3c735..dc1c87ab20 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/insert/Insert.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/insert/Insert.java
@@ -54,6 +54,9 @@ public class Insert extends BaseStatement {
private boolean first;
private boolean replace;
private boolean ignore;
+ private boolean highPriority;
+ private boolean lowPriority;
+ private boolean overwrite;
private List onDuplicateKeyUpdateColumns;
private final List tableInsert;
private final ConditionalInsert conditionalInsert;
@@ -78,6 +81,9 @@ public Insert(@NonNull ParserRuleContext context, @NonNull Insert target) {
this.ignore = target.ignore;
this.onDuplicateKeyUpdateColumns = target.onDuplicateKeyUpdateColumns;
this.tableInsert = target.tableInsert;
+ this.overwrite = target.overwrite;
+ this.highPriority = target.highPriority;
+ this.lowPriority = target.lowPriority;
this.conditionalInsert = target.conditionalInsert;
}
@@ -95,6 +101,11 @@ public String toString() {
} else {
builder.append("INSERT");
}
+ if (this.highPriority) {
+ builder.append(" HIGH_PRIORITY");
+ } else if (this.lowPriority) {
+ builder.append(" LOW_PRIORITY");
+ }
if (this.all) {
builder.append(" ALL");
} else if (this.first) {
@@ -102,6 +113,9 @@ public String toString() {
} else if (this.ignore) {
builder.append(" IGNORE");
}
+ if (this.overwrite) {
+ builder.append(" OVERWRITE");
+ }
if (CollectionUtils.isNotEmpty(this.tableInsert)) {
builder.append(" ").append(this.tableInsert.stream()
.map(InsertTable::toString).collect(Collectors.joining("\n")));
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/ExpressionReference.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/ExpressionReference.java
index e586f48d26..c15143fefc 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/ExpressionReference.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/ExpressionReference.java
@@ -51,6 +51,8 @@ public class ExpressionReference extends BaseStatement implements FromReference
@Setter
private FlashbackUsage flashbackUsage;
@Setter
+ private boolean lateral;
+ @Setter
private List aliasColumns;
public ExpressionReference(@NonNull ParserRuleContext context,
@@ -67,7 +69,11 @@ public ExpressionReference(@NonNull Expression target, String alias) {
@Override
public String toString() {
- StringBuilder builder = new StringBuilder(this.target.toString());
+ StringBuilder builder = new StringBuilder();
+ if (this.lateral) {
+ builder.append("LATERAL ");
+ }
+ builder.append(this.target.toString());
if (this.flashbackUsage != null) {
builder.append(" ").append(this.flashbackUsage.toString());
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/PartitionUsage.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/PartitionUsage.java
index c9d0c02bc8..fbd2d6711c 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/PartitionUsage.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/PartitionUsage.java
@@ -16,10 +16,13 @@
package com.oceanbase.tools.sqlparser.statement.select;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
import org.antlr.v4.runtime.ParserRuleContext;
import com.oceanbase.tools.sqlparser.statement.BaseStatement;
+import com.oceanbase.tools.sqlparser.statement.Expression;
import lombok.EqualsAndHashCode;
import lombok.Getter;
@@ -39,16 +42,33 @@ public class PartitionUsage extends BaseStatement {
private final PartitionType type;
private final List nameList;
+ private final Map externalTablePartition;
public PartitionUsage(@NonNull ParserRuleContext context, PartitionType type, @NonNull List nameList) {
super(context);
this.type = type;
this.nameList = nameList;
+ this.externalTablePartition = null;
}
public PartitionUsage(PartitionType type, @NonNull List nameList) {
this.type = type;
this.nameList = nameList;
+ this.externalTablePartition = null;
+ }
+
+ public PartitionUsage(@NonNull ParserRuleContext context, PartitionType type,
+ @NonNull Map externalTablePartition) {
+ super(context);
+ this.type = type;
+ this.nameList = null;
+ this.externalTablePartition = externalTablePartition;
+ }
+
+ public PartitionUsage(PartitionType type, @NonNull Map externalTablePartition) {
+ this.type = type;
+ this.nameList = null;
+ this.externalTablePartition = externalTablePartition;
}
@Override
@@ -59,7 +79,11 @@ public String toString() {
} else {
buffer.append("SUBPARTITION ");
}
- return buffer.append("(").append(String.join(",", nameList)).append(")").toString();
+ if (this.nameList != null) {
+ return buffer.append("(").append(String.join(",", nameList)).append(")").toString();
+ }
+ return buffer.append("(").append(this.externalTablePartition.entrySet().stream()
+ .map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(", "))).append(")").toString();
}
}
diff --git a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/SelectBody.java b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/SelectBody.java
index 54886df64c..5423e22d38 100644
--- a/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/SelectBody.java
+++ b/libs/ob-sql-parser/src/main/java/com/oceanbase/tools/sqlparser/statement/select/SelectBody.java
@@ -54,14 +54,16 @@ public class SelectBody extends BaseExpression {
private List with = new ArrayList<>();
private boolean recursive;
private List groupBy = new ArrayList<>();
- boolean withRollUp;
- boolean withCheckOption;
+ private boolean withRollUp;
+ private boolean withCheckOption;
+ private boolean approximate;
private List windows = new ArrayList<>();
private Fetch fetch;
private Limit limit;
private ForUpdate forUpdate;
private OrderBy orderBy;
private boolean lockInShareMode;
+
private RelatedSelectBody relatedSelect;
private final List> values;
private final List froms;
@@ -92,6 +94,7 @@ public SelectBody(@NonNull ParserRuleContext context, @NonNull SelectBody other)
this.with = other.with;
this.recursive = other.recursive;
this.groupBy = other.groupBy;
+ this.lockInShareMode = other.lockInShareMode;
this.withRollUp = other.withRollUp;
this.withCheckOption = other.withCheckOption;
this.windows = other.windows;
@@ -102,6 +105,7 @@ public SelectBody(@NonNull ParserRuleContext context, @NonNull SelectBody other)
this.froms = other.froms;
this.selectItems = other.selectItems;
this.forUpdate = other.forUpdate;
+ this.approximate = other.approximate;
this.values = other.values;
}
@@ -182,6 +186,9 @@ public String doToString() {
if (this.orderBy != null) {
builder.append(" ").append(this.orderBy.toString());
}
+ if (this.approximate) {
+ builder.append(" APPROXIMATE");
+ }
if (this.fetch != null) {
builder.append(" ").append(this.fetch.toString());
}
diff --git a/libs/ob-sql-parser/src/main/resources/obmysql/sql/OBParser.g4 b/libs/ob-sql-parser/src/main/resources/obmysql/sql/OBParser.g4
index 16a1c8e18b..529f4bb9e0 100644
--- a/libs/ob-sql-parser/src/main/resources/obmysql/sql/OBParser.g4
+++ b/libs/ob-sql-parser/src/main/resources/obmysql/sql/OBParser.g4
@@ -323,11 +323,6 @@ simple_expr
| LeftBracket expr_list RightBracket
;
-search_expr
- : expr_const
- | func_expr
- ;
-
expr
: (NOT|USER_VARIABLE SET_VAR) expr
| LeftParen expr RightParen
@@ -1025,11 +1020,6 @@ reference_action
| SET DEFAULT
;
-opt_match_option
- : MATCH match_action
- | empty
- ;
-
match_action
: SIMPLE
| FULL
@@ -1037,8 +1027,8 @@ match_action
;
column_definition
- : column_definition_ref data_type opt_column_attribute_list? (REFERENCES relation_factor LeftParen column_name_list RightParen opt_match_option opt_reference_option_list)? (FIRST | (BEFORE column_name) | (AFTER column_name))?
- | column_definition_ref data_type (GENERATED opt_generated_option_list)? AS LeftParen expr RightParen (VIRTUAL | STORED)? opt_generated_column_attribute_list? (REFERENCES relation_factor LeftParen column_name_list RightParen opt_match_option opt_reference_option_list)? (FIRST | (BEFORE column_name) | (AFTER column_name))?
+ : column_definition_ref data_type opt_column_attribute_list? references_clause? (FIRST | (BEFORE column_name) | (AFTER column_name))?
+ | column_definition_ref data_type (GENERATED opt_generated_option_list)? AS LeftParen expr RightParen (VIRTUAL | STORED)? opt_generated_column_attribute_list? references_clause? (FIRST | (BEFORE column_name) | (AFTER column_name))?
| column_definition_ref SERIAL opt_column_attribute_list? (FIRST | (BEFORE column_name) | (AFTER column_name))?
;
@@ -1283,8 +1273,8 @@ column_attribute
| COLLATE collation_name
| SKIP_INDEX LeftParen (skip_index_type | (opt_skip_index_type_list Comma skip_index_type))? RightParen
| lob_chunk_size
- | COLUMN_FORMAT (DEFAULT|FIXED|DYNAMIC)
- | STORAGE (DEFAULT|DISK|MEMORY)
+ | COLUMN_FORMAT col_attri_value=(DEFAULT|FIXED|DYNAMIC)
+ | STORAGE col_attri_value=(DEFAULT|DISK|MEMORY)
;
now_or_signed_literal
@@ -1359,7 +1349,6 @@ table_option
| AUTO_INCREMENT_CACHE_SIZE COMP_EQ? INTNUM
| PARTITION_TYPE COMP_EQ? USER_SPECIFIED
| PROPERTIES COMP_EQ? LeftParen external_properties_list RightParen
-
| lob_storage_clause
| MICRO_INDEX_CLUSTERED COMP_EQ? BOOL_VALUE
| AUTO_REFRESH COMP_EQ? (OFF|IMMEDIATE|INTERVAL)
@@ -1672,7 +1661,11 @@ external_properties_list
;
external_properties
- : ((((ACCESSID|ACCESSKEY)|(ACCESSTYPE|TYPE))|((ENDPOINT|STSTOKEN)|(PROJECT_NAME|SCHEMA_NAME)))|((COMPRESSION_CODE|QUOTA_NAME)|TABLE_NAME)) COMP_EQ STRING_VALUE
+ : external_properties_key COMP_EQ STRING_VALUE
+ ;
+
+external_properties_key
+ : ((((ACCESSID|ACCESSKEY)|(ACCESSTYPE|TYPE))|((ENDPOINT|STSTOKEN)|(PROJECT_NAME|SCHEMA_NAME)))|((COMPRESSION_CODE|QUOTA_NAME)|TABLE_NAME))
;
external_file_format_list
@@ -1868,7 +1861,7 @@ index_option
| COMMENT STRING_VALUE
| (STORING|CTXCAT) LeftParen column_name_list RightParen
| WITH ROWID
- | WITH PARSER STRING_VALUE
+ | WITH PARSER relation_name
| WITH LeftParen vec_index_params RightParen
| index_using_algorithm
| visibility_option
@@ -2027,7 +2020,6 @@ select_stmt
: with_clause? (select_no_parens into_clause? |select_with_parens)
;
-
select_with_parens
: LeftParen with_clause? (select_no_parens |select_with_parens) RightParen
;
@@ -3488,14 +3480,17 @@ rename_table_action
alter_table_stmt
: ALTER EXTERNAL? TABLE relation_factor alter_table_actions?
- | ALTER TABLE relation_factor alter_column_group_option
- | ALTER EXTERNAL TABLE relation_factor ADD PARTITION LeftParen add_external_table_partition_actions RightParen LOCATION STRING_VALUE
- | ALTER EXTERNAL TABLE relation_factor DROP PARTITION LOCATION STRING_VALUE
+ | ALTER TABLE relation_factor alter_column_group_action
+ | ALTER EXTERNAL TABLE relation_factor alter_external_table_action
+ ;
+
+alter_external_table_action
+ : ADD PARTITION LeftParen add_external_table_partition_actions? RightParen LOCATION STRING_VALUE
+ | DROP PARTITION LOCATION STRING_VALUE
;
add_external_table_partition_actions
: add_external_table_partition_action
- | empty
| add_external_table_partition_actions Comma add_external_table_partition_action
;
@@ -3585,13 +3580,13 @@ visibility_option
| INVISIBLE
;
-alter_column_group_option
+alter_column_group_action
: (ADD|DROP) COLUMN GROUP LeftParen column_group_list RightParen
;
alter_column_option
: ADD COLUMN? column_definition
- | ADD COLUMN? LeftParen column_definition_list RightParen
+ | ADD COLUMN? LeftParen column_definition_list RightParen lob_storage_clause?
| DROP column_definition_ref (CASCADE | RESTRICT)?
| DROP COLUMN column_definition_ref (CASCADE | RESTRICT)?
| ALTER COLUMN? column_definition_ref alter_column_behavior
@@ -4468,7 +4463,39 @@ vec_index_param_value
;
json_query_expr
- : JSON_QUERY LeftParen simple_expr Comma complex_string_literal (RETURNING cast_data_type)? TRUNCATE? ((ALLOW SCALARS) | (DISALLOW SCALARS))? PRETTY? ASCII? ((WITHOUT WRAPPER) | (WITHOUT ARRAY WRAPPER) | (WITH WRAPPER) | (WITH ARRAY WRAPPER) | (WITH UNCONDITIONAL WRAPPER) | (WITH CONDITIONAL WRAPPER) | (WITH UNCONDITIONAL ARRAY WRAPPER) | (WITH CONDITIONAL ARRAY WRAPPER))? ASIS? (on_empty_query | on_error_query | on_mismatch_query | (on_error_query on_empty_query) | (on_empty_query on_error_query) | (on_error_query on_mismatch_query) | (on_empty_query on_mismatch_query) | (on_error_query on_empty_query on_mismatch_query) | (on_empty_query on_error_query on_mismatch_query))? MULTIVALUE? RightParen
+ : JSON_QUERY LeftParen simple_expr Comma complex_string_literal (RETURNING cast_data_type)? json_query_opt RightParen
+ ;
+
+json_query_opt
+ : TRUNCATE? scalars_opt? PRETTY? ASCII? wrapper_opts? ASIS? json_query_on_opt? MULTIVALUE?
+ ;
+
+scalars_opt
+ : ALLOW SCALARS
+ | DISALLOW SCALARS
+ ;
+
+wrapper_opts
+ : WITHOUT WRAPPER
+ | WITHOUT ARRAY WRAPPER
+ | WITH WRAPPER
+ | WITH ARRAY WRAPPER
+ | WITH UNCONDITIONAL WRAPPER
+ | WITH CONDITIONAL WRAPPER
+ | WITH UNCONDITIONAL ARRAY WRAPPER
+ | WITH CONDITIONAL ARRAY WRAPPER
+ ;
+
+json_query_on_opt
+ : on_empty_query
+ | on_error_query
+ | on_mismatch_query
+ | on_error_query on_empty_query
+ | on_empty_query on_error_query
+ | on_error_query on_mismatch_query
+ | on_empty_query on_mismatch_query
+ | on_error_query on_empty_query on_mismatch_query
+ | on_empty_query on_error_query on_mismatch_query
;
opt_response_query
@@ -4489,7 +4516,17 @@ on_empty_query
;
json_value_expr
- : JSON_VALUE LeftParen simple_expr Comma complex_string_literal (RETURNING cast_data_type)? TRUNCATE? ASCII? (on_empty | on_error | (on_empty on_error))? RightParen
+ : JSON_VALUE LeftParen simple_expr Comma complex_string_literal (RETURNING cast_data_type)? json_value_opt RightParen
+ ;
+
+json_value_opt
+ : TRUNCATE? ASCII? json_value_on_opt?
+ ;
+
+json_value_on_opt
+ : on_empty
+ | on_error
+ | on_empty on_error
;
opt_on_empty_or_error
diff --git a/libs/ob-sql-parser/src/main/resources/oboracle/sql/OBParser.g4 b/libs/ob-sql-parser/src/main/resources/oboracle/sql/OBParser.g4
index 35e0e9df9a..fc6045b429 100644
--- a/libs/ob-sql-parser/src/main/resources/oboracle/sql/OBParser.g4
+++ b/libs/ob-sql-parser/src/main/resources/oboracle/sql/OBParser.g4
@@ -1590,9 +1590,7 @@ table_option
| PATTERN COMP_EQ? STRING_VALUE
| PARTITION_TYPE COMP_EQ? USER_SPECIFIED
| MICRO_INDEX_CLUSTERED COMP_EQ? BOOL_VALUE
- | AUTO_REFRESH COMP_EQ? OFF
- | AUTO_REFRESH COMP_EQ? IMMEDIATE
- | AUTO_REFRESH COMP_EQ? INTERVAL
+ | AUTO_REFRESH COMP_EQ? (OFF|IMMEDIATE|INTERVAL)
;
parallel_option
@@ -1923,7 +1921,11 @@ external_properties_list
;
external_properties
- : ((((ACCESSID|ACCESSKEY)|(ACCESSTYPE|TYPE))|((ENDPOINT|STSTOKEN)|(PROJECT_NAME|SCHEMA_NAME)))|((COMPRESSION_CODE|QUOTA_NAME)|TABLE_NAME)) COMP_EQ STRING_VALUE
+ : external_properties_key COMP_EQ STRING_VALUE
+ ;
+
+external_properties_key
+ : ((((ACCESSID|ACCESSKEY)|(ACCESSTYPE|TYPE))|((ENDPOINT|STSTOKEN)|(PROJECT_NAME|SCHEMA_NAME)))|((COMPRESSION_CODE|QUOTA_NAME)|TABLE_NAME))
;
external_file_format_list
@@ -2892,12 +2894,11 @@ table_subquery
use_partition
: (PARTITION|SUBPARTITION) LeftParen name_list RightParen
- | PARTITION LeftParen external_table_partitions RightParen
+ | PARTITION LeftParen external_table_partitions? RightParen
;
external_table_partitions
: external_table_partition
- | empty
| external_table_partitions Comma external_table_partition
;
@@ -3704,14 +3705,17 @@ alter_index_option_oracle
alter_table_stmt
: ALTER EXTERNAL? TABLE relation_factor alter_table_actions
- | ALTER TABLE relation_factor alter_column_group_option
- | ALTER EXTERNAL TABLE relation_factor ADD PARTITION LeftParen add_external_table_partition_actions RightParen LOCATION STRING_VALUE
- | ALTER EXTERNAL TABLE relation_factor DROP PARTITION LOCATION STRING_VALUE
+ | ALTER TABLE relation_factor alter_column_group_action
+ | ALTER EXTERNAL TABLE relation_factor alter_external_table_action
+ ;
+
+alter_external_table_action
+ : ADD PARTITION LeftParen add_external_table_partition_actions? RightParen LOCATION STRING_VALUE
+ | DROP PARTITION LOCATION STRING_VALUE
;
add_external_table_partition_actions
: add_external_table_partition_action
- | empty
| add_external_table_partition_actions Comma add_external_table_partition_action
;
@@ -3815,7 +3819,7 @@ visibility_option
| INVISIBLE
;
-alter_column_group_option
+alter_column_group_action
: (ADD|DROP) COLUMN GROUP LeftParen column_group_list RightParen
;
@@ -4579,7 +4583,11 @@ date_unit_for_extract
;
json_mergepatch_expr
- : JSON_MERGEPATCH LeftParen bit_expr Comma bit_expr js_mp_return_clause? opt_json_mergepatch json_mergepatch_on_error? RightParen
+ : JSON_MERGEPATCH LeftParen bit_expr Comma bit_expr js_mp_return_clause? json_mergepatch_opt RightParen
+ ;
+
+json_mergepatch_opt
+ : opt_json_mergepatch json_mergepatch_on_error?
;
json_mergepatch_on_error
@@ -4623,7 +4631,11 @@ js_array_return_clause
;
json_value_expr
- : JSON_VALUE LeftParen js_doc_expr Comma js_literal opt_js_value_returning_type TRUNCATE? ASCII? json_value_on_opt? RightParen
+ : JSON_VALUE LeftParen js_doc_expr Comma js_literal opt_js_value_returning_type json_value_opt RightParen
+ ;
+
+json_value_opt
+ : TRUNCATE? ASCII? json_value_on_opt?
;
json_equal_expr
@@ -4735,7 +4747,11 @@ json_exists_response_type
;
json_query_expr
- : JSON_QUERY LeftParen js_doc_expr Comma js_literal (RETURNING js_query_return_type)? TRUNCATE? scalars_opt? PRETTY? ASCII? wrapper_opts? ASIS? json_query_on_opt? MULTIVALUE? RightParen
+ : JSON_QUERY LeftParen js_doc_expr Comma js_literal (RETURNING js_query_return_type)? json_query_opt RightParen
+ ;
+
+json_query_opt
+ : TRUNCATE? scalars_opt? PRETTY? ASCII? wrapper_opts? ASIS? json_query_on_opt? MULTIVALUE?
;
json_query_on_opt
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableActionFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableActionFactoryTest.java
index 08c8c26752..0684519be0 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableActionFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableActionFactoryTest.java
@@ -35,6 +35,7 @@
import com.oceanbase.tools.sqlparser.statement.common.CharacterType;
import com.oceanbase.tools.sqlparser.statement.common.GeneralDataType;
import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
+import com.oceanbase.tools.sqlparser.statement.common.mysql.LobStorageOption;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition;
import com.oceanbase.tools.sqlparser.statement.createtable.ConstraintState;
import com.oceanbase.tools.sqlparser.statement.createtable.HashPartition;
@@ -147,6 +148,23 @@ public void generate_addColumns_succeed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_addColumnsWithLobStorage_succeed() {
+ StatementFactory factory = new MySQLAlterTableActionFactory(
+ getActionContext("add (id varchar(64), id1 blob) json(col) store as (chunk 'aas' chunk 123)"));
+ AlterTableAction actual = factory.generate();
+
+ AlterTableAction expect = new AlterTableAction();
+ CharacterType t1 = new CharacterType("varchar", new BigDecimal("64"));
+ ColumnDefinition d1 = new ColumnDefinition(new ColumnReference(null, null, "id"), t1);
+ GeneralDataType t2 = new GeneralDataType("blob", null);
+ ColumnDefinition d2 = new ColumnDefinition(new ColumnReference(null, null, "id1"), t2);
+ expect.setAddColumns(Arrays.asList(d1, d2));
+ LobStorageOption storageOption = new LobStorageOption("col", Arrays.asList("'aas'", "123"));
+ expect.setLobStorageOption(storageOption);
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_dropColumnCascade_succeed() {
StatementFactory factory = new MySQLAlterTableActionFactory(
@@ -208,6 +226,19 @@ public void generate_alterColumn_succeed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_alterColumn1_succeed() {
+ StatementFactory factory = new MySQLAlterTableActionFactory(
+ getActionContext("alter column a.b set default (12)"));
+ AlterTableAction actual = factory.generate();
+
+ AlterTableAction expect = new AlterTableAction();
+ AlterColumnBehavior behavior = new AlterColumnBehavior();
+ behavior.setDefaultValue(new ConstExpression("12"));
+ expect.alterColumnBehavior(new ColumnReference(null, "a", "b"), behavior);
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_alterColumnDropDefault_succeed() {
StatementFactory factory = new MySQLAlterTableActionFactory(
@@ -642,6 +673,17 @@ public void generate_dropForeignConstraints_succeed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_exchangePartition_succeed() {
+ StatementFactory factory = new MySQLAlterTableActionFactory(
+ getActionContext("exchange partition p1 with table tbl without validation"));
+ AlterTableAction actual = factory.generate();
+
+ AlterTableAction expect = new AlterTableAction();
+ expect.setExchangePartition("p1", new RelationFactor("tbl"));
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_dropPrimaryKey_succeed() {
StatementFactory factory = new MySQLAlterTableActionFactory(
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableFactoryTest.java
index 7cce672361..cff06c4a86 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLAlterTableFactoryTest.java
@@ -18,6 +18,8 @@
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.CharStreams;
@@ -29,6 +31,7 @@
import com.oceanbase.tools.sqlparser.obmysql.OBLexer;
import com.oceanbase.tools.sqlparser.obmysql.OBParser;
import com.oceanbase.tools.sqlparser.obmysql.OBParser.Alter_table_stmtContext;
+import com.oceanbase.tools.sqlparser.statement.Expression;
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.CharacterType;
@@ -37,6 +40,7 @@
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition;
import com.oceanbase.tools.sqlparser.statement.createtable.TableOptions;
import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
+import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
public class MySQLAlterTableFactoryTest {
@@ -71,6 +75,52 @@ public void generate_alterTable1_succeed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_alterExternalTableAddEmptyPartition_succeed() {
+ StatementFactory factory = new MySQLAlterTableFactory(
+ getAlterContext("alter external table a.b add partition () location 'abcd'"));
+ AlterTable actual = factory.generate();
+
+ AlterTableAction action = new AlterTableAction();
+ action.setExternalTableLocation("'abcd'");
+ action.setAddExternalTablePartition(new HashMap<>());
+ AlterTable expect = new AlterTable(getRelationFactor("a", "b"), Collections.singletonList(action));
+ expect.setExternal(true);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_alterExternalTableAddPartition_succeed() {
+ StatementFactory factory = new MySQLAlterTableFactory(
+ getAlterContext(
+ "alter external table a.b add partition (col='aaa', col1=@@global.ss) location 'abcd'"));
+ AlterTable actual = factory.generate();
+
+ AlterTableAction action = new AlterTableAction();
+ action.setExternalTableLocation("'abcd'");
+ Map partitions = new HashMap<>();
+ partitions.put("col", new ConstExpression("'aaa'"));
+ partitions.put("col1", new ConstExpression("@@global.ss"));
+ action.setAddExternalTablePartition(partitions);
+ AlterTable expect = new AlterTable(getRelationFactor("a", "b"), Collections.singletonList(action));
+ expect.setExternal(true);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_alterExternalTableDropPartition_succeed() {
+ StatementFactory factory = new MySQLAlterTableFactory(
+ getAlterContext("alter external table a.b drop partition location 'abcd'"));
+ AlterTable actual = factory.generate();
+
+ AlterTableAction action = new AlterTableAction();
+ action.setExternalTableLocation("'abcd'");
+ action.setDropExternalTablePartition(true);
+ AlterTable expect = new AlterTable(getRelationFactor("a", "b"), Collections.singletonList(action));
+ expect.setExternal(true);
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_alterExternalTable1_succeed() {
StatementFactory factory = new MySQLAlterTableFactory(
@@ -121,4 +171,5 @@ private RelationFactor getRelationFactor(String schema, String relation) {
relationFactor.setSchema(schema);
return relationFactor;
}
+
}
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateIndexFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateIndexFactoryTest.java
index 7fddcceb7e..7317b280cd 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateIndexFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateIndexFactoryTest.java
@@ -15,9 +15,7 @@
*/
package com.oceanbase.tools.sqlparser.adapter;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.CharStreams;
@@ -194,13 +192,20 @@ public void generate_withColumnGroup_customGroup_succeed() {
@Test
public void generate_CreateVectorIndex_Succeed() {
StatementFactory factory = new MySQLCreateIndexFactory(
- getCreateIdxContext("create vector index vec_idx1 on t_vec(c2) with (distance=l2, type=hnsw);"));
+ getCreateIdxContext("create vector index vec_idx1 on t_vec(c2) " +
+ "key_block_size=1234 with (distance=l2, type=hnsw);"));
CreateIndex actual = factory.generate();
CreateIndex expected = new CreateIndex(new RelationFactor("vec_idx1"),
- new RelationFactor("t_vec"), Arrays.asList(
+ new RelationFactor("t_vec"), Collections.singletonList(
new SortColumn(new ColumnReference(null, null, "c2"))));
- expected.setIndexOptions(new IndexOptions());
+ IndexOptions indexOptions = new IndexOptions();
+ indexOptions.setKeyBlockSize(1234);
+ Map params = new HashMap<>();
+ params.put("distance", "l2");
+ params.put("type", "hnsw");
+ indexOptions.setVectorIndexParams(params);
+ expected.setIndexOptions(indexOptions);
expected.setVector(true);
Assert.assertEquals(expected, actual);
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateTableFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateTableFactoryTest.java
index 7ff458254f..0d203c3201 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateTableFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLCreateTableFactoryTest.java
@@ -39,6 +39,7 @@
import com.oceanbase.tools.sqlparser.statement.common.ColumnGroupElement;
import com.oceanbase.tools.sqlparser.statement.common.DataType;
import com.oceanbase.tools.sqlparser.statement.common.RelationFactor;
+import com.oceanbase.tools.sqlparser.statement.common.mysql.LobStorageOption;
import com.oceanbase.tools.sqlparser.statement.common.mysql.VectorType;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnAttributes;
import com.oceanbase.tools.sqlparser.statement.createtable.ColumnDefinition;
@@ -143,6 +144,23 @@ public void generate_createTableAsSelect_generateSucceed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_createTableAsSelectIgnore_generateSucceed() {
+ Create_table_stmtContext context =
+ getCreateTableContext("create table any_schema.abcd ignore as select * from tab");
+ StatementFactory factory = new MySQLCreateTableFactory(context);
+ CreateTable actual = factory.generate();
+
+ CreateTable expect = new CreateTable(context, getRelationFactor("any_schema", "abcd"));
+ expect.setIgnore(true);
+ NameReference from = new NameReference(null, "tab", null);
+ SelectBody selectBody =
+ new SelectBody(Collections.singletonList(new Projection()), Collections.singletonList(from));
+ Select select = new Select(selectBody);
+ expect.setAs(select);
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_sortKey_succeed() {
Create_table_stmtContext context =
@@ -365,18 +383,60 @@ public void generate_physicalAttrs_succeed() {
@Test
public void generate_formatTableOp_succeed() {
- Create_table_stmtContext context = getCreateTableContext(
- "create table any_schema.abcd (id varchar(64)) kv_attributes='12' format=(ENCODING='aaaa',LINE_DELIMITER=123,"
- + "SKIP_HEADER=12,"
- + "EMPTY_FIELD_AS_NULL=true,NULL_IF_EXETERNAL=(1,2,3))");
+ Create_table_stmtContext context = getCreateTableContext("create table any_schema.abcd (id varchar(64)) "
+ + "kv_attributes='12' "
+ + "key_block_size=456 "
+ + "AUTO_INCREMENT_CACHE_SIZE=667 "
+ + "partition_type=USER_SPECIFIED "
+ + "properties=(ACCESSID='abcd', PROJECT_NAME='ooop') "
+ + "json(col) store as (chunk 'aas' chunk 123) "
+ + "micro_index_clustered=true "
+ + "auto_refresh=OFF "
+ + "max_rows=123445 "
+ + "min_rows=9879 "
+ + "password='asdasd' "
+ + "pack_keys=default "
+ + "connection='asasdasd' "
+ + "data directory='ooopi' "
+ + "index directory='indxasdasd' "
+ + "encryption='asdasdasdas' "
+ + "stats_auto_recalc=default "
+ + "stats_persistent=default "
+ + "stats_sample_pages=3345 "
+ + "union=(col1, col2) "
+ + "insert_method=FIRST "
+ + "format=(ENCODING='aaaa',LINE_DELIMITER=123,SKIP_HEADER=12,EMPTY_FIELD_AS_NULL=true," +
+ "NULL_IF_EXETERNAL=(1,2,3),COMPRESSION=col3)");
StatementFactory factory = new MySQLCreateTableFactory(context);
CreateTable actual = factory.generate();
-
CreateTable expect = new CreateTable(context, getRelationFactor("any_schema", "abcd"));
DataType dataType = new CharacterType("varchar", new BigDecimal("64"));
expect.setTableElements(
Collections.singletonList(new ColumnDefinition(new ColumnReference(null, null, "id"), dataType)));
TableOptions tableOptions = new TableOptions();
+ tableOptions.setAutoIncrementCacheSize(667);
+ tableOptions.setDataDirectory("'ooopi'");
+ tableOptions.setIndexDirectory("'indxasdasd'");
+ tableOptions.setStatsAutoRecalc("default");
+ tableOptions.setStatsPersistent("default");
+ tableOptions.setStatsSamplePages("3345");
+ tableOptions.setUnion(Arrays.asList(new RelationFactor("col1"), new RelationFactor("col2")));
+ tableOptions.setInsertMethod("FIRST");
+ tableOptions.setEncryption("'asdasdasdas'");
+ tableOptions.setPartitionType("USER_SPECIFIED");
+ Map externalProperties = new HashMap<>();
+ externalProperties.put("ACCESSID", "'abcd'");
+ externalProperties.put("PROJECT_NAME", "'ooop'");
+ tableOptions.setExternalProperties(externalProperties);
+ LobStorageOption storageOption = new LobStorageOption("col", Arrays.asList("'aas'", "123"));
+ tableOptions.setMicroIndexClustered(true);
+ tableOptions.setLobStorageOption(storageOption);
+ tableOptions.setAutoRefresh("OFF");
+ tableOptions.setMaxRows(123445);
+ tableOptions.setMinRows(9879);
+ tableOptions.setPassword("'asdasd'");
+ tableOptions.setPackKeys("default");
+ tableOptions.setConnection("'asasdasd'");
Map map = new HashMap<>();
map.put("ENCODING", new ConstExpression("'aaaa'"));
map.put("EMPTY_FIELD_AS_NULL", new BoolValue(true));
@@ -386,8 +446,13 @@ public void generate_formatTableOp_succeed() {
es.addExpression(new ConstExpression("2"));
es.addExpression(new ConstExpression("3"));
map.put("NULL_IF_EXETERNAL", es);
+ map.put("COMPRESSION", new ConstExpression("col3"));
map.put("LINE_DELIMITER", new ConstExpression("123"));
+ tableOptions.setKeyBlockSize(456);
+
tableOptions.setFormat(map);
+ tableOptions.setKeyBlockSize(456);
+ tableOptions.setAutoIncrementCacheSize(667);
tableOptions.setKvAttributes("'12'");
expect.setTableOptions(tableOptions);
Assert.assertEquals(expect, actual);
@@ -507,7 +572,12 @@ public void generate_WithVectorIndex_Succeed() {
SortColumn indexColumn = new SortColumn(new ColumnReference(null, null, "c1"));
OutOfLineIndex index = new OutOfLineIndex("idx1", Collections.singletonList(indexColumn));
index.setVector(true);
- index.setIndexOptions(new IndexOptions());
+ IndexOptions indexOptions = new IndexOptions();
+ index.setIndexOptions(indexOptions);
+ Map params = new HashMap<>();
+ params.put("distance", "L2");
+ params.put("type", "hnsw");
+ indexOptions.setVectorIndexParams(params);
expect.setTableElements(
Arrays.asList(new ColumnDefinition(new ColumnReference(null, null, "c1"), dataType), index));
Assert.assertEquals(expect, actual);
@@ -534,4 +604,5 @@ private RelationFactor getRelationFactor(String schema, String relation) {
relationFactor.setSchema(schema);
return relationFactor;
}
+
}
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLExpressionFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLExpressionFactoryTest.java
index 3f875de38c..16c299ccf2 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLExpressionFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLExpressionFactoryTest.java
@@ -43,23 +43,7 @@
import com.oceanbase.tools.sqlparser.statement.common.WindowOffsetType;
import com.oceanbase.tools.sqlparser.statement.common.WindowSpec;
import com.oceanbase.tools.sqlparser.statement.common.WindowType;
-import com.oceanbase.tools.sqlparser.statement.expression.ArrayExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.BoolValue;
-import com.oceanbase.tools.sqlparser.statement.expression.CaseWhen;
-import com.oceanbase.tools.sqlparser.statement.expression.CollectionExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
-import com.oceanbase.tools.sqlparser.statement.expression.CompoundExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ExpressionParam;
-import com.oceanbase.tools.sqlparser.statement.expression.FullTextSearch;
-import com.oceanbase.tools.sqlparser.statement.expression.FunctionCall;
-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.*;
import com.oceanbase.tools.sqlparser.statement.select.OrderBy;
import com.oceanbase.tools.sqlparser.statement.select.SortDirection;
import com.oceanbase.tools.sqlparser.statement.select.SortKey;
@@ -222,6 +206,23 @@ public void generate_matchNaturalMode_generateSucceed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_matchNaturalModeWithQueryExpansion_generateSucceed() {
+ ExprContext context = getExprContext(
+ "match(col,tab.col,chz.tab.col) against ('abc' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ColumnReference(null, null, "col")));
+ params.add(new ExpressionParam(new ColumnReference(null, "tab", "col")));
+ params.add(new ExpressionParam(new ColumnReference("chz", "tab", "col")));
+ FullTextSearch expect = new FullTextSearch(params, "'abc'");
+ expect.setWithQueryExpansion(true);
+ expect.setSearchMode(TextSearchMode.NATURAL_LANGUAGE_MODE);
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_matchBooleanMode_generateSucceed() {
ExprContext context = getExprContext("match(col,tab.col,chz.tab.col) against ('abc' IN BOOLEAN MODE)");
@@ -338,6 +339,28 @@ public void generate_st_asmvt_generateFunctionCallSucceed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_lastRefreshScn_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("last_refresh_scn(123)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ FunctionCall expect = new FunctionCall("last_refresh_scn",
+ Collections.singletonList(new ExpressionParam(new ConstExpression("123"))));
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_sumOpnsize_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("sum_Opnsize(123)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ FunctionCall expect = new FunctionCall("sum_Opnsize",
+ Collections.singletonList(new ExpressionParam(new ConstExpression("123"))));
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_stddevPopExpr_generateFunctionCallSucceed() {
ExprContext context = getExprContext("STDDEV_POP(all 1)");
@@ -453,7 +476,7 @@ public void generate_groupConcat_generateFunctionCallSucceed() {
@Test
public void generate_castAsChar_generateFunctionCallSucceed() {
- ExprContext context = getExprContext("cast('abc' as character(15) binary)");
+ ExprContext context = getExprContext("cast('abc' as character(15) binary array)");
StatementFactory factory = new MySQLExpressionFactory(context);
Expression actual = factory.generate();
@@ -462,6 +485,7 @@ public void generate_castAsChar_generateFunctionCallSucceed() {
CharacterType type = new CharacterType("character", new BigDecimal(15));
type.setBinary(true);
p.addOption(type);
+ p.addOption(new ConstExpression("array"));
params.add(p);
FunctionCall expect = new FunctionCall("cast", params);
Assert.assertEquals(expect, actual);
@@ -756,6 +780,258 @@ public void generate_weightString3Int_generateFunctionCallSucceed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_jsonQueryExpr_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc')");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new JsonOption());
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExprFullOpts_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "TRUNCATE " +
+ "allow scalars " +
+ "pretty " +
+ "ASCII " +
+ "with unconditional array wrapper " +
+ "asis " +
+ "empty on empty empty array on error_p error_p on mismatch " +
+ "MULTIVALUE)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setTruncate(true);
+ jsonOpt.setScalarsMode(JsonOption.ScalarsMode.ALLOW_SCALARS);
+ jsonOpt.setPretty(true);
+ jsonOpt.setAscii(true);
+ jsonOpt.setMultiValue(true);
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITH_UNCONDITIONAL_ARRAY_WRAPPER);
+ jsonOpt.setAsis(true);
+ JsonOnOption jsonOnOption = new JsonOnOption();
+ jsonOnOption.setOnEmpty(new ConstExpression("empty"));
+ jsonOnOption.setOnError(new ConstExpression("empty array"));
+ jsonOnOption.setOnMismatches(Collections.singletonList(
+ new JsonOnOption.OnMismatch(new ConstExpression("error_p"), null)));
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExprFullOpts2_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "empty array on empty empty array on error_p error_p on mismatch)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ JsonOnOption jsonOnOption = new JsonOnOption();
+ jsonOnOption.setOnEmpty(new ConstExpression("empty array"));
+ jsonOnOption.setOnError(new ConstExpression("empty array"));
+ jsonOnOption.setOnMismatches(Collections.singletonList(
+ new JsonOnOption.OnMismatch(new ConstExpression("error_p"), null)));
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExprFullOpts4_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "empty object on empty empty array on error_p error_p on mismatch)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ JsonOnOption jsonOnOption = new JsonOnOption();
+ jsonOnOption.setOnEmpty(new ConstExpression("empty object"));
+ jsonOnOption.setOnError(new ConstExpression("empty array"));
+ jsonOnOption.setOnMismatches(Collections.singletonList(
+ new JsonOnOption.OnMismatch(new ConstExpression("error_p"), null)));
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExpr1_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "with array wrapper)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITH_ARRAY_WRAPPER);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExpr2_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "with conditional wrapper)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITH_CONDITIONAL_WRAPPER);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExpr3_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "with unconditional wrapper)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITH_UNCONDITIONAL_WRAPPER);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExpr4_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "with wrapper)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITH_WRAPPER);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExpr5_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "without wrapper)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITHOUT_WRAPPER);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExpr6_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "without array wrapper)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITHOUT_ARRAY_WRAPPER);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonQueryExprFullOpts1_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_QUERY('123', _utf8 'abc' " +
+ "returning double " +
+ "TRUNCATE " +
+ "disallow scalars " +
+ "pretty " +
+ "ASCII " +
+ "with conditional array wrapper " +
+ "asis " +
+ "error_p on empty empty object on error_p dot on mismatch " +
+ "MULTIVALUE)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ params.add(new ExpressionParam(new ConstExpression("_utf8 'abc'")));
+ FunctionCall expect = new FunctionCall("JSON_QUERY", params);
+ expect.addOption(new NumberType("double", null, null));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setTruncate(true);
+ jsonOpt.setScalarsMode(JsonOption.ScalarsMode.DISALLOW_SCALARS);
+ jsonOpt.setPretty(true);
+ jsonOpt.setAscii(true);
+ jsonOpt.setWrapperMode(JsonOption.WrapperMode.WITH_CONDITIONAL_ARRAY_WRAPPER);
+ jsonOpt.setAsis(true);
+ jsonOpt.setMultiValue(true);
+ JsonOnOption jsonOnOption = new JsonOnOption();
+ jsonOnOption.setOnEmpty(new ConstExpression("error_p"));
+ jsonOnOption.setOnError(new ConstExpression("empty object"));
+ jsonOnOption.setOnMismatches(Collections.singletonList(
+ new JsonOnOption.OnMismatch(new ConstExpression("dot"), null)));
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_jsonValueExpr_generateFunctionCallSucceed() {
ExprContext context = getExprContext("JSON_VALUE('123', _utf8 'abc' returning double TRUNCATE ASCII)");
@@ -768,8 +1044,10 @@ public void generate_jsonValueExpr_generateFunctionCallSucceed() {
params.add(p);
FunctionCall expect = new FunctionCall("JSON_VALUE", params);
expect.addOption(new NumberType("double", null, null));
- expect.addOption(new ConstExpression("TRUNCATE"));
- expect.addOption(new ConstExpression("ASCII"));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setTruncate(true);
+ jsonOpt.setAscii(true);
+ expect.addOption(jsonOpt);
Assert.assertEquals(expect, actual);
}
@@ -786,11 +1064,13 @@ public void generate_jsonValueExprOnEmpty_generateFunctionCallSucceed() {
params.add(p);
FunctionCall expect = new FunctionCall("JSON_VALUE", params);
expect.addOption(new NumberType("double", null, null));
- expect.addOption(new ConstExpression("TRUNCATE"));
- expect.addOption(new ConstExpression("ASCII"));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setTruncate(true);
+ jsonOpt.setAscii(true);
JsonOnOption jsonOnOption = new JsonOnOption();
jsonOnOption.setOnEmpty(new ConstExpression("error_p"));
- expect.addOption(jsonOnOption);
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
Assert.assertEquals(expect, actual);
}
@@ -807,11 +1087,13 @@ public void generate_jsonValueExprOnError_generateFunctionCallSucceed() {
params.add(p);
FunctionCall expect = new FunctionCall("JSON_VALUE", params);
expect.addOption(new NumberType("double", null, null));
- expect.addOption(new ConstExpression("TRUNCATE"));
- expect.addOption(new ConstExpression("ASCII"));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setTruncate(true);
+ jsonOpt.setAscii(true);
JsonOnOption jsonOnOption = new JsonOnOption();
jsonOnOption.setOnError(new NullExpression());
- expect.addOption(jsonOnOption);
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
Assert.assertEquals(expect, actual);
}
@@ -828,12 +1110,30 @@ public void generate_jsonValueExprOnErrorEmpty_generateFunctionCallSucceed() {
params.add(p);
FunctionCall expect = new FunctionCall("JSON_VALUE", params);
expect.addOption(new NumberType("double", null, null));
- expect.addOption(new ConstExpression("TRUNCATE"));
- expect.addOption(new ConstExpression("ASCII"));
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setTruncate(true);
+ jsonOpt.setAscii(true);
JsonOnOption jsonOnOption = new JsonOnOption();
jsonOnOption.setOnError(new NullExpression());
jsonOnOption.setOnEmpty(new ConstExpression("12"));
- expect.addOption(jsonOnOption);
+ jsonOpt.setOnOption(jsonOnOption);
+ expect.addOption(jsonOpt);
+ Assert.assertEquals(expect, actual);
+ }
+
+ @Test
+ public void generate_jsonValueExprNoOpt_generateFunctionCallSucceed() {
+ ExprContext context = getExprContext("JSON_VALUE('123', _utf8 'abc' returning double)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ConstExpression("'123'")));
+ FunctionParam p = new ExpressionParam(new ConstExpression("_utf8 'abc'"));
+ params.add(p);
+ FunctionCall expect = new FunctionCall("JSON_VALUE", params);
+ expect.addOption(new NumberType("double", null, null));
+ expect.addOption(new JsonOption());
Assert.assertEquals(expect, actual);
}
@@ -1430,6 +1730,20 @@ public void generate_vectorDistanceExpr_Succeed() {
Assert.assertEquals(expected, actual);
}
+ @Test
+ public void generate_vectorDistanceExpr1_Succeed() {
+ ExprContext context = getExprContext("VECTOR_DISTANCE(vector1, vector2, COSINE)");
+ StatementFactory factory = new MySQLExpressionFactory(context);
+ Expression actual = factory.generate();
+
+ List params = new ArrayList<>();
+ params.add(new ExpressionParam(new ColumnReference(null, null, "vector1")));
+ params.add(new ExpressionParam(new ColumnReference(null, null, "vector2")));
+ params.add(new ExpressionParam(new ConstExpression("COSINE")));
+ FunctionCall expected = new FunctionCall("VECTOR_DISTANCE", params);
+ Assert.assertEquals(expected, actual);
+ }
+
@Test
public void generate_AnyArrayExpr_1_Succeed() {
ExprContext context = getExprContext("\"hel\" = ANY([\"hello\", \"hi\"])");
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLFromReferenceFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLFromReferenceFactoryTest.java
index c840f8744d..62d9da22a0 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLFromReferenceFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLFromReferenceFactoryTest.java
@@ -15,10 +15,7 @@
*/
package com.oceanbase.tools.sqlparser.adapter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
import org.antlr.v4.runtime.BailErrorStrategy;
import org.antlr.v4.runtime.CharStreams;
@@ -38,14 +35,7 @@
import com.oceanbase.tools.sqlparser.statement.common.BraceBlock;
import com.oceanbase.tools.sqlparser.statement.common.GeneralDataType;
import com.oceanbase.tools.sqlparser.statement.common.NumberType;
-import com.oceanbase.tools.sqlparser.statement.expression.ColumnReference;
-import com.oceanbase.tools.sqlparser.statement.expression.CompoundExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ConstExpression;
-import com.oceanbase.tools.sqlparser.statement.expression.ExpressionParam;
-import com.oceanbase.tools.sqlparser.statement.expression.FunctionCall;
-import com.oceanbase.tools.sqlparser.statement.expression.FunctionParam;
-import com.oceanbase.tools.sqlparser.statement.expression.JsonOnOption;
-import com.oceanbase.tools.sqlparser.statement.expression.NullExpression;
+import com.oceanbase.tools.sqlparser.statement.expression.*;
import com.oceanbase.tools.sqlparser.statement.select.ExpressionReference;
import com.oceanbase.tools.sqlparser.statement.select.FlashBackType;
import com.oceanbase.tools.sqlparser.statement.select.FlashbackUsage;
@@ -169,6 +159,7 @@ public void generate_jsonTable2_generateSucceed() {
FunctionParam op2 = new ExpressionParam(new ColumnReference(null, null, "col1"));
op2.addOption(new NumberType("int", null, null));
op2.addOption(new ConstExpression("123"));
+ op2.addOption(new JsonOption());
fcall.addOption(op2);
FunctionParam op3 = new ExpressionParam(new ColumnReference(null, null, "col2"));
@@ -177,7 +168,9 @@ public void generate_jsonTable2_generateSucceed() {
op3.addOption(new ConstExpression("123"));
JsonOnOption onOption = new JsonOnOption();
onOption.setOnEmpty(new NullExpression());
- op3.addOption(onOption);
+ JsonOption jsonOpt = new JsonOption();
+ jsonOpt.setOnOption(onOption);
+ op3.addOption(jsonOpt);
fcall.addOption(op3);
FunctionParam op4 = new ExpressionParam(new ColumnReference(null, null, "col3"));
@@ -186,7 +179,9 @@ public void generate_jsonTable2_generateSucceed() {
op4.addOption(new ConstExpression("123"));
onOption = new JsonOnOption();
onOption.setOnError(new ConstExpression("error_p"));
- op4.addOption(onOption);
+ jsonOpt = new JsonOption();
+ jsonOpt.setOnOption(onOption);
+ op4.addOption(jsonOpt);
fcall.addOption(op4);
FunctionParam op5 = new ExpressionParam(new ColumnReference(null, null, "col4"));
@@ -196,7 +191,9 @@ public void generate_jsonTable2_generateSucceed() {
onOption = new JsonOnOption();
onOption.setOnEmpty(new NullExpression());
onOption.setOnError(new ConstExpression("error_p"));
- op5.addOption(onOption);
+ jsonOpt = new JsonOption();
+ jsonOpt.setOnOption(onOption);
+ op5.addOption(jsonOpt);
fcall.addOption(op5);
ExpressionReference expect = new ExpressionReference(fcall, null);
Assert.assertEquals(expect, actual);
@@ -298,6 +295,21 @@ public void generate_nameRefWithPartition_generateNameRefSucceed() {
Assert.assertEquals(expect, actual);
}
+ @Test
+ public void generate_nameRefWithExternalPartition_generateNameRefSucceed() {
+ Table_referenceContext context = getTableReferenceContext(
+ "select a from mysql.tab partition (col1=@@global.lalal, col2='aaa')");
+ StatementFactory factory = new MySQLFromReferenceFactory(context);
+ FromReference actual = factory.generate();
+
+ NameReference expect = new NameReference("mysql", "tab", null);
+ Map partitionMap = new HashMap<>();
+ partitionMap.put("col1", new ConstExpression("@@global.lalal"));
+ partitionMap.put("col2", new ConstExpression("'aaa'"));
+ expect.setPartitionUsage(new PartitionUsage(PartitionType.PARTITION, partitionMap));
+ Assert.assertEquals(expect, actual);
+ }
+
@Test
public void generate_nameRefWithFlashback_generateNameRefSucceed() {
Table_referenceContext context =
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLInsertFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLInsertFactoryTest.java
index 5d58c3fe27..e0f89ab1f6 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLInsertFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLInsertFactoryTest.java
@@ -71,6 +71,24 @@ public void generate_simpleInsert_succeed() {
Assert.assertEquals(actual, expect);
}
+ @Test
+ public void generate_insertWithHighPriority_succeed() {
+ StatementFactory factory = new MySQLInsertFactory(
+ getInsertContext("insert high_priority overwrite a.b values(1,default)"));
+ Insert actual = factory.generate();
+
+ RelationFactor factor = new RelationFactor("b");
+ factor.setSchema("a");
+ InsertTable insertTable = new InsertTable(factor);
+ List> values = new ArrayList<>();
+ values.add(Arrays.asList(new ConstExpression("1"), new ConstExpression("default")));
+ insertTable.setValues(values);
+ Insert expect = new Insert(Collections.singletonList(insertTable), null);
+ expect.setHighPriority(true);
+ expect.setOverwrite(true);
+ Assert.assertEquals(actual, expect);
+ }
+
@Test
public void generate_simpleReplace_succeed() {
StatementFactory factory = new MySQLInsertFactory(getInsertContext(
diff --git a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLSelectFactoryTest.java b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLSelectFactoryTest.java
index f5ee27b5cc..3ac36da245 100644
--- a/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLSelectFactoryTest.java
+++ b/libs/ob-sql-parser/src/test/java/com/oceanbase/tools/sqlparser/adapter/MySQLSelectFactoryTest.java
@@ -116,7 +116,7 @@ public void generate_parentSelectUnionDual_generateSelectSucceed() {
@Test
public void generate_orderAndLimitUnion_generateSelectSucceed() {
Select_stmtContext context = getSelectContext(
- "select col.* abc from tab order by col desc limit 3 union distinct select * from dual");
+ "select col.* abc from tab order by col desc approx limit 3 union distinct select * from dual");
StatementFactory