fix(oracle): serialize RAW values with HEXTORAW
This commit is contained in:
parent
1e7b3f3dec
commit
5ad5b4fcc3
|
|
@ -1787,6 +1787,11 @@ pub fn format_grid_sql_literal(
|
|||
return literal;
|
||||
}
|
||||
}
|
||||
if is_oracle_raw_literal_column(database_type, column_info) {
|
||||
if let Some(literal) = format_oracle_raw_literal_text(&text) {
|
||||
return literal;
|
||||
}
|
||||
}
|
||||
if column_info.map(|column| is_numeric_type(&column.data_type)).unwrap_or(false) && is_numeric_literal(&text) {
|
||||
// BigDecimal/BigInteger cells cross JSON-RPC as strings so browsers cannot round them.
|
||||
return text;
|
||||
|
|
@ -2082,6 +2087,24 @@ fn format_mysql_binary_literal_text(text: &str) -> Option<String> {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_oracle_raw_literal_column(database_type: Option<DatabaseType>, column_info: Option<&DataGridColumnInfo>) -> bool {
|
||||
is_oracle_temporal_literal_database(database_type)
|
||||
&& column_info.map(|column| is_oracle_raw_column_type(&column.data_type)).unwrap_or(false)
|
||||
}
|
||||
|
||||
fn is_oracle_raw_column_type(data_type: &str) -> bool {
|
||||
data_type.trim().split(['(', ':', ' ']).next().is_some_and(|base| base.eq_ignore_ascii_case("raw"))
|
||||
}
|
||||
|
||||
fn format_oracle_raw_literal_text(text: &str) -> Option<String> {
|
||||
let hex = text.strip_prefix("0x")?;
|
||||
if hex.len() % 2 == 0 && hex.chars().all(|ch| ch.is_ascii_hexdigit()) {
|
||||
Some(format!("HEXTORAW('{hex}')"))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn is_geometry_column_type(data_type: &str) -> bool {
|
||||
let lower = data_type.to_ascii_lowercase();
|
||||
let base = lower.split('(').next().unwrap_or(&lower).trim();
|
||||
|
|
@ -4749,6 +4772,51 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepares_oracle_raw_update_with_hex_literals() {
|
||||
let result = prepare_data_grid_save(DataGridSaveStatementOptions {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
identifier_quote: None,
|
||||
table_meta: DataGridTableMeta {
|
||||
catalog: None,
|
||||
database: None,
|
||||
schema: Some("APP".to_string()),
|
||||
table_name: "RAW_VALUES".to_string(),
|
||||
primary_keys: vec!["ID".to_string()],
|
||||
columns: Some(vec![column("ID", "RAW(16)", false, None), column("PAYLOAD", "RAW(16)", true, None)]),
|
||||
},
|
||||
columns: vec!["ID".to_string(), "PAYLOAD".to_string()],
|
||||
source_columns: None,
|
||||
rows: vec![vec![json!("0x00112233445566778899aabbccddeeff"), json!("0xaabb")]],
|
||||
dirty_rows: vec![(0, vec![(1, json!("0xccdd"))])],
|
||||
deleted_rows: vec![],
|
||||
new_rows: vec![],
|
||||
});
|
||||
|
||||
assert_eq!(result.validation_error, None);
|
||||
assert_eq!(
|
||||
result.statements,
|
||||
vec![
|
||||
"UPDATE \"APP\".\"RAW_VALUES\" SET \"PAYLOAD\" = HEXTORAW('ccdd') WHERE \"ID\" = HEXTORAW('00112233445566778899aabbccddeeff');"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oracle_raw_literals_require_valid_even_length_hex() {
|
||||
let raw = column("ID", "RAW(16)", false, None);
|
||||
let text = column("ID", "VARCHAR2(64)", false, None);
|
||||
let blob = column("ID", "BLOB", false, None);
|
||||
|
||||
for database_type in [DatabaseType::Oracle, DatabaseType::OceanbaseOracle] {
|
||||
assert_eq!(format_grid_sql_literal(&json!("0x00aB"), Some(database_type), Some(&raw)), "HEXTORAW('00aB')");
|
||||
assert_eq!(format_grid_sql_literal(&json!("0xabc"), Some(database_type), Some(&raw)), "'0xabc'");
|
||||
assert_eq!(format_grid_sql_literal(&json!("0x00gg"), Some(database_type), Some(&raw)), "'0x00gg'");
|
||||
assert_eq!(format_grid_sql_literal(&json!("0x00ab"), Some(database_type), Some(&text)), "'0x00ab'");
|
||||
assert_eq!(format_grid_sql_literal(&json!("0x00ab"), Some(database_type), Some(&blob)), "'0x00ab'");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn prepares_oceanbase_oracle_lob_deletes_with_synthetic_rowid() {
|
||||
let result = prepare_data_grid_save(DataGridSaveStatementOptions {
|
||||
|
|
|
|||
Loading…
Reference in New Issue