fix(oracle): avoid rownum on initial view reads

This commit is contained in:
t8y2 committed 2026-07-27 21:18:16 +08:00
1 parent ae90b81c14
commit 0be9bcef12
2 files changed
+46 -2

No files matched your search

@@ -54,6 +54,9 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String
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 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;
let select_columns = if include_oracle_row_id {
format!("ROWIDTOCHAR(t.ROWID) AS \"{DBX_ROWID_COLUMN}\", t.*")
@@ -109,6 +112,9 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String
)
}
TablePaginationStrategy::Rownum => {
if oracle_view_first_page {
return format!("SELECT {page_select_columns} FROM {table_alias}{where_clause}{order}");
}
let rownum_inner_select_columns =
if include_oracle_row_id { &select_columns } else { &rownum_select_columns };
build_rownum_table_select_sql(
@@ -118,7 +124,7 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String
rownum_inner_select_columns,
&page_select_columns,
limit,
options.offset.unwrap_or(0),
offset,
)
}
TablePaginationStrategy::Unbounded => {
+39 -1
View File
@@ -819,7 +819,7 @@ fn builds_oracle_and_neo4j_table_data_queries() {
include_row_id: true,
..Default::default()
}),
"SELECT \"ID\", \"NAME\" FROM (SELECT \"ID\", \"NAME\" FROM \"DBXTEST\".\"DBX_JOIN_VIEW\") WHERE ROWNUM <= 100"
"SELECT \"ID\", \"NAME\" FROM \"DBXTEST\".\"DBX_JOIN_VIEW\""
);
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
@@ -841,6 +841,44 @@ fn builds_oracle_and_neo4j_table_data_queries() {
);
}
#[test]
fn oracle_view_first_page_preserves_filter_and_sort_without_rownum() {
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
database_type: Some(DatabaseType::Oracle),
schema: Some("DBXTEST".to_string()),
table_name: "DBX_JOIN_VIEW".to_string(),
table_type: Some("VIEW".to_string()),
columns: vec!["ID".to_string(), "NAME".to_string()],
order_by: Some("\"ID\" DESC".to_string()),
limit: Some(100),
offset: Some(0),
where_input: Some("STATUS = 'A'".to_string()),
include_row_id: true,
..Default::default()
}),
"SELECT \"ID\", \"NAME\" FROM \"DBXTEST\".\"DBX_JOIN_VIEW\" WHERE (STATUS = 'A') ORDER BY \"ID\" DESC"
);
}
#[test]
fn oracle_view_later_pages_keep_rownum_pagination() {
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
database_type: Some(DatabaseType::Oracle),
schema: Some("DBXTEST".to_string()),
table_name: "DBX_JOIN_VIEW".to_string(),
table_type: Some("VIEW".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_JOIN_VIEW\") dbx_inner WHERE ROWNUM <= 200) WHERE \"__dbx_row_num\" > 100"
);
}
#[test]
fn normalizes_where_input_with_multibyte_identifier_prefix() {
assert_eq!(normalize_where_input(Some("`客户名称` = '示例客户'")), "`客户名称` = '示例客户'");