fix(jdbc): avoid double quoting kyuubi identifiers
This commit is contained in:
1 parent
0f40f6cd0c
commit
573f31c8dc
3 files changed
+51
No files matched your search
@@ -17,6 +17,7 @@ export interface BuildTableSelectSqlOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function quoteTableIdentifier(databaseType: DatabaseType | undefined, name: string): string {
|
export function quoteTableIdentifier(databaseType: DatabaseType | undefined, name: string): string {
|
||||||
|
if (databaseType === "jdbc") return quoteJdbcIdentifier(name);
|
||||||
if (databaseType === "mysql" || databaseType === "hive" || databaseType === "tdengine" || databaseType === "access")
|
if (databaseType === "mysql" || databaseType === "hive" || databaseType === "tdengine" || databaseType === "access")
|
||||||
return `\`${name.replace(/`/g, "``")}\``;
|
return `\`${name.replace(/`/g, "``")}\``;
|
||||||
if (databaseType === "informix" && /^[A-Za-z_][A-Za-z0-9_$]*$/.test(name)) return name;
|
if (databaseType === "informix" && /^[A-Za-z_][A-Za-z0-9_$]*$/.test(name)) return name;
|
||||||
@@ -29,6 +30,11 @@ function quoteCypherIdentifier(name: string): string {
|
|||||||
return `\`${name.replace(/`/g, "``")}\``;
|
return `\`${name.replace(/`/g, "``")}\``;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function quoteJdbcIdentifier(name: string): string {
|
||||||
|
if (/^[A-Za-z_][A-Za-z0-9_$]*$/.test(name)) return name;
|
||||||
|
return `\`${name.replace(/`/g, "``")}\``;
|
||||||
|
}
|
||||||
|
|
||||||
export function qualifiedTableName(
|
export function qualifiedTableName(
|
||||||
options: Pick<BuildTableSelectSqlOptions, "databaseType" | "schema" | "tableName">,
|
options: Pick<BuildTableSelectSqlOptions, "databaseType" | "schema" | "tableName">,
|
||||||
): string {
|
): string {
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ pub fn qualified_table_name(database_type: Option<DatabaseType>, schema: Option<
|
|||||||
|
|
||||||
pub fn quote_table_identifier(database_type: Option<DatabaseType>, name: &str) -> String {
|
pub fn quote_table_identifier(database_type: Option<DatabaseType>, name: &str) -> String {
|
||||||
match database_type {
|
match database_type {
|
||||||
|
Some(DatabaseType::Jdbc) if is_simple_jdbc_identifier(name) => name.to_string(),
|
||||||
|
Some(DatabaseType::Jdbc) => format!("`{}`", name.replace('`', "``")),
|
||||||
Some(
|
Some(
|
||||||
DatabaseType::Mysql
|
DatabaseType::Mysql
|
||||||
| DatabaseType::Hive
|
| DatabaseType::Hive
|
||||||
@@ -368,6 +370,15 @@ fn is_simple_informix_identifier(name: &str) -> bool {
|
|||||||
&& chars.all(|ch| ch.is_ascii_alphanumeric() || ch == '_' || ch == '$')
|
&& chars.all(|ch| ch.is_ascii_alphanumeric() || ch == '_' || ch == '$')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_simple_jdbc_identifier(name: &str) -> bool {
|
||||||
|
let mut chars = name.chars();
|
||||||
|
let Some(first) = chars.next() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
(first.is_ascii_alphabetic() || first == '_')
|
||||||
|
&& chars.all(|ch| ch.is_ascii_alphanumeric() || ch == '_' || ch == '$')
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@@ -378,12 +389,18 @@ mod tests {
|
|||||||
assert_eq!(quote_table_identifier(Some(DatabaseType::SqlServer), "user]name"), "[user]]name]");
|
assert_eq!(quote_table_identifier(Some(DatabaseType::SqlServer), "user]name"), "[user]]name]");
|
||||||
assert_eq!(quote_table_identifier(Some(DatabaseType::Postgres), "user\"name"), "\"user\"\"name\"");
|
assert_eq!(quote_table_identifier(Some(DatabaseType::Postgres), "user\"name"), "\"user\"\"name\"");
|
||||||
assert_eq!(quote_table_identifier(Some(DatabaseType::Informix), "users_1"), "users_1");
|
assert_eq!(quote_table_identifier(Some(DatabaseType::Informix), "users_1"), "users_1");
|
||||||
|
assert_eq!(quote_table_identifier(Some(DatabaseType::Jdbc), "users_1"), "users_1");
|
||||||
|
assert_eq!(quote_table_identifier(Some(DatabaseType::Jdbc), "user name"), "`user name`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn qualifies_schema_only_for_schema_aware_databases() {
|
fn qualifies_schema_only_for_schema_aware_databases() {
|
||||||
assert_eq!(qualified_table_name(Some(DatabaseType::Postgres), Some("public"), "users"), "\"public\".\"users\"");
|
assert_eq!(qualified_table_name(Some(DatabaseType::Postgres), Some("public"), "users"), "\"public\".\"users\"");
|
||||||
assert_eq!(qualified_table_name(Some(DatabaseType::Mysql), Some("public"), "users"), "`users`");
|
assert_eq!(qualified_table_name(Some(DatabaseType::Mysql), Some("public"), "users"), "`users`");
|
||||||
|
assert_eq!(
|
||||||
|
qualified_table_name(Some(DatabaseType::Jdbc), Some("cbsdw_dwd"), "dwd_test_df"),
|
||||||
|
"cbsdw_dwd.dwd_test_df"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -413,6 +430,17 @@ mod tests {
|
|||||||
}),
|
}),
|
||||||
"SELECT TOP (100) [id], [name] FROM [dbo].[users] ORDER BY [id] ASC"
|
"SELECT TOP (100) [id], [name] FROM [dbo].[users] ORDER BY [id] ASC"
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
build_table_select_sql(TableSelectSqlOptions {
|
||||||
|
database_type: Some(DatabaseType::Jdbc),
|
||||||
|
schema: Some("cbsdw_dwd"),
|
||||||
|
table_name: "dwd_test_df",
|
||||||
|
columns: &[],
|
||||||
|
order_columns: &[],
|
||||||
|
limit: 100,
|
||||||
|
}),
|
||||||
|
"SELECT * FROM cbsdw_dwd.dwd_test_df LIMIT 100;"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { strict as assert } from "node:assert";
|
||||||
|
import test from "node:test";
|
||||||
|
import { qualifiedTableName, quoteTableIdentifier } from "../../apps/desktop/src/lib/tableSelectSql.ts";
|
||||||
|
|
||||||
|
test("JDBC table identifiers avoid double quotes for Kyuubi-compatible names", () => {
|
||||||
|
assert.equal(quoteTableIdentifier("jdbc", "cbsdw_dwd"), "cbsdw_dwd");
|
||||||
|
assert.equal(quoteTableIdentifier("jdbc", "dwd_test_df"), "dwd_test_df");
|
||||||
|
assert.equal(
|
||||||
|
qualifiedTableName({ databaseType: "jdbc", schema: "cbsdw_dwd", tableName: "dwd_test_df" }),
|
||||||
|
"cbsdw_dwd.dwd_test_df",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("JDBC table identifiers use backticks only when quoting is needed", () => {
|
||||||
|
assert.equal(quoteTableIdentifier("jdbc", "daily orders"), "`daily orders`");
|
||||||
|
assert.equal(quoteTableIdentifier("jdbc", "daily`orders"), "`daily``orders`");
|
||||||
|
});
|
||||||
Reference in new issue
Block a user