diff --git a/src/lib/tableSelectSql.ts b/src/lib/tableSelectSql.ts index 23be73701..8dde7b616 100644 --- a/src/lib/tableSelectSql.ts +++ b/src/lib/tableSelectSql.ts @@ -17,7 +17,7 @@ export interface BuildTableSelectSqlOptions { } export function quoteTableIdentifier(databaseType: DatabaseType | undefined, name: string): string { - if (databaseType === "mysql") return `\`${name.replace(/`/g, "``")}\``; + if (databaseType === "mysql" || databaseType === "hive") return `\`${name.replace(/`/g, "``")}\``; if (databaseType === "neo4j") return quoteCypherIdentifier(name); if (databaseType === "sqlserver") return `[${name.replace(/\]/g, "]]")}]`; return `"${name.replace(/"/g, '""')}"`; @@ -69,7 +69,9 @@ export function buildTableSelectSql(options: BuildTableSelectSqlOptions): string const order = orderBy ? ` ORDER BY ${orderBy}` : ""; const selectColumns = - options.includeRowId && databaseType === "oracle" ? `ROWIDTOCHAR(t.ROWID) AS "${DBX_ROWID_COLUMN}", t.*` : "*"; + options.includeRowId && databaseType === "oracle" + ? `ROWIDTOCHAR(t.ROWID) AS "${DBX_ROWID_COLUMN}", t.*` + : buildSelectColumns(databaseType, options.columns); const tableAlias = options.includeRowId && usesFetchFirst(databaseType) ? `${table} t` : table; if (usesFetchFirst(databaseType)) { @@ -83,7 +85,17 @@ export function buildTableSelectSql(options: BuildTableSelectSqlOptions): string } const offset = options.offset ? ` OFFSET ${options.offset}` : ""; - return `SELECT * FROM ${table}${where}${order} LIMIT ${limit}${offset};`; + return `SELECT ${selectColumns} FROM ${table}${where}${order} LIMIT ${limit}${offset};`; +} + +function buildSelectColumns(databaseType: DatabaseType | undefined, columns?: string[]): string { + if (databaseType !== "hive" || !columns?.length) return "*"; + return columns + .map((column) => { + const ident = quoteTableIdentifier(databaseType, column); + return `${ident} AS ${ident}`; + }) + .join(", "); } function buildNeo4jTableSelectSql(options: BuildTableSelectSqlOptions, limit: number): string { diff --git a/tests/dataGridSql.test.ts b/tests/dataGridSql.test.ts index d7c4ba4c7..7123487e6 100644 --- a/tests/dataGridSql.test.ts +++ b/tests/dataGridSql.test.ts @@ -38,6 +38,27 @@ test("builds SQL Server grid save statements with schema and bracket quoting", ( ]); }); +test("builds Hive grid save statements with backtick identifiers", () => { + const statements = buildDataGridSaveStatements({ + databaseType: "hive", + tableMeta: { + tableName: "department states", + primaryKeys: ["dept id"], + }, + columns: ["dept id", "display name"], + rows: [[10, "Sales"]], + dirtyRows: [[0, [[1, "Marketing"]]]], + deletedRows: [0], + newRows: [[20, "Engineering"]], + }); + + assert.deepEqual(statements, [ + "UPDATE `department states` SET `display name` = 'Marketing' WHERE `dept id` = 10;", + "DELETE FROM `department states` WHERE `dept id` = 10;", + "INSERT INTO `department states` (`dept id`, `display name`) VALUES (20, 'Engineering');", + ]); +}); + test("uses Oracle ROWID as a synthetic key without writing it as a normal column", () => { const statements = buildDataGridSaveStatements({ databaseType: "oracle", diff --git a/tests/tableSelectSql.test.ts b/tests/tableSelectSql.test.ts index c8f1742c1..0d3109fc5 100644 --- a/tests/tableSelectSql.test.ts +++ b/tests/tableSelectSql.test.ts @@ -28,6 +28,28 @@ test("builds a schema-qualified PostgreSQL table WHERE query", () => { assert.equal(sql, 'SELECT * FROM "public"."orders" WHERE (amount > 10) LIMIT 50 OFFSET 100;'); }); +test("builds Hive table data queries with backtick identifiers", () => { + const sql = buildTableSelectSql({ + databaseType: "hive", + tableName: "departments", + primaryKeys: ["dept id"], + limit: 100, + }); + + assert.equal(sql, "SELECT * FROM `departments` ORDER BY `dept id` ASC LIMIT 100;"); +}); + +test("expands Hive table data queries into aliased table columns", () => { + const sql = buildTableSelectSql({ + databaseType: "hive", + tableName: "departments", + columns: ["id", "name"], + limit: 100, + }); + + assert.equal(sql, "SELECT `id` AS `id`, `name` AS `name` FROM `departments` LIMIT 100;"); +}); + test("builds SQL Server first page query with schema-aware brackets", () => { const sql = buildTableSelectSql({ databaseType: "sqlserver",