fix(dameng): use fetch pagination for transfer

This commit is contained in:
t8y2 committed 2026-06-25 01:09:48 +08:00
1 parent 529454e6d1
commit b5bbdfa5e9
1 file changed
+81 -4
+81 -4
View File
@@ -1551,7 +1551,7 @@ pub fn pagination_sql(
let col_list = columns.iter().map(|c| quote_identifier(c, db_type)).collect::<Vec<_>>().join(", ");
match db_type {
DatabaseType::SqlServer | DatabaseType::Oracle => {
DatabaseType::SqlServer | DatabaseType::Oracle | DatabaseType::Dameng => {
format!(
"SELECT {col_list} FROM {full_table} ORDER BY (SELECT NULL) OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"
)
@@ -1580,7 +1580,7 @@ pub fn pagination_sql_with_order(
let order_expression = postgres_order_by_expression(order_by_columns, db_type);
match db_type {
DatabaseType::SqlServer | DatabaseType::Oracle => {
DatabaseType::SqlServer | DatabaseType::Oracle | DatabaseType::Dameng => {
let order_by = order_expression.unwrap_or_else(|| "(SELECT NULL)".to_string());
format!(
"SELECT {col_list} FROM {full_table} ORDER BY {order_by} OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"
@@ -1621,7 +1621,7 @@ pub fn pagination_sql_with_filter_order(
.or_else(|| postgres_order_by_expression(default_order_columns, db_type));
match db_type {
DatabaseType::SqlServer | DatabaseType::Oracle => {
DatabaseType::SqlServer | DatabaseType::Oracle | DatabaseType::Dameng => {
let order_by = order_expression.unwrap_or_else(|| "(SELECT NULL)".to_string());
format!(
"SELECT {col_list} FROM {full_table}{where_clause} ORDER BY {order_by} OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"
@@ -1667,7 +1667,7 @@ pub fn keyset_pagination_sql(
let where_clause = keyset_where_clause(primary_keys, last_pk_values, db_type);
match db_type {
DatabaseType::SqlServer | DatabaseType::Oracle => {
DatabaseType::SqlServer | DatabaseType::Oracle | DatabaseType::Dameng => {
format!(
"SELECT {col_list} FROM {full_table}{where_clause} ORDER BY {order} OFFSET 0 ROWS FETCH NEXT {limit} ROWS ONLY"
)
@@ -3966,6 +3966,43 @@ mod tests {
assert_eq!(sql, "SELECT `id`, `name` FROM `users` ORDER BY `id` LIMIT 200, 300");
}
#[test]
fn dameng_export_pagination_uses_offset_fetch() {
let sql = pagination_sql(
&[String::from("id"), String::from("name")],
"users",
"SYSDBA",
&DatabaseType::Dameng,
500,
100,
);
assert_eq!(
sql,
"SELECT \"id\", \"name\" FROM \"SYSDBA\".\"users\" ORDER BY (SELECT NULL) OFFSET 500 ROWS FETCH NEXT 100 ROWS ONLY"
);
assert!(!sql.contains(" LIMIT "));
}
#[test]
fn dameng_ordered_pagination_uses_offset_fetch() {
let sql = pagination_sql_with_order(
&[String::from("id"), String::from("name")],
"users",
"SYSDBA",
&DatabaseType::Dameng,
200,
100,
&[String::from("id")],
);
assert_eq!(
sql,
"SELECT \"id\", \"name\" FROM \"SYSDBA\".\"users\" ORDER BY \"id\" OFFSET 200 ROWS FETCH NEXT 100 ROWS ONLY"
);
assert!(!sql.contains(" LIMIT "));
}
#[test]
fn filtered_pagination_preserves_where_and_order() {
let sql = pagination_sql_with_filter_order(
@@ -3986,6 +4023,27 @@ mod tests {
);
}
#[test]
fn dameng_filtered_pagination_preserves_where_and_order() {
let sql = pagination_sql_with_filter_order(
&[String::from("id"), String::from("status")],
"users",
"SYSDBA",
&DatabaseType::Dameng,
10_000,
2_000,
Some("WHERE status = 'active'"),
Some("\"id\" DESC"),
&[String::from("id")],
);
assert_eq!(
sql,
"SELECT \"id\", \"status\" FROM \"SYSDBA\".\"users\" WHERE (status = 'active') ORDER BY \"id\" DESC OFFSET 10000 ROWS FETCH NEXT 2000 ROWS ONLY"
);
assert!(!sql.contains(" LIMIT "));
}
#[test]
fn filtered_count_preserves_where() {
let sql = count_sql_with_where("users", "public", &DatabaseType::SapHana, Some("WHERE status = 'active'"));
@@ -4011,6 +4069,25 @@ mod tests {
);
}
#[test]
fn dameng_keyset_pagination_includes_offset_fetch() {
let sql = keyset_pagination_sql(
&[String::from("id"), String::from("name")],
"users",
"SYSDBA",
&DatabaseType::Dameng,
&[String::from("id")],
&[json!(25)],
100,
);
assert_eq!(
sql,
"SELECT \"id\", \"name\" FROM \"SYSDBA\".\"users\" WHERE \"id\" > 25 ORDER BY \"id\" ASC OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY"
);
assert!(!sql.contains(" LIMIT "));
}
#[test]
fn composite_keyset_pagination_uses_portable_lexicographic_predicate() {
let sql = keyset_pagination_sql(