feat(impala): add full database support

This commit is contained in:
zipg authored and GitHub committed 2026-08-14 20:41:57 +08:00
1 parent 185ff68d78
commit a6d9e6818e
54 files changed
+1092 -148

No files matched your search

@@ -53,6 +53,7 @@ pub fn is_schema_aware(database_type: DatabaseType) -> bool {
| DatabaseType::Trino
| DatabaseType::PrestoSql
| DatabaseType::Hive
| DatabaseType::Impala
| DatabaseType::Spark
| DatabaseType::Db2
| DatabaseType::Informix
@@ -669,8 +669,8 @@ pub fn profile_for(db_type: DatabaseType) -> DdlDialectProfile {
ClickHouse => clickhouse_profile(),
DuckDb | Questdb | SapHana | Teradata | Snowflake | Trino | PrestoSql | Hive | Spark | Db2 | Informix
| Bigquery | Kylin | Oscar | Tdengine | Iotdb | Databricks | Jdbc => conservative_ansi(db_type),
DuckDb | Questdb | SapHana | Teradata | Snowflake | Trino | PrestoSql | Hive | Impala | Spark | Db2
| Informix | Bigquery | Kylin | Oscar | Tdengine | Iotdb | Databricks | Jdbc => conservative_ansi(db_type),
// Non-tabular / not applicable for relational CREATE TABLE
Redis | MongoDb | Elasticsearch | Easysearch | Meilisearch | Qdrant | Milvus | Weaviate | ChromaDb | Neo4j
@@ -129,6 +129,7 @@ pub fn quote_table_identifier(database_type: Option<DatabaseType>, name: &str) -
| DatabaseType::StarRocks
| DatabaseType::ManticoreSearch
| DatabaseType::Hive
| DatabaseType::Impala
| DatabaseType::Spark
| DatabaseType::Databend
| DatabaseType::Tdengine
@@ -378,6 +379,7 @@ pub(crate) fn quote_transfer_identifier(name: &str, database_type: &DatabaseType
| DatabaseType::Doris
| DatabaseType::StarRocks
| DatabaseType::Hive
| DatabaseType::Impala
| DatabaseType::Spark
| DatabaseType::Questdb => format!("`{}`", name.replace('`', "``")),
DatabaseType::SqlServer => format!("[{}]", name.replace(']', "]]")),
@@ -186,6 +186,11 @@ pub fn build_table_data_select_sql(options: TableDataSelectSqlOptions) -> String
let default_order_by = if database_type == Some(DatabaseType::InfluxDb) {
// InfluxQL only allows sorting of timestamp column
Some("time DESC".to_string())
} else if database_type == Some(DatabaseType::Impala) {
// Impala requires ORDER BY when OFFSET is present. Keeping the same
// fallback on the first page also prevents page boundaries from using
// different row orders when the table has no explicit key.
Some("1".to_string())
} else {
None
};
@@ -502,7 +507,7 @@ pub(super) fn build_select_columns(
.collect::<Vec<_>>()
.join(", ");
}
if database_type != Some(DatabaseType::Hive) {
if !matches!(database_type, Some(DatabaseType::Hive | DatabaseType::Impala)) {
return "*".to_string();
}
columns
+31
View File
@@ -4,11 +4,13 @@ use crate::models::connection::DatabaseType;
#[test]
fn transfer_identifier_policy_preserves_legacy_output() {
assert_eq!(quote_transfer_identifier("user`events", &DatabaseType::Hive), "`user``events`");
assert_eq!(quote_transfer_identifier("user`events", &DatabaseType::Impala), "`user``events`");
assert_eq!(quote_transfer_identifier("user`events", &DatabaseType::ClickHouse), "`user``events`");
assert_eq!(quote_transfer_identifier("user`events", &DatabaseType::Doris), "`user``events`");
assert_eq!(quote_transfer_identifier("user]events", &DatabaseType::SqlServer), "[user]]events]");
assert_eq!(quote_transfer_identifier("user\"events", &DatabaseType::Postgres), "\"user\"\"events\"");
assert_eq!(qualified_transfer_table("events", "warehouse", &DatabaseType::Hive, None), "`warehouse`.`events`");
assert_eq!(qualified_transfer_table("events", "warehouse", &DatabaseType::Impala, None), "`warehouse`.`events`");
assert_eq!(qualified_transfer_table("events", "warehouse", &DatabaseType::Mysql, None), "`events`");
}
@@ -245,6 +247,17 @@ fn builds_select_sql_with_limit_syntax_for_database_type() {
}),
"SELECT * FROM `test`.`dws_event_analyse` LIMIT 100;"
);
assert_eq!(
build_table_select_sql(TableSelectSqlOptions {
database_type: Some(DatabaseType::Impala),
schema: Some("dbx_demo"),
table_name: "connection_test",
columns: &[],
order_columns: &[],
limit: 100,
}),
"SELECT * FROM `dbx_demo`.`connection_test` LIMIT 100;"
);
assert_eq!(
build_table_select_sql(TableSelectSqlOptions {
database_type: Some(DatabaseType::StarRocks),
@@ -340,6 +353,24 @@ fn builds_table_data_where_and_schema_queries() {
}),
"SELECT * FROM \"public\".\"orders\" WHERE (amount > 10) LIMIT 50 OFFSET 100;"
);
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
database_type: Some(DatabaseType::Impala),
schema: Some("dbx_demo".to_string()),
table_name: "connection_test".to_string(),
table_type: Some("TABLE".to_string()),
primary_keys: Vec::new(),
columns: vec!["id".to_string(), "name".to_string()],
fallback_order_columns: Vec::new(),
order_by: None,
limit: Some(2),
offset: Some(1),
where_input: None,
include_row_id: false,
..Default::default()
}),
"SELECT `id` AS `id`, `name` AS `name` FROM `dbx_demo`.`connection_test` ORDER BY 1 LIMIT 2 OFFSET 1;"
);
assert_eq!(
build_table_data_select_sql(TableDataSelectSqlOptions {
database_type: Some(DatabaseType::Kingbase),