From 7238d52d3ac9bf17ce026a36e510fe0305e36ede Mon Sep 17 00:00:00 2001 From: ondrejromancov Date: Tue, 11 Jun 2024 15:45:07 +0200 Subject: [PATCH 1/2] Add tests for database entities containing a hyphen in their name --- .../server/src/complete/utils/getLastToken.ts | 4 +- packages/server/test/complete.test.ts | 44 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/server/src/complete/utils/getLastToken.ts b/packages/server/src/complete/utils/getLastToken.ts index 94f291ef..297f6a50 100644 --- a/packages/server/src/complete/utils/getLastToken.ts +++ b/packages/server/src/complete/utils/getLastToken.ts @@ -1,6 +1,6 @@ -// Gets the last token from the given string considering that tokens can contain dots. +// Gets the last token from the given string considering that tokens can contain dots and dashes. export function getLastToken(sql: string): string { - const match = sql.match(/^(?:.|\s)*[^A-z0-9\\.:'"](.*?)$/) + const match = sql.match(/^(?:.|\s)*[^A-z0-9\\.\-:'"](.*?)$/) if (match) { let prevToken = '' let currentToken = match[1] diff --git a/packages/server/test/complete.test.ts b/packages/server/test/complete.test.ts index 3431372e..f02e747b 100644 --- a/packages/server/test/complete.test.ts +++ b/packages/server/test/complete.test.ts @@ -999,3 +999,47 @@ describe('DROP statement', () => { expect(result.candidates[0].label).toEqual('TABLE1') }) }) + +const SIMPLE_NESTED_SCHEMA_WITH_HYPHEN = { + tables: [ + { + catalog: 'catalog-3', + database: 'schema3', + tableName: 'table3', + columns: [{ columnName: 'abc', description: 'def' }], + }, + ], + functions: [], +} + +describe('Fully qualified table names with dash', () => { + test('complete catalog name', () => { + const result = complete( + 'SELECT * FROM catalog-3.sch', + { line: 0, column: 26 }, + SIMPLE_NESTED_SCHEMA_WITH_HYPHEN + ) + expect(result.candidates.length).toEqual(1) + const expected = [expect.objectContaining({ label: 'schema3' })] + expect(result.candidates).toEqual(expect.arrayContaining(expected)) + }) + test('complete table name', () => { + const result = complete( + 'SELECT * FROM catalog-3.schema3.tab', + { line: 0, column: 34 }, + SIMPLE_NESTED_SCHEMA_WITH_HYPHEN + ) + expect(result.candidates.length).toEqual(1) + const expected = [expect.objectContaining({ label: 'table3' })] + expect(result.candidates).toEqual(expect.arrayContaining(expected)) + }) + test('complete table name on dot', () => { + const result = complete( + 'SELECT * FROM catalog-3.schema3.', + { line: 0, column: 32 }, + SIMPLE_NESTED_SCHEMA_WITH_HYPHEN + ) + const expected = [expect.objectContaining({ label: 'table3' })] + expect(result.candidates).toEqual(expect.arrayContaining(expected)) + }) +}) From 82b651f997564de1653c9b6827f17f3d6b32a391 Mon Sep 17 00:00:00 2001 From: ondrejromancov Date: Tue, 11 Jun 2024 15:51:04 +0200 Subject: [PATCH 2/2] Support parsing database entities using a hyphen character --- packages/sql-parser/base/fromClauseParser.js | 4 ++-- packages/sql-parser/base/parser.js | 4 ++-- packages/sql-parser/parser.pegjs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/sql-parser/base/fromClauseParser.js b/packages/sql-parser/base/fromClauseParser.js index c44398fa..e62d7cf5 100644 --- a/packages/sql-parser/base/fromClauseParser.js +++ b/packages/sql-parser/base/fromClauseParser.js @@ -327,7 +327,7 @@ function peg$parse(input, options) { var peg$r2 = /^[^"]/; var peg$r3 = /^[.]/; var peg$r4 = /^[A-Za-z_]/; - var peg$r5 = /^[A-Za-z0-9_]/; + var peg$r5 = /^[A-Za-z0-9_\-]/; var peg$r6 = /^[A-Za-z0-9_:[\]']/; var peg$r7 = /^[:@]/; var peg$r8 = /^[^'\\\0-\x1F\x7F]/; @@ -364,7 +364,7 @@ function peg$parse(input, options) { var peg$e21 = peg$classExpectation(["\""], true, false); var peg$e22 = peg$classExpectation(["."], false, false); var peg$e23 = peg$classExpectation([["A", "Z"], ["a", "z"], "_"], false, false); - var peg$e24 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_"], false, false); + var peg$e24 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_", "-"], false, false); var peg$e25 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_", ":", "[", "]", "'"], false, false); var peg$e26 = peg$classExpectation([":", "@"], false, false); var peg$e27 = peg$literalExpectation("\"", false); diff --git a/packages/sql-parser/base/parser.js b/packages/sql-parser/base/parser.js index d8fb27b5..48b1bfbc 100644 --- a/packages/sql-parser/base/parser.js +++ b/packages/sql-parser/base/parser.js @@ -327,7 +327,7 @@ function peg$parse(input, options) { var peg$r2 = /^[^"]/; var peg$r3 = /^[.]/; var peg$r4 = /^[A-Za-z_]/; - var peg$r5 = /^[A-Za-z0-9_]/; + var peg$r5 = /^[A-Za-z0-9_\-]/; var peg$r6 = /^[A-Za-z0-9_:[\]']/; var peg$r7 = /^[:@]/; var peg$r8 = /^[^'\\\0-\x1F\x7F]/; @@ -364,7 +364,7 @@ function peg$parse(input, options) { var peg$e21 = peg$classExpectation(["\""], true, false); var peg$e22 = peg$classExpectation(["."], false, false); var peg$e23 = peg$classExpectation([["A", "Z"], ["a", "z"], "_"], false, false); - var peg$e24 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_"], false, false); + var peg$e24 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_", "-"], false, false); var peg$e25 = peg$classExpectation([["A", "Z"], ["a", "z"], ["0", "9"], "_", ":", "[", "]", "'"], false, false); var peg$e26 = peg$classExpectation([":", "@"], false, false); var peg$e27 = peg$literalExpectation("\"", false); diff --git a/packages/sql-parser/parser.pegjs b/packages/sql-parser/parser.pegjs index c9dfa489..f02b8def 100644 --- a/packages/sql-parser/parser.pegjs +++ b/packages/sql-parser/parser.pegjs @@ -843,7 +843,7 @@ ident_name ident_start = [A-Za-z_] -ident_part = [A-Za-z0-9_] +ident_part = [A-Za-z0-9_-] // to support column name like `cf1:name` in hbase // Allow square brackets and quote to support nested columns with subscripts for example `books['title'].chapters[12].paragraphs`