fix(oracle): stop ROWID pagination injection on views
This commit is contained in:
11 files changed
+196
-17
No files matched your search
@@ -267,11 +267,12 @@ pub fn build_table_data_select_sql_with_database(
|
||||
};
|
||||
let order_by = options.order_by.as_deref().filter(|order| !order.trim().is_empty()).or(default_order_by.as_deref());
|
||||
let order = order_by.map(|order_by| format!(" ORDER BY {order_by}")).unwrap_or_default();
|
||||
// Oracle join views can raise ORA-01445 when ROWID is selected; keep the
|
||||
// synthetic ROWID fallback scoped to base-table reads.
|
||||
// Oracle views with DISTINCT/GROUP BY raise ORA-01446 when ROWID is
|
||||
// selected. Missing object metadata must therefore fail closed instead of
|
||||
// being treated as a base table.
|
||||
let include_oracle_row_id = options.include_row_id
|
||||
&& uses_oracle_row_id(database_type)
|
||||
&& !is_view_table_type(options.table_type.as_deref());
|
||||
&& is_oracle_base_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);
|
||||
@@ -530,6 +531,10 @@ fn is_view_table_type(table_type: Option<&str>) -> bool {
|
||||
table_type.is_some_and(|value| value.to_ascii_uppercase().contains("VIEW"))
|
||||
}
|
||||
|
||||
fn is_oracle_base_table_type(table_type: Option<&str>) -> bool {
|
||||
table_type.is_some_and(|value| value.trim().eq_ignore_ascii_case("TABLE"))
|
||||
}
|
||||
|
||||
pub fn build_table_select_sql(options: TableSelectSqlOptions<'_>) -> String {
|
||||
let database_type = options.database_type;
|
||||
if database_type == Some(DatabaseType::VictoriaMetrics) {
|
||||
|
||||
@@ -1304,7 +1304,7 @@ fn builds_oracle_and_neo4j_table_data_queries() {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
schema: Some("DBXTEST".to_string()),
|
||||
table_name: "DBX_LOAD_TABLE_006".to_string(),
|
||||
table_type: None,
|
||||
table_type: Some("TABLE".to_string()),
|
||||
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
|
||||
columns: Vec::new(),
|
||||
fallback_order_columns: Vec::new(),
|
||||
@@ -1322,7 +1322,7 @@ fn builds_oracle_and_neo4j_table_data_queries() {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
schema: Some("DBXTEST".to_string()),
|
||||
table_name: "DBX_LOAD_TABLE_006".to_string(),
|
||||
table_type: None,
|
||||
table_type: Some("TABLE".to_string()),
|
||||
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
|
||||
columns: vec!["ID".to_string(), "NAME".to_string()],
|
||||
fallback_order_columns: Vec::new(),
|
||||
@@ -1445,6 +1445,25 @@ fn builds_oracle_and_neo4j_table_data_queries() {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oracle_unknown_table_type_does_not_assume_rowid_support() {
|
||||
assert_eq!(
|
||||
build_table_data_select_sql(TableDataSelectSqlOptions {
|
||||
database_type: Some(DatabaseType::Oracle),
|
||||
schema: Some("DBXTEST".to_string()),
|
||||
table_name: "DBX_DISTINCT_VIEW".to_string(),
|
||||
table_type: None,
|
||||
primary_keys: vec![DBX_ROWID_COLUMN.to_string()],
|
||||
columns: vec!["ID".to_string(), "NAME".to_string()],
|
||||
limit: Some(100),
|
||||
offset: Some(100),
|
||||
include_row_id: true,
|
||||
..Default::default()
|
||||
}),
|
||||
"SELECT \"ID\", \"NAME\" FROM (SELECT dbx_inner.*, ROWNUM AS \"__dbx_row_num\" FROM (SELECT \"ID\", \"NAME\" FROM \"DBXTEST\".\"DBX_DISTINCT_VIEW\") dbx_inner WHERE ROWNUM <= 200) WHERE \"__dbx_row_num\" > 100"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn builds_oracle_rowid_wrapped_large_value_reload_sql() {
|
||||
// The data-grid large-value reload selects the synthetic rowid key plus the
|
||||
|
||||
Reference in new issue
Block a user