fix(gbase8s): omit owner from data grid writes

Closes #5911
This commit is contained in:
t8y2 committed 2026-08-11 10:59:54 +00:00
1 parent 8482ef25ec
commit 11d9df0169
9 files changed
+144 -27

No files matched your search

+83 -10
View File
@@ -281,21 +281,32 @@ pub struct DataGridSavePreparation {
}
pub fn prepare_data_grid_save(options: DataGridSaveStatementOptions) -> DataGridSavePreparation {
prepare_data_grid_save_for_driver_profile(options, None)
}
pub fn prepare_data_grid_save_for_driver_profile(
options: DataGridSaveStatementOptions,
driver_profile: Option<&str>,
) -> DataGridSavePreparation {
let validation_error = validate_data_grid_save(&options);
if validation_error.is_some() {
return DataGridSavePreparation {
validation_error,
statements: Vec::new(),
rollback_statements: Vec::new(),
execution_schema: data_grid_save_execution_schema(options.database_type, &options.table_meta),
execution_schema: data_grid_save_execution_schema(
options.database_type,
driver_profile,
&options.table_meta,
),
};
}
DataGridSavePreparation {
validation_error: None,
statements: build_data_grid_save_statements(&options),
rollback_statements: build_data_grid_rollback_statements(&options),
execution_schema: data_grid_save_execution_schema(options.database_type, &options.table_meta),
statements: build_data_grid_save_statements(&options, driver_profile),
rollback_statements: build_data_grid_rollback_statements(&options, driver_profile),
execution_schema: data_grid_save_execution_schema(options.database_type, driver_profile, &options.table_meta),
}
}
@@ -1082,7 +1093,10 @@ fn validate_inserted_primary_keys(options: &DataGridSaveStatementOptions) -> Opt
None
}
fn build_data_grid_save_statements(options: &DataGridSaveStatementOptions) -> Vec<String> {
fn build_data_grid_save_statements(
options: &DataGridSaveStatementOptions,
driver_profile: Option<&str>,
) -> Vec<String> {
if options.database_type == Some(DatabaseType::Neo4j) {
return build_neo4j_data_grid_save_statements(options);
}
@@ -1092,10 +1106,15 @@ fn build_data_grid_save_statements(options: &DataGridSaveStatementOptions) -> Ve
let save_columns = effective_columns(options);
let column_info = options.table_meta.columns.as_deref().unwrap_or(&[]);
let schema = crate::sql_dialect::table_data_schema(
options.database_type,
driver_profile,
options.table_meta.schema.as_deref(),
);
let table = data_grid_qualified_table_name(
options.database_type,
options.table_meta.catalog.as_deref(),
options.table_meta.schema.as_deref(),
schema,
options.table_meta.database.as_deref(),
&options.table_meta.table_name,
options.identifier_quote.as_deref(),
@@ -1244,7 +1263,10 @@ fn build_data_grid_save_statements(options: &DataGridSaveStatementOptions) -> Ve
statements
}
fn build_data_grid_rollback_statements(options: &DataGridSaveStatementOptions) -> Vec<String> {
fn build_data_grid_rollback_statements(
options: &DataGridSaveStatementOptions,
driver_profile: Option<&str>,
) -> Vec<String> {
if options.database_type == Some(DatabaseType::Neo4j) {
return build_neo4j_data_grid_rollback_statements(options);
}
@@ -1257,10 +1279,15 @@ fn build_data_grid_rollback_statements(options: &DataGridSaveStatementOptions) -
let save_columns = effective_columns(options);
let column_info = options.table_meta.columns.as_deref().unwrap_or(&[]);
let schema = crate::sql_dialect::table_data_schema(
options.database_type,
driver_profile,
options.table_meta.schema.as_deref(),
);
let table = data_grid_qualified_table_name(
options.database_type,
options.table_meta.catalog.as_deref(),
options.table_meta.schema.as_deref(),
schema,
options.table_meta.database.as_deref(),
&options.table_meta.table_name,
options.identifier_quote.as_deref(),
@@ -1706,12 +1733,14 @@ fn copy_column_info(
fn data_grid_save_execution_schema(
database_type: Option<DatabaseType>,
driver_profile: Option<&str>,
table_meta: &DataGridTableMeta,
) -> Option<String> {
if matches!(database_type, Some(DatabaseType::Neo4j | DatabaseType::Oracle)) {
return None;
}
table_meta.schema.clone()
crate::sql_dialect::table_data_schema(database_type, driver_profile, table_meta.schema.as_deref())
.map(str::to_string)
}
pub fn normalize_data_grid_save_error(database_type: Option<DatabaseType>, error: &str) -> String {
@@ -4914,7 +4943,51 @@ mod tests {
}
#[test]
fn gbase8s_save_keeps_unquoted_owner_when_driver_reports_no_identifier_quote() {
fn gbase8s_save_omits_owner_for_insert_update_delete_and_rollback() {
let result = prepare_data_grid_save_for_driver_profile(
DataGridSaveStatementOptions {
database_type: Some(DatabaseType::Informix),
identifier_quote: Some(String::new()),
table_meta: DataGridTableMeta {
catalog: None,
database: Some("webcenter".to_string()),
schema: Some("gbasedbt".to_string()),
table_name: "user_device".to_string(),
primary_keys: vec!["id".to_string()],
columns: Some(vec![column("id", "integer", false, None), column("dev_id", "varchar", false, None)]),
},
columns: vec!["id".to_string(), "dev_id".to_string()],
source_columns: None,
rows: vec![vec![json!(1), json!("1")], vec![json!(2), json!("deleted")]],
dirty_rows: vec![(0, vec![(1, json!("2"))])],
deleted_rows: vec![1],
new_rows: vec![vec![json!(3), json!("new")]],
},
Some("GBASE8S"),
);
assert_eq!(result.validation_error, None);
assert_eq!(result.execution_schema, None);
assert_eq!(
result.statements,
vec![
"UPDATE user_device SET dev_id = '2' WHERE id = 1;",
"DELETE FROM user_device WHERE id = 2;",
"INSERT INTO user_device (id, dev_id) VALUES (3, 'new');",
]
);
assert_eq!(
result.rollback_statements,
vec![
"DELETE FROM user_device WHERE id = 3 AND dev_id = 'new';",
"INSERT INTO user_device (id, dev_id) VALUES (2, 'deleted');",
"UPDATE user_device SET dev_id = '1' WHERE id = 1 AND dev_id = '2';",
]
);
}
#[test]
fn standard_informix_save_preserves_owner_qualification_without_gbase8s_profile() {
let result = prepare_data_grid_save(DataGridSaveStatementOptions {
database_type: Some(DatabaseType::Informix),
identifier_quote: Some(String::new()),
+1 -1
View File
@@ -40,7 +40,7 @@ pub use identifiers::{
pub(crate) use identifiers::{parse_sqlserver_linked_schema_ref, qualified_transfer_table, quote_transfer_identifier};
pub use table_select::{build_count_table_sql, build_table_data_select_sql, build_table_select_sql};
pub(crate) use table_select::{
quote_table_data_identifier, table_data_qualified_table_name, uses_connection_identifier_quote,
quote_table_data_identifier, table_data_qualified_table_name, table_data_schema, uses_connection_identifier_quote,
};
pub use type_rewrite::{
apply_auto_inc_to_column_def, column_is_auto_increment, rewrite_column_type, split_type_base_params,
@@ -19,15 +19,23 @@ pub fn build_count_table_sql(database_type: Option<DatabaseType>, schema: Option
format!("SELECT COUNT(*) AS row_count FROM {}", qualified_table_name(database_type, schema, table_name))
}
pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String {
let database_type = options.database_type;
let schema = if database_type == Some(DatabaseType::Informix)
&& options.driver_profile.as_deref().is_some_and(|profile| profile.eq_ignore_ascii_case("gbase8s"))
pub(crate) fn table_data_schema<'a>(
database_type: Option<DatabaseType>,
driver_profile: Option<&str>,
schema: Option<&'a str>,
) -> Option<&'a str> {
if database_type == Some(DatabaseType::Informix)
&& driver_profile.is_some_and(|profile| profile.eq_ignore_ascii_case("gbase8s"))
{
None
} else {
options.schema.as_deref()
};
schema
}
}
pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String {
let database_type = options.database_type;
let schema = table_data_schema(database_type, options.driver_profile.as_deref(), options.schema.as_deref());
let limit = options.limit.unwrap_or(100);
if database_type == Some(DatabaseType::Neo4j) {
return build_neo4j_table_select_sql(&options, limit);
+3 -1
View File
@@ -252,6 +252,8 @@ pub struct BuildSingleColumnAlterSqlRequest {
#[serde(rename_all = "camelCase")]
pub struct PrepareDataGridSaveRequest {
pub options: dbx_core::data_grid_sql::DataGridSaveStatementOptions,
#[serde(default)]
pub driver_profile: Option<String>,
}
#[derive(Deserialize, utoipa::ToSchema)]
@@ -802,7 +804,7 @@ pub async fn analyze_editable_query_editability(
pub async fn prepare_data_grid_save(
Json(req): Json<PrepareDataGridSaveRequest>,
) -> Json<dbx_core::data_grid_sql::DataGridSavePreparation> {
Json(dbx_core::data_grid_sql::prepare_data_grid_save(req.options))
Json(dbx_core::data_grid_sql::prepare_data_grid_save_for_driver_profile(req.options, req.driver_profile.as_deref()))
}
#[utoipa::path(