fix(oceanbase): use rowid for keyless Oracle rows

This commit is contained in:
t8y2 committed 2026-07-15 13:00:38 +08:00
1 parent 86a6846b10
commit 002dbbf602
12 files changed
+234 -17

No files matched your search

@@ -65,6 +65,10 @@ pub fn uses_fetch_first(database_type: DatabaseType) -> bool {
matches!(database_type, DatabaseType::Oracle | DatabaseType::Dameng | DatabaseType::Db2)
}
pub fn uses_oracle_row_id(database_type: Option<DatabaseType>) -> bool {
matches!(database_type, Some(DatabaseType::Oracle | DatabaseType::OceanbaseOracle))
}
/// Oracle 系方言不支持 `INSERT ... VALUES (...), (...)` 多行语法,
/// 复制为 INSERT 与导出 INSERT 都需按行生成单条语句。
pub fn uses_single_row_insert_statements(database_type: DatabaseType) -> bool {
@@ -1,6 +1,8 @@
use crate::models::connection::DatabaseType;
use super::capabilities::{firebird_rows_clause, table_pagination_strategy, uses_fetch_first, TablePaginationStrategy};
use super::capabilities::{
firebird_rows_clause, table_pagination_strategy, uses_oracle_row_id, TablePaginationStrategy,
};
use super::identifiers::{
normalize_where_input, qualified_table_name, qualified_table_name_with_catalog, quote_table_identifier,
};
@@ -50,7 +52,7 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String
// Oracle join views can raise ORA-01445 when ROWID is selected; keep the
// synthetic ROWID fallback scoped to base-table reads.
let include_oracle_row_id = options.include_row_id
&& database_type == Some(DatabaseType::Oracle)
&& uses_oracle_row_id(database_type)
&& !is_view_table_type(options.table_type.as_deref());
let select_columns = if include_oracle_row_id {
@@ -72,8 +74,7 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String
} else {
rownum_select_columns.clone()
};
let table_alias =
if include_oracle_row_id && database_type.is_some_and(uses_fetch_first) { format!("{table} t") } else { table };
let table_alias = if include_oracle_row_id { format!("{table} t") } else { table };
match table_pagination_strategy(database_type) {
TablePaginationStrategy::IrisTop => {
+18
View File
@@ -784,6 +784,24 @@ fn builds_oracle_and_neo4j_table_data_queries() {
}),
"SELECT \"__DBX_ROWID\", \"ID\", \"NAME\" FROM (SELECT ROWIDTOCHAR(t.ROWID) AS \"__DBX_ROWID\", t.* FROM \"DBXTEST\".\"DBX_LOAD_TABLE_006\" t) WHERE ROWNUM <= 100"
);
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
database_type: Some(DatabaseType::OceanbaseOracle),
schema: Some("APP".to_string()),
table_name: "DATA_REPORT_SUB_TASK".to_string(),
table_type: Some("TABLE".to_string()),
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
columns: vec!["ID".to_string(), "SMC_RESPONSE".to_string()],
fallback_order_columns: Vec::new(),
order_by: None,
limit: Some(100),
offset: None,
where_input: None,
include_row_id: true,
..Default::default()
}),
"SELECT \"__DBX_ROWID\", \"ID\", \"SMC_RESPONSE\" FROM (SELECT ROWIDTOCHAR(t.ROWID) AS \"__DBX_ROWID\", t.* FROM \"APP\".\"DATA_REPORT_SUB_TASK\" t) WHERE ROWNUM <= 100"
);
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
database_type: Some(DatabaseType::Oracle),