fix(hana): improve metadata fallback and SQLScript parameters
This commit is contained in:
1 parent
fd80464cb2
commit
430f097602
6 files changed
+57
-22
No files matched your search
@@ -176,6 +176,11 @@ describe("extractSqlParameters", () => {
|
||||
const sql = "select value::int, value := 1, :actual_value";
|
||||
expect(extractSqlParameters(sql)).toEqual(["actual_value"]);
|
||||
});
|
||||
|
||||
it("ignores HANA SQLScript variable references", () => {
|
||||
const sql = "DO BEGIN Dummy1 = SELECT 1 FROM DUMMY; SELECT * FROM :Dummy1; END";
|
||||
expect(extractSqlParameters(sql, { databaseType: "saphana" })).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("substituteSqlParameters", () => {
|
||||
@@ -264,6 +269,11 @@ DEALLOCATE PREPARE stmt;`;
|
||||
}),
|
||||
).toBe("exec dbo.search_orders @date_start = '2026-07-04', @status = 'paid', @tenant_id = 7");
|
||||
});
|
||||
|
||||
it("keeps HANA SQLScript variable references while replacing template parameters", () => {
|
||||
const sql = "DO BEGIN Dummy1 = SELECT * FROM ORDERS WHERE TENANT_ID = ${tenant_id}; SELECT * FROM :Dummy1; END";
|
||||
expect(substituteSqlParameters(sql, { tenant_id: { kind: "number", value: "42" } }, { databaseType: "saphana" })).toBe("DO BEGIN Dummy1 = SELECT * FROM ORDERS WHERE TENANT_ID = 42; SELECT * FROM :Dummy1; END");
|
||||
});
|
||||
});
|
||||
|
||||
describe("sqlParameterLiteral", () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { DatabaseType } from "@/types/database";
|
||||
|
||||
export type SqlParameterValueKind = "string" | "number" | "boolean" | "null" | "raw";
|
||||
|
||||
export interface SqlParameterInput {
|
||||
@@ -19,19 +21,23 @@ interface ParameterOccurrence extends SqlParameterDescriptor {
|
||||
end: number;
|
||||
}
|
||||
|
||||
export interface SqlParameterOptions {
|
||||
databaseType?: DatabaseType;
|
||||
}
|
||||
|
||||
const PARAMETER_NAME_RE = /^[\p{L}_][\p{L}\p{N}_]*$/u;
|
||||
const PARAMETER_NAME_START_RE = /[\p{L}_]/u;
|
||||
const PARAMETER_NAME_CHAR_RE = /[\p{L}\p{N}_]/u;
|
||||
const SQL_SERVER_TEMP_TABLE_CONTEXT_KEYWORDS = new Set(["table", "from", "join", "into", "update", "truncate"]);
|
||||
|
||||
export function extractSqlParameters(sql: string): string[] {
|
||||
return extractSqlParameterDescriptors(sql).map((descriptor) => descriptor.key);
|
||||
export function extractSqlParameters(sql: string, options?: SqlParameterOptions): string[] {
|
||||
return extractSqlParameterDescriptors(sql, options).map((descriptor) => descriptor.key);
|
||||
}
|
||||
|
||||
export function extractSqlParameterDescriptors(sql: string): SqlParameterDescriptor[] {
|
||||
export function extractSqlParameterDescriptors(sql: string, options?: SqlParameterOptions): SqlParameterDescriptor[] {
|
||||
const names = new Set<string>();
|
||||
const descriptors: SqlParameterDescriptor[] = [];
|
||||
for (const occurrence of findSqlParameterOccurrences(sql)) {
|
||||
for (const occurrence of findSqlParameterOccurrences(sql, options)) {
|
||||
if (names.has(occurrence.key)) continue;
|
||||
names.add(occurrence.key);
|
||||
descriptors.push({
|
||||
@@ -44,8 +50,8 @@ export function extractSqlParameterDescriptors(sql: string): SqlParameterDescrip
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
export function substituteSqlParameters(sql: string, values: Record<string, SqlParameterInput>): string {
|
||||
const occurrences = findSqlParameterOccurrences(sql);
|
||||
export function substituteSqlParameters(sql: string, values: Record<string, SqlParameterInput>, options?: SqlParameterOptions): string {
|
||||
const occurrences = findSqlParameterOccurrences(sql, options);
|
||||
if (!occurrences.length) return sql;
|
||||
|
||||
let result = "";
|
||||
@@ -68,9 +74,10 @@ export function sqlParameterLiteral(input: SqlParameterInput): string {
|
||||
return quoteSqlString(raw);
|
||||
}
|
||||
|
||||
function findSqlParameterOccurrences(sql: string): ParameterOccurrence[] {
|
||||
function findSqlParameterOccurrences(sql: string, options?: SqlParameterOptions): ParameterOccurrence[] {
|
||||
const occurrences: ParameterOccurrence[] = [];
|
||||
const nativeSqlServerParameters = collectNativeSqlServerParameters(sql);
|
||||
const supportsNamedParameters = options?.databaseType !== "saphana";
|
||||
let i = 0;
|
||||
let dollarQuoteEnd = "";
|
||||
let positionalIndex = 0;
|
||||
@@ -110,7 +117,7 @@ function findSqlParameterOccurrences(sql: string): ParameterOccurrence[] {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (ch === ":") {
|
||||
if (ch === ":" && supportsNamedParameters) {
|
||||
const name = readParameterName(sql, i + 1);
|
||||
if (name && sql[i - 1] !== ":" && sql[i + 1] !== "=") {
|
||||
occurrences.push({
|
||||
|
||||
Reference in new issue
Block a user