fix(xugu): enable safe row editing without primary keys
This commit is contained in:
1 parent
39b2d2a6ac
commit
3e75be87eb
17 files changed
+236
-50
No files matched your search
@@ -80,6 +80,18 @@ pub fn uses_oracle_row_id(database_type: Option<DatabaseType>) -> bool {
|
||||
matches!(database_type, Some(DatabaseType::Oracle | DatabaseType::OceanbaseOracle))
|
||||
}
|
||||
|
||||
/// Xugu exposes an unqualified ROWID pseudo-column for base, partitioned and
|
||||
/// temporary tables. It is intentionally separate from Oracle's ROWIDTOCHAR
|
||||
/// representation because qualified ROWID and ROWIDTOCHAR are not supported
|
||||
/// by Xugu.
|
||||
pub fn uses_xugu_row_id(database_type: Option<DatabaseType>) -> bool {
|
||||
database_type == Some(DatabaseType::Xugu)
|
||||
}
|
||||
|
||||
pub fn uses_synthetic_row_id(database_type: Option<DatabaseType>) -> bool {
|
||||
uses_oracle_row_id(database_type) || uses_xugu_row_id(database_type)
|
||||
}
|
||||
|
||||
/// Oracle 系方言不支持 `INSERT ... VALUES (...), (...)` 多行语法,
|
||||
/// 复制为 INSERT 与导出 INSERT 都需按行生成单条语句。
|
||||
pub fn uses_single_row_insert_statements(database_type: DatabaseType) -> bool {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::models::connection::DatabaseType;
|
||||
|
||||
use super::capabilities::{
|
||||
firebird_rows_clause, table_pagination_strategy, uses_oracle_row_id, TablePaginationStrategy,
|
||||
firebird_rows_clause, table_pagination_strategy, uses_oracle_row_id, uses_xugu_row_id, TablePaginationStrategy,
|
||||
};
|
||||
use super::identifiers::{
|
||||
normalize_where_input, qualified_table_name, qualified_table_name_with_catalog, quote_gaussdb_jdbc_identifier,
|
||||
@@ -272,6 +272,8 @@ pub fn build_table_data_select_sql_with_database(
|
||||
let include_oracle_row_id = options.include_row_id
|
||||
&& uses_oracle_row_id(database_type)
|
||||
&& !is_view_table_type(options.table_type.as_deref());
|
||||
let include_xugu_row_id =
|
||||
options.include_row_id && uses_xugu_row_id(database_type) && !is_view_table_type(options.table_type.as_deref());
|
||||
let offset = options.offset.unwrap_or(0);
|
||||
let oracle_view_first_page =
|
||||
database_type == Some(DatabaseType::Oracle) && is_view_table_type(options.table_type.as_deref()) && offset == 0;
|
||||
@@ -280,6 +282,15 @@ pub fn build_table_data_select_sql_with_database(
|
||||
format!("ROWIDTOCHAR(t.ROWID) AS \"{DBX_ROWID_COLUMN}\", t.*")
|
||||
} else if let Some(preview_columns) = build_large_value_preview_columns(&options) {
|
||||
preview_columns
|
||||
} else if include_xugu_row_id {
|
||||
if options.columns.is_empty() {
|
||||
format!("ROWID AS \"{DBX_ROWID_COLUMN}\", *")
|
||||
} else {
|
||||
format!(
|
||||
"ROWID AS \"{DBX_ROWID_COLUMN}\", {}",
|
||||
quoted_table_columns_or_star(database_type, &options.columns)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
build_select_columns(
|
||||
database_type,
|
||||
|
||||
@@ -1326,6 +1326,60 @@ fn builds_oracle_and_neo4j_table_data_queries() {
|
||||
}),
|
||||
"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::Xugu),
|
||||
schema: Some("DBXTEST".to_string()),
|
||||
table_name: "DBX_LOAD_TABLE_006".to_string(),
|
||||
table_type: Some("PARTITIONED TABLE".to_string()),
|
||||
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
|
||||
columns: Vec::new(),
|
||||
fallback_order_columns: Vec::new(),
|
||||
order_by: None,
|
||||
limit: Some(100),
|
||||
offset: None,
|
||||
where_input: None,
|
||||
include_row_id: true,
|
||||
..Default::default()
|
||||
}),
|
||||
"SELECT ROWID AS \"__DBX_ROWID\", * FROM \"DBXTEST\".\"DBX_LOAD_TABLE_006\" LIMIT 100;"
|
||||
);
|
||||
assert_eq!(
|
||||
build_table_data_select_sql(TableDataSelectSqlOptions {
|
||||
database_type: Some(DatabaseType::Xugu),
|
||||
schema: Some("DBXTEST".to_string()),
|
||||
table_name: "DBX_LOAD_TABLE_006".to_string(),
|
||||
table_type: Some("TEMPORARY TABLE".to_string()),
|
||||
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
|
||||
columns: vec!["ID".to_string(), "NAME".to_string()],
|
||||
fallback_order_columns: Vec::new(),
|
||||
order_by: None,
|
||||
limit: Some(25),
|
||||
offset: Some(10),
|
||||
where_input: None,
|
||||
include_row_id: true,
|
||||
..Default::default()
|
||||
}),
|
||||
"SELECT ROWID AS \"__DBX_ROWID\", \"ID\", \"NAME\" FROM \"DBXTEST\".\"DBX_LOAD_TABLE_006\" LIMIT 25 OFFSET 10;"
|
||||
);
|
||||
assert_eq!(
|
||||
build_table_data_select_sql(TableDataSelectSqlOptions {
|
||||
database_type: Some(DatabaseType::Xugu),
|
||||
schema: Some("DBXTEST".to_string()),
|
||||
table_name: "DBX_JOIN_VIEW".to_string(),
|
||||
table_type: Some("VIEW".to_string()),
|
||||
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
|
||||
columns: vec!["ID".to_string(), "NAME".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 * FROM \"DBXTEST\".\"DBX_JOIN_VIEW\" LIMIT 100;"
|
||||
);
|
||||
assert_eq!(
|
||||
build_table_data_select_sql(TableDataSelectSqlOptions {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
|
||||
Reference in new issue
Block a user