rawsql-ts 0.1.0-beta.11 → 0.1.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -18
- package/dist/esm/index.js +17 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/models/BinarySelectQuery.js +137 -0
- package/dist/esm/models/BinarySelectQuery.js.map +1 -0
- package/dist/esm/models/Clause.js +289 -0
- package/dist/esm/models/Clause.js.map +1 -0
- package/dist/esm/models/KeywordTrie.js +48 -0
- package/dist/esm/models/KeywordTrie.js.map +1 -0
- package/dist/esm/models/Lexeme.js +18 -0
- package/dist/esm/models/Lexeme.js.map +1 -0
- package/dist/esm/models/SelectQuery.js +5 -0
- package/dist/esm/models/SelectQuery.js.map +1 -0
- package/dist/esm/models/SimpleSelectQuery.js +288 -0
- package/dist/esm/models/SimpleSelectQuery.js.map +1 -0
- package/dist/esm/models/SqlComponent.js +22 -0
- package/dist/esm/models/SqlComponent.js.map +1 -0
- package/dist/esm/models/ValueComponent.js +223 -0
- package/dist/esm/models/ValueComponent.js.map +1 -0
- package/dist/esm/models/ValuesQuery.js +12 -0
- package/dist/esm/models/ValuesQuery.js.map +1 -0
- package/dist/esm/parsers/CommandExpressionParser.js +120 -0
- package/dist/esm/parsers/CommandExpressionParser.js.map +1 -0
- package/dist/esm/parsers/CommonTableParser.js +58 -0
- package/dist/esm/parsers/CommonTableParser.js.map +1 -0
- package/dist/esm/parsers/ForClauseParser.js +54 -0
- package/dist/esm/parsers/ForClauseParser.js.map +1 -0
- package/dist/esm/parsers/FromClauseParser.js +43 -0
- package/dist/esm/parsers/FromClauseParser.js.map +1 -0
- package/dist/esm/parsers/FunctionExpressionParser.js +174 -0
- package/dist/esm/parsers/FunctionExpressionParser.js.map +1 -0
- package/dist/esm/parsers/GroupByParser.js +54 -0
- package/dist/esm/parsers/GroupByParser.js.map +1 -0
- package/dist/esm/parsers/HavingParser.js +32 -0
- package/dist/esm/parsers/HavingParser.js.map +1 -0
- package/dist/esm/parsers/IdentifierParser.js +35 -0
- package/dist/esm/parsers/IdentifierParser.js.map +1 -0
- package/dist/esm/parsers/JoinClauseParser.js +101 -0
- package/dist/esm/parsers/JoinClauseParser.js.map +1 -0
- package/dist/esm/parsers/KeywordParser.js +87 -0
- package/dist/esm/parsers/KeywordParser.js.map +1 -0
- package/dist/esm/parsers/LimitClauseParser.js +46 -0
- package/dist/esm/parsers/LimitClauseParser.js.map +1 -0
- package/dist/esm/parsers/LiteralParser.js +34 -0
- package/dist/esm/parsers/LiteralParser.js.map +1 -0
- package/dist/esm/parsers/OrderByClauseParser.js +73 -0
- package/dist/esm/parsers/OrderByClauseParser.js.map +1 -0
- package/dist/esm/parsers/OverExpressionParser.js +40 -0
- package/dist/esm/parsers/OverExpressionParser.js.map +1 -0
- package/dist/esm/parsers/ParameterExpressionParser.js +11 -0
- package/dist/esm/parsers/ParameterExpressionParser.js.map +1 -0
- package/dist/esm/parsers/ParenExpressionParser.js +29 -0
- package/dist/esm/parsers/ParenExpressionParser.js.map +1 -0
- package/dist/esm/parsers/PartitionByParser.js +49 -0
- package/dist/esm/parsers/PartitionByParser.js.map +1 -0
- package/dist/esm/parsers/SelectClauseParser.js +80 -0
- package/dist/esm/parsers/SelectClauseParser.js.map +1 -0
- package/dist/esm/parsers/SelectQueryParser.js +149 -0
- package/dist/esm/parsers/SelectQueryParser.js.map +1 -0
- package/dist/esm/parsers/SourceAliasExpressionParser.js +45 -0
- package/dist/esm/parsers/SourceAliasExpressionParser.js.map +1 -0
- package/dist/esm/parsers/SourceExpressionParser.js +31 -0
- package/dist/esm/parsers/SourceExpressionParser.js.map +1 -0
- package/dist/esm/parsers/SourceParser.js +115 -0
- package/dist/esm/parsers/SourceParser.js.map +1 -0
- package/dist/esm/parsers/SqlTokenizer.js +170 -0
- package/dist/esm/parsers/SqlTokenizer.js.map +1 -0
- package/dist/esm/parsers/StringSpecifierExpressionParser.js +18 -0
- package/dist/esm/parsers/StringSpecifierExpressionParser.js.map +1 -0
- package/dist/esm/parsers/UnaryExpressionParser.js +26 -0
- package/dist/esm/parsers/UnaryExpressionParser.js.map +1 -0
- package/dist/esm/parsers/ValueParser.js +132 -0
- package/dist/esm/parsers/ValueParser.js.map +1 -0
- package/dist/esm/parsers/ValuesQueryParser.js +82 -0
- package/dist/esm/parsers/ValuesQueryParser.js.map +1 -0
- package/dist/esm/parsers/WhereClauseParser.js +32 -0
- package/dist/esm/parsers/WhereClauseParser.js.map +1 -0
- package/dist/esm/parsers/WindowClauseParser.js +41 -0
- package/dist/esm/parsers/WindowClauseParser.js.map +1 -0
- package/dist/esm/parsers/WindowExpressionParser.js +159 -0
- package/dist/esm/parsers/WindowExpressionParser.js.map +1 -0
- package/dist/esm/parsers/WithClauseParser.js +53 -0
- package/dist/esm/parsers/WithClauseParser.js.map +1 -0
- package/dist/esm/tokenReaders/BaseTokenReader.js +78 -0
- package/dist/esm/tokenReaders/BaseTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/CommandTokenReader.js +141 -0
- package/dist/esm/tokenReaders/CommandTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/FunctionTokenReader.js +41 -0
- package/dist/esm/tokenReaders/FunctionTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/IdentifierTokenReader.js +66 -0
- package/dist/esm/tokenReaders/IdentifierTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/LiteralTokenReader.js +185 -0
- package/dist/esm/tokenReaders/LiteralTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/OperatorTokenReader.js +94 -0
- package/dist/esm/tokenReaders/OperatorTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/ParameterTokenReader.js +40 -0
- package/dist/esm/tokenReaders/ParameterTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/StringSpecifierTokenReader.js +27 -0
- package/dist/esm/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/SymbolTokenReader.js +31 -0
- package/dist/esm/tokenReaders/SymbolTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/TokenReaderManager.js +106 -0
- package/dist/esm/tokenReaders/TokenReaderManager.js.map +1 -0
- package/dist/esm/tokenReaders/TypeTokenReader.js +55 -0
- package/dist/esm/tokenReaders/TypeTokenReader.js.map +1 -0
- package/dist/esm/transformers/CTEBuilder.js +184 -0
- package/dist/esm/transformers/CTEBuilder.js.map +1 -0
- package/dist/esm/transformers/CTECollector.js +380 -0
- package/dist/esm/transformers/CTECollector.js.map +1 -0
- package/dist/esm/transformers/CTEDisabler.js +321 -0
- package/dist/esm/transformers/CTEDisabler.js.map +1 -0
- package/dist/esm/transformers/CTEInjector.js +79 -0
- package/dist/esm/transformers/CTEInjector.js.map +1 -0
- package/dist/esm/transformers/CTENormalizer.js +42 -0
- package/dist/esm/transformers/CTENormalizer.js.map +1 -0
- package/dist/esm/transformers/Formatter.js +463 -0
- package/dist/esm/transformers/Formatter.js.map +1 -0
- package/dist/esm/transformers/QueryConverter.js +115 -0
- package/dist/esm/transformers/QueryConverter.js.map +1 -0
- package/dist/esm/transformers/SelectValueCollector.js +245 -0
- package/dist/esm/transformers/SelectValueCollector.js.map +1 -0
- package/dist/esm/transformers/SelectableColumnCollector.js +304 -0
- package/dist/esm/transformers/SelectableColumnCollector.js.map +1 -0
- package/dist/esm/transformers/TableColumnResolver.js +2 -0
- package/dist/esm/transformers/TableColumnResolver.js.map +1 -0
- package/dist/esm/transformers/TableSourceCollector.js +380 -0
- package/dist/esm/transformers/TableSourceCollector.js.map +1 -0
- package/dist/esm/transformers/UpstreamSelectQueryFinder.js +125 -0
- package/dist/esm/transformers/UpstreamSelectQueryFinder.js.map +1 -0
- package/dist/esm/types/index.d.ts +14 -0
- package/dist/esm/types/models/BinarySelectQuery.d.ts +91 -0
- package/dist/esm/types/models/Clause.d.ts +189 -0
- package/dist/esm/types/models/KeywordTrie.d.ts +11 -0
- package/dist/esm/types/models/Lexeme.d.ts +25 -0
- package/dist/esm/types/models/SelectQuery.d.ts +5 -0
- package/dist/esm/types/models/SimpleSelectQuery.d.ts +167 -0
- package/dist/esm/types/models/SqlComponent.d.ts +18 -0
- package/dist/esm/types/models/ValueComponent.d.ts +158 -0
- package/dist/esm/types/models/ValuesQuery.d.ts +10 -0
- package/dist/esm/types/parsers/CommandExpressionParser.d.ts +15 -0
- package/dist/esm/types/parsers/CommonTableParser.d.ts +9 -0
- package/dist/esm/types/parsers/ForClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/FromClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/FunctionExpressionParser.d.ts +22 -0
- package/dist/esm/types/parsers/GroupByParser.d.ts +10 -0
- package/dist/esm/types/parsers/HavingParser.d.ts +9 -0
- package/dist/esm/types/parsers/IdentifierParser.d.ts +8 -0
- package/dist/esm/types/parsers/JoinClauseParser.d.ts +14 -0
- package/dist/esm/types/parsers/KeywordParser.d.ts +17 -0
- package/dist/esm/types/parsers/LimitClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/LiteralParser.d.ts +8 -0
- package/dist/esm/types/parsers/OrderByClauseParser.d.ts +10 -0
- package/dist/esm/types/parsers/OverExpressionParser.d.ts +9 -0
- package/dist/esm/types/parsers/ParameterExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/ParenExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/PartitionByParser.d.ts +9 -0
- package/dist/esm/types/parsers/SelectClauseParser.d.ts +10 -0
- package/dist/esm/types/parsers/SelectQueryParser.d.ts +13 -0
- package/dist/esm/types/parsers/SourceAliasExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/SourceExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/SourceParser.d.ts +13 -0
- package/dist/esm/types/parsers/SqlTokenizer.d.ts +64 -0
- package/dist/esm/types/parsers/StringSpecifierExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/UnaryExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/ValueParser.d.ts +14 -0
- package/dist/esm/types/parsers/ValuesQueryParser.d.ts +10 -0
- package/dist/esm/types/parsers/WhereClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/WindowClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/WindowExpressionParser.d.ts +12 -0
- package/dist/esm/types/parsers/WithClauseParser.d.ts +9 -0
- package/dist/esm/types/tokenReaders/BaseTokenReader.d.ts +43 -0
- package/dist/esm/types/tokenReaders/CommandTokenReader.d.ts +7 -0
- package/dist/esm/types/tokenReaders/FunctionTokenReader.d.ts +11 -0
- package/dist/esm/types/tokenReaders/IdentifierTokenReader.d.ts +15 -0
- package/dist/esm/types/tokenReaders/LiteralTokenReader.d.ts +23 -0
- package/dist/esm/types/tokenReaders/OperatorTokenReader.d.ts +5 -0
- package/dist/esm/types/tokenReaders/ParameterTokenReader.d.ts +11 -0
- package/dist/esm/types/tokenReaders/StringSpecifierTokenReader.d.ts +8 -0
- package/dist/esm/types/tokenReaders/SymbolTokenReader.d.ts +12 -0
- package/dist/esm/types/tokenReaders/TokenReaderManager.d.ts +53 -0
- package/dist/esm/types/tokenReaders/TypeTokenReader.d.ts +11 -0
- package/dist/esm/types/transformers/CTEBuilder.d.ts +52 -0
- package/dist/esm/types/transformers/CTECollector.d.ts +81 -0
- package/dist/esm/types/transformers/CTEDisabler.d.ts +77 -0
- package/dist/esm/types/transformers/CTEInjector.d.ts +40 -0
- package/dist/esm/types/transformers/CTENormalizer.d.ts +25 -0
- package/dist/esm/types/transformers/Formatter.d.ts +82 -0
- package/dist/esm/types/transformers/QueryConverter.d.ts +41 -0
- package/dist/esm/types/transformers/SelectValueCollector.d.ts +60 -0
- package/dist/esm/types/transformers/SelectableColumnCollector.d.ts +70 -0
- package/dist/esm/types/transformers/TableColumnResolver.d.ts +10 -0
- package/dist/esm/types/transformers/TableSourceCollector.d.ts +92 -0
- package/dist/esm/types/transformers/UpstreamSelectQueryFinder.d.ts +27 -0
- package/dist/esm/types/utils/charLookupTable.d.ts +11 -0
- package/dist/esm/types/utils/stringUtils.d.ts +43 -0
- package/dist/esm/utils/charLookupTable.js +69 -0
- package/dist/esm/utils/charLookupTable.js.map +1 -0
- package/dist/esm/utils/stringUtils.js +164 -0
- package/dist/esm/utils/stringUtils.js.map +1 -0
- package/package.json +4 -1
@@ -0,0 +1,120 @@
|
|
1
|
+
import { TokenType } from "../models/Lexeme";
|
2
|
+
import { ArrayExpression, CaseExpression, CaseKeyValuePair, SwitchCaseArgument, UnaryExpression } from "../models/ValueComponent";
|
3
|
+
import { ValueParser } from "./ValueParser";
|
4
|
+
export class CommandExpressionParser {
|
5
|
+
static parseFromLexeme(lexemes, index) {
|
6
|
+
let idx = index;
|
7
|
+
const current = lexemes[idx];
|
8
|
+
if (current.value === "case") {
|
9
|
+
idx++;
|
10
|
+
return this.parseCaseExpression(lexemes, idx);
|
11
|
+
}
|
12
|
+
else if (current.value === "case when") {
|
13
|
+
idx++;
|
14
|
+
return this.parseCaseWhenExpression(lexemes, idx);
|
15
|
+
}
|
16
|
+
else if (current.value === "array") {
|
17
|
+
idx++;
|
18
|
+
return this.parseArrayExpression(lexemes, idx);
|
19
|
+
}
|
20
|
+
return this.parseModifierUnaryExpression(lexemes, idx);
|
21
|
+
}
|
22
|
+
static parseModifierUnaryExpression(lexemes, index) {
|
23
|
+
let idx = index;
|
24
|
+
// Check for modifier unary expression
|
25
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.Command) {
|
26
|
+
const command = lexemes[idx].value;
|
27
|
+
idx++;
|
28
|
+
const result = ValueParser.parseFromLexeme(lexemes, idx);
|
29
|
+
return { value: new UnaryExpression(command, result.value), newIndex: result.newIndex };
|
30
|
+
}
|
31
|
+
throw new Error(`Invalid modifier unary expression at index ${idx}, Lexeme: ${lexemes[idx].value}`);
|
32
|
+
}
|
33
|
+
static parseCaseExpression(lexemes, index) {
|
34
|
+
let idx = index;
|
35
|
+
const condition = ValueParser.parseFromLexeme(lexemes, idx);
|
36
|
+
idx = condition.newIndex;
|
37
|
+
const switchCaseResult = this.parseSwitchCaseArgument(lexemes, idx, []);
|
38
|
+
idx = switchCaseResult.newIndex;
|
39
|
+
// Create CASE expression
|
40
|
+
const result = new CaseExpression(condition.value, switchCaseResult.value);
|
41
|
+
return { value: result, newIndex: idx };
|
42
|
+
}
|
43
|
+
static parseCaseWhenExpression(lexemes, index) {
|
44
|
+
let idx = index;
|
45
|
+
// Parse the first WHEN clause
|
46
|
+
const casewhenResult = this.parseCaseConditionValuePair(lexemes, idx);
|
47
|
+
idx = casewhenResult.newIndex;
|
48
|
+
// Add the initial WHEN-THEN pair to the list
|
49
|
+
const caseWhenList = [casewhenResult.value];
|
50
|
+
// Process remaining WHEN-ELSE-END parts
|
51
|
+
const switchCaseResult = this.parseSwitchCaseArgument(lexemes, idx, caseWhenList);
|
52
|
+
idx = switchCaseResult.newIndex;
|
53
|
+
// Create CASE expression with condition null (uses WHEN conditions instead of a simple CASE)
|
54
|
+
const result = new CaseExpression(null, switchCaseResult.value);
|
55
|
+
return { value: result, newIndex: idx };
|
56
|
+
}
|
57
|
+
// parseSwitchCaseArgument method processes the WHEN, ELSE, and END clauses of a CASE expression.
|
58
|
+
static parseSwitchCaseArgument(lexemes, index, initialWhenThenList) {
|
59
|
+
let idx = index;
|
60
|
+
const whenThenList = [...initialWhenThenList];
|
61
|
+
let elseValue = null;
|
62
|
+
// Process WHEN clauses
|
63
|
+
while (idx < lexemes.length && this.isCommandWithValue(lexemes[idx], "when")) {
|
64
|
+
idx++;
|
65
|
+
const whenResult = this.parseCaseConditionValuePair(lexemes, idx);
|
66
|
+
idx = whenResult.newIndex;
|
67
|
+
whenThenList.push(whenResult.value);
|
68
|
+
}
|
69
|
+
// Process ELSE
|
70
|
+
if (idx < lexemes.length && this.isCommandWithValue(lexemes[idx], "else")) {
|
71
|
+
idx++;
|
72
|
+
const elseResult = ValueParser.parseFromLexeme(lexemes, idx);
|
73
|
+
elseValue = elseResult.value;
|
74
|
+
idx = elseResult.newIndex;
|
75
|
+
}
|
76
|
+
// Process END
|
77
|
+
if (idx < lexemes.length && this.isCommandWithValue(lexemes[idx], "end")) {
|
78
|
+
idx++;
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
throw new Error(`The CASE expression requires 'end' keyword at the end (index ${idx})`);
|
82
|
+
}
|
83
|
+
if (whenThenList.length === 0) {
|
84
|
+
throw new Error(`The CASE expression requires at least one WHEN clause (index ${idx})`);
|
85
|
+
}
|
86
|
+
// Create SwitchCaseArgument
|
87
|
+
const value = new SwitchCaseArgument(whenThenList, elseValue);
|
88
|
+
return { value, newIndex: idx };
|
89
|
+
}
|
90
|
+
// Helper method: Check if a lexeme is a Command token with the specified value
|
91
|
+
static isCommandWithValue(lexeme, value) {
|
92
|
+
return lexeme.type === TokenType.Command && lexeme.value === value;
|
93
|
+
}
|
94
|
+
static parseCaseConditionValuePair(lexemes, index) {
|
95
|
+
let idx = index;
|
96
|
+
const condition = ValueParser.parseFromLexeme(lexemes, idx);
|
97
|
+
idx = condition.newIndex;
|
98
|
+
// Check for the existence of the THEN keyword
|
99
|
+
if (idx >= lexemes.length || lexemes[idx].type !== TokenType.Command || lexemes[idx].value !== "then") {
|
100
|
+
throw new Error(`Expected 'then' after WHEN condition at index ${idx}`);
|
101
|
+
}
|
102
|
+
idx++; // Skip the THEN keyword
|
103
|
+
// Parse the value after THEN
|
104
|
+
const value = ValueParser.parseFromLexeme(lexemes, idx);
|
105
|
+
idx = value.newIndex;
|
106
|
+
return { value: new CaseKeyValuePair(condition.value, value.value), newIndex: idx };
|
107
|
+
}
|
108
|
+
static parseArrayExpression(lexemes, index) {
|
109
|
+
let idx = index;
|
110
|
+
// Array function is enclosed in []
|
111
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.OpenBracket) {
|
112
|
+
const arg = ValueParser.parseArgument(TokenType.OpenBracket, TokenType.CloseBracket, lexemes, idx);
|
113
|
+
idx = arg.newIndex;
|
114
|
+
const value = new ArrayExpression(arg.value);
|
115
|
+
return { value, newIndex: idx };
|
116
|
+
}
|
117
|
+
throw new Error(`Expected opening bracket '[' for array expression at index ${idx}`);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
//# sourceMappingURL=CommandExpressionParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"CommandExpressionParser.js","sourceRoot":"","sources":["../../../src/parsers/CommandExpressionParser.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import { CommonTable } from "../models/Clause";
|
2
|
+
import { TokenType } from "../models/Lexeme";
|
3
|
+
import { SqlTokenizer } from "./SqlTokenizer";
|
4
|
+
import { SelectQueryParser } from "./SelectQueryParser";
|
5
|
+
import { SourceAliasExpressionParser } from "./SourceAliasExpressionParser";
|
6
|
+
export class CommonTableParser {
|
7
|
+
// Parse SQL string to AST (was: parse)
|
8
|
+
static parse(query) {
|
9
|
+
const tokenizer = new SqlTokenizer(query); // Initialize tokenizer
|
10
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
11
|
+
// Parse
|
12
|
+
const result = this.parseFromLexeme(lexemes, 0);
|
13
|
+
// Error if there are remaining tokens
|
14
|
+
if (result.newIndex < lexemes.length) {
|
15
|
+
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The CommonTable definition is complete but there are additional tokens.`);
|
16
|
+
}
|
17
|
+
return result.value;
|
18
|
+
}
|
19
|
+
// Parse from lexeme array (was: parse)
|
20
|
+
static parseFromLexeme(lexemes, index) {
|
21
|
+
let idx = index;
|
22
|
+
// Parse alias and optional column aliases
|
23
|
+
// SourceAliasExpressionParser already handles column aliases if present
|
24
|
+
const aliasResult = SourceAliasExpressionParser.parseFromLexeme(lexemes, idx);
|
25
|
+
idx = aliasResult.newIndex;
|
26
|
+
if (idx < lexemes.length && lexemes[idx].value !== "as") {
|
27
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'AS' keyword after CTE name but found "${lexemes[idx].value}".`);
|
28
|
+
}
|
29
|
+
idx++; // Skip 'AS' keyword
|
30
|
+
// Materialized flag
|
31
|
+
let materialized = null;
|
32
|
+
// Parse optional MATERIALIZED or NOT MATERIALIZED keywords
|
33
|
+
if (idx < lexemes.length) {
|
34
|
+
const currentValue = lexemes[idx].value;
|
35
|
+
if (currentValue === "materialized") {
|
36
|
+
materialized = true;
|
37
|
+
idx++;
|
38
|
+
}
|
39
|
+
else if (currentValue === "not materialized") {
|
40
|
+
materialized = false;
|
41
|
+
idx++;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
if (idx < lexemes.length && lexemes[idx].type !== TokenType.OpenParen) {
|
45
|
+
throw new Error(`Syntax error at position ${idx}: Expected '(' after CTE name but found "${lexemes[idx].value}".`);
|
46
|
+
}
|
47
|
+
idx++; // Skip opening parenthesis
|
48
|
+
const queryResult = SelectQueryParser.parseFromLexeme(lexemes, idx);
|
49
|
+
idx = queryResult.newIndex;
|
50
|
+
if (idx < lexemes.length && lexemes[idx].type !== TokenType.CloseParen) {
|
51
|
+
throw new Error(`Syntax error at position ${idx}: Expected ')' after CTE query but found "${lexemes[idx].value}".`);
|
52
|
+
}
|
53
|
+
idx++; // Skip closing parenthesis
|
54
|
+
const value = new CommonTable(queryResult.value, aliasResult.value, materialized);
|
55
|
+
return { value, newIndex: idx };
|
56
|
+
}
|
57
|
+
}
|
58
|
+
//# sourceMappingURL=CommonTableParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"CommonTableParser.js","sourceRoot":"","sources":["../../../src/parsers/CommonTableParser.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { ForClause, LockMode } from "../models/Clause";
|
2
|
+
import { SqlTokenizer } from "./SqlTokenizer";
|
3
|
+
export class ForClauseParser {
|
4
|
+
// Parse SQL string to AST (was: parse)
|
5
|
+
static parse(query) {
|
6
|
+
const tokenizer = new SqlTokenizer(query);
|
7
|
+
const lexemes = tokenizer.readLexmes();
|
8
|
+
// Parse
|
9
|
+
const result = this.parseFromLexeme(lexemes, 0);
|
10
|
+
// Error if there are remaining tokens
|
11
|
+
if (result.newIndex < lexemes.length) {
|
12
|
+
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The FOR clause is complete but there are additional tokens.`);
|
13
|
+
}
|
14
|
+
return result.value;
|
15
|
+
}
|
16
|
+
// Parse from lexeme array (was: parse)
|
17
|
+
static parseFromLexeme(lexemes, index) {
|
18
|
+
let idx = index;
|
19
|
+
// Check for FOR keyword
|
20
|
+
if (lexemes[idx].value.toLowerCase() !== 'for') {
|
21
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'FOR' keyword but found "${lexemes[idx].value}". FOR clauses must start with the FOR keyword.`);
|
22
|
+
}
|
23
|
+
idx++;
|
24
|
+
if (idx >= lexemes.length) {
|
25
|
+
throw new Error(`Syntax error: Unexpected end of input after 'FOR' keyword. The FOR clause requires a lock mode specification.`);
|
26
|
+
}
|
27
|
+
// Parse lock mode
|
28
|
+
const lockModeValue = lexemes[idx].value;
|
29
|
+
let lockMode;
|
30
|
+
switch (lockModeValue) {
|
31
|
+
case 'update':
|
32
|
+
lockMode = LockMode.Update;
|
33
|
+
idx++;
|
34
|
+
break;
|
35
|
+
case 'share':
|
36
|
+
lockMode = LockMode.Share;
|
37
|
+
idx++;
|
38
|
+
break;
|
39
|
+
case 'key share':
|
40
|
+
lockMode = LockMode.KeyShare;
|
41
|
+
idx++;
|
42
|
+
break;
|
43
|
+
case 'no key update':
|
44
|
+
lockMode = LockMode.NokeyUpdate;
|
45
|
+
idx++;
|
46
|
+
break;
|
47
|
+
default:
|
48
|
+
throw new Error(`Syntax error at position ${idx}: Invalid lock mode "${lockModeValue}". Valid lock modes are: UPDATE, SHARE, KEY SHARE, NO KEY UPDATE.`);
|
49
|
+
}
|
50
|
+
const clause = new ForClause(lockMode);
|
51
|
+
return { value: clause, newIndex: idx };
|
52
|
+
}
|
53
|
+
}
|
54
|
+
//# sourceMappingURL=ForClauseParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ForClauseParser.js","sourceRoot":"","sources":["../../../src/parsers/ForClauseParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,OAAO,eAAe;IACxB,uCAAuC;IAChC,MAAM,CAAC,KAAK,CAAC,KAAa;QAC7B,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;QAEvC,QAAQ;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEhD,sCAAsC;QACtC,IAAI,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,iBAAiB,MAAM,CAAC,QAAQ,+DAA+D,CAAC,CAAC;QACtL,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;IAED,uCAAuC;IAChC,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,wBAAwB;QACxB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;YAC7C,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,uCAAuC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,iDAAiD,CAAC,CAAC;QAC/J,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,+GAA+G,CAAC,CAAC;QACrI,CAAC;QAED,kBAAkB;QAClB,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QACzC,IAAI,QAAkB,CAAC;QAEvB,QAAQ,aAAa,EAAE,CAAC;YACpB,KAAK,QAAQ;gBACT,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;gBAC3B,GAAG,EAAE,CAAC;gBACN,MAAM;YACV,KAAK,OAAO;gBACR,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC;gBAC1B,GAAG,EAAE,CAAC;gBACN,MAAM;YACV,KAAK,WAAW;gBACZ,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;gBAC7B,GAAG,EAAE,CAAC;gBACN,MAAM;YACV,KAAK,eAAe;gBAChB,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC;gBAChC,GAAG,EAAE,CAAC;gBACN,MAAM;YACV;gBACI,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,wBAAwB,aAAa,mEAAmE,CAAC,CAAC;QACjK,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IAC5C,CAAC;CACJ"}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { FromClause } from "../models/Clause";
|
2
|
+
import { SqlTokenizer } from "./SqlTokenizer";
|
3
|
+
import { JoinClauseParser } from "./JoinClauseParser";
|
4
|
+
import { SourceExpressionParser } from "./SourceExpressionParser";
|
5
|
+
export class FromClauseParser {
|
6
|
+
// Parse SQL string to AST (was: parse)
|
7
|
+
static parse(query) {
|
8
|
+
const tokenizer = new SqlTokenizer(query); // Initialize tokenizer
|
9
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
10
|
+
// Parse
|
11
|
+
const result = this.parseFromLexeme(lexemes, 0);
|
12
|
+
// Error if there are remaining tokens
|
13
|
+
if (result.newIndex < lexemes.length) {
|
14
|
+
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The FROM clause is complete but there are additional tokens.`);
|
15
|
+
}
|
16
|
+
return result.value;
|
17
|
+
}
|
18
|
+
// Parse from lexeme array (was: parse)
|
19
|
+
static parseFromLexeme(lexemes, index) {
|
20
|
+
let idx = index;
|
21
|
+
if (lexemes[idx].value !== 'from') {
|
22
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'FROM' keyword but found "${lexemes[idx].value}". FROM clauses must start with the FROM keyword.`);
|
23
|
+
}
|
24
|
+
idx++;
|
25
|
+
if (idx >= lexemes.length) {
|
26
|
+
throw new Error(`Syntax error: Unexpected end of input after 'FROM' keyword. The FROM clause requires a table reference.`);
|
27
|
+
}
|
28
|
+
// Parse the main source expression
|
29
|
+
const sourceExpression = SourceExpressionParser.parseFromLexeme(lexemes, idx);
|
30
|
+
idx = sourceExpression.newIndex;
|
31
|
+
const join = JoinClauseParser.tryParse(lexemes, idx);
|
32
|
+
idx = (join === null || join === void 0 ? void 0 : join.newIndex) || idx;
|
33
|
+
if (join !== null) {
|
34
|
+
const clause = new FromClause(sourceExpression.value, join.value);
|
35
|
+
return { value: clause, newIndex: idx };
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
const clause = new FromClause(sourceExpression.value, null);
|
39
|
+
return { value: clause, newIndex: idx };
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
//# sourceMappingURL=FromClauseParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"FromClauseParser.js","sourceRoot":"","sources":["../../../src/parsers/FromClauseParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,OAAO,gBAAgB;IACzB,uCAAuC;IAChC,MAAM,CAAC,KAAK,CAAC,KAAa;QAC7B,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB;QAClE,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa;QAErD,QAAQ;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEhD,sCAAsC;QACtC,IAAI,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,iBAAiB,MAAM,CAAC,QAAQ,gEAAgE,CAAC,CAAC;QACvL,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;IAED,uCAAuC;IAChC,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,wCAAwC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,mDAAmD,CAAC,CAAC;QAClK,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,yGAAyG,CAAC,CAAC;QAC/H,CAAC;QAED,mCAAmC;QACnC,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9E,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC;QAEhC,MAAM,IAAI,GAAG,gBAAgB,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACrD,GAAG,GAAG,CAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,QAAQ,KAAI,GAAG,CAAC;QAE5B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YAClE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC5C,CAAC;IACL,CAAC;CACJ"}
|
@@ -0,0 +1,174 @@
|
|
1
|
+
import { TokenType } from "../models/Lexeme";
|
2
|
+
import { FunctionCall, BinaryExpression, TypeValue, CastExpression, BetweenExpression } from "../models/ValueComponent";
|
3
|
+
import { OverExpressionParser } from "./OverExpressionParser";
|
4
|
+
import { ValueParser } from "./ValueParser";
|
5
|
+
export class FunctionExpressionParser {
|
6
|
+
static parseFromLexeme(lexemes, index) {
|
7
|
+
let idx = index;
|
8
|
+
const current = lexemes[idx];
|
9
|
+
if (current.value === "substring" || current.value === "overlay") {
|
10
|
+
return this.parseKeywordFunction(lexemes, idx, [
|
11
|
+
{ key: "from", required: false },
|
12
|
+
{ key: "for", required: false }
|
13
|
+
]);
|
14
|
+
}
|
15
|
+
else if (current.value === "cast") {
|
16
|
+
return this.parseKeywordFunction(lexemes, idx, [
|
17
|
+
{ key: "as", required: true }
|
18
|
+
]);
|
19
|
+
}
|
20
|
+
else if (current.value === "trim") {
|
21
|
+
return this.parseKeywordFunction(lexemes, idx, [
|
22
|
+
{ key: "from", required: false }
|
23
|
+
]);
|
24
|
+
}
|
25
|
+
return this.parseFunctionCall(lexemes, idx);
|
26
|
+
}
|
27
|
+
static tryParseBinaryExpression(lexemes, index, left, allowAndOperator = true) {
|
28
|
+
let idx = index;
|
29
|
+
// If the next element is an operator, process it as a binary expression
|
30
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.Operator) {
|
31
|
+
if (!allowAndOperator && lexemes[idx].value === "and") {
|
32
|
+
// Handle special case for "and" operator
|
33
|
+
return null;
|
34
|
+
}
|
35
|
+
const operator = lexemes[idx].value;
|
36
|
+
idx++;
|
37
|
+
// between
|
38
|
+
if (operator === "between") {
|
39
|
+
return this.parseBetweenExpression(lexemes, idx, left, false);
|
40
|
+
}
|
41
|
+
else if (operator === "not between") {
|
42
|
+
return this.parseBetweenExpression(lexemes, idx, left, true);
|
43
|
+
}
|
44
|
+
// ::
|
45
|
+
if (operator === "::") {
|
46
|
+
const typeValue = this.parseTypeValue(lexemes, idx);
|
47
|
+
idx = typeValue.newIndex;
|
48
|
+
const exp = new CastExpression(left, typeValue.value);
|
49
|
+
return { value: exp, newIndex: idx };
|
50
|
+
}
|
51
|
+
// Get the right-hand side value
|
52
|
+
const rightResult = ValueParser.parseFromLexeme(lexemes, idx);
|
53
|
+
idx = rightResult.newIndex;
|
54
|
+
// Create binary expression
|
55
|
+
const value = new BinaryExpression(left, operator, rightResult.value);
|
56
|
+
return { value, newIndex: idx };
|
57
|
+
}
|
58
|
+
return null;
|
59
|
+
}
|
60
|
+
static parseBetweenExpression(lexemes, index, value, negated) {
|
61
|
+
let idx = index;
|
62
|
+
const lower = ValueParser.parseFromLexeme(lexemes, idx, false);
|
63
|
+
idx = lower.newIndex;
|
64
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.Operator && lexemes[idx].value !== "and") {
|
65
|
+
throw new Error(`Expected 'and' after 'between' at index ${idx}`);
|
66
|
+
}
|
67
|
+
idx++;
|
68
|
+
const upper = ValueParser.parseFromLexeme(lexemes, idx);
|
69
|
+
idx = upper.newIndex;
|
70
|
+
const result = new BetweenExpression(value, lower.value, upper.value, negated);
|
71
|
+
return { value: result, newIndex: idx };
|
72
|
+
}
|
73
|
+
static parseFunctionCall(lexemes, index) {
|
74
|
+
let idx = index;
|
75
|
+
// Get function name
|
76
|
+
const result = lexemes[idx];
|
77
|
+
const functionName = result.value;
|
78
|
+
idx++;
|
79
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.OpenParen) {
|
80
|
+
// General argument parsing
|
81
|
+
const arg = ValueParser.parseArgument(TokenType.OpenParen, TokenType.CloseParen, lexemes, idx);
|
82
|
+
idx = arg.newIndex;
|
83
|
+
if (idx < lexemes.length && lexemes[idx].value === "over") {
|
84
|
+
const over = OverExpressionParser.parseFromLexeme(lexemes, idx);
|
85
|
+
idx = over.newIndex;
|
86
|
+
const value = new FunctionCall(functionName, arg.value, over.value);
|
87
|
+
return { value, newIndex: idx };
|
88
|
+
}
|
89
|
+
else {
|
90
|
+
const value = new FunctionCall(functionName, arg.value, null);
|
91
|
+
return { value, newIndex: idx };
|
92
|
+
}
|
93
|
+
}
|
94
|
+
else {
|
95
|
+
throw new Error(`Expected opening parenthesis after function name '${functionName}' at index ${idx}`);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
static parseKeywordFunction(lexemes, index, keywords) {
|
99
|
+
let idx = index;
|
100
|
+
const functionName = lexemes[idx].value;
|
101
|
+
idx++;
|
102
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.OpenParen) {
|
103
|
+
idx++;
|
104
|
+
const input = ValueParser.parseFromLexeme(lexemes, idx);
|
105
|
+
let arg = input.value;
|
106
|
+
idx = input.newIndex;
|
107
|
+
// Delegate to the standard function parser if parsing by comma
|
108
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.Comma) {
|
109
|
+
return this.parseFunctionCall(lexemes, index);
|
110
|
+
}
|
111
|
+
// Check keywords
|
112
|
+
for (const { key, required } of keywords) {
|
113
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.Command && lexemes[idx].value === key) {
|
114
|
+
idx++;
|
115
|
+
if (idx < lexemes.length && (lexemes[idx].type === TokenType.Type || lexemes[idx].maybeType === true)) {
|
116
|
+
const typeValue = this.parseTypeValue(lexemes, idx);
|
117
|
+
arg = new BinaryExpression(arg, key, typeValue.value);
|
118
|
+
idx = typeValue.newIndex;
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
const right = ValueParser.parseFromLexeme(lexemes, idx);
|
122
|
+
arg = new BinaryExpression(arg, key, right.value);
|
123
|
+
idx = right.newIndex;
|
124
|
+
}
|
125
|
+
}
|
126
|
+
else if (required) {
|
127
|
+
throw new Error(`Keyword '${key}' is required at index ${idx}`);
|
128
|
+
}
|
129
|
+
}
|
130
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.CloseParen) {
|
131
|
+
idx++;
|
132
|
+
if (idx < lexemes.length && lexemes[idx].value === "over") {
|
133
|
+
idx++;
|
134
|
+
const over = OverExpressionParser.parseFromLexeme(lexemes, idx);
|
135
|
+
idx = over.newIndex;
|
136
|
+
const value = new FunctionCall(functionName, arg, over.value);
|
137
|
+
return { value, newIndex: idx };
|
138
|
+
}
|
139
|
+
else {
|
140
|
+
const value = new FunctionCall(functionName, arg, null);
|
141
|
+
return { value, newIndex: idx };
|
142
|
+
}
|
143
|
+
}
|
144
|
+
else {
|
145
|
+
throw new Error(`Missing closing parenthesis for function '${functionName}' at index ${idx}`);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
throw new Error(`Missing opening parenthesis for function '${functionName}' at index ${idx}`);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
static parseTypeValue(lexemes, index) {
|
153
|
+
let idx = index;
|
154
|
+
// Check for type value
|
155
|
+
if (idx < lexemes.length && (lexemes[idx].type === TokenType.Type || lexemes[idx].maybeType === true)) {
|
156
|
+
const typeName = lexemes[idx].value;
|
157
|
+
idx++;
|
158
|
+
// Check for array type
|
159
|
+
if (idx < lexemes.length && lexemes[idx].type === TokenType.OpenParen) {
|
160
|
+
const arg = ValueParser.parseArgument(TokenType.OpenParen, TokenType.CloseParen, lexemes, idx);
|
161
|
+
idx = arg.newIndex;
|
162
|
+
const value = new TypeValue(typeName, arg.value);
|
163
|
+
return { value, newIndex: idx };
|
164
|
+
}
|
165
|
+
else {
|
166
|
+
// Create TypeValue
|
167
|
+
const value = new TypeValue(typeName);
|
168
|
+
return { value, newIndex: idx };
|
169
|
+
}
|
170
|
+
}
|
171
|
+
throw new Error(`Expected type value at index ${idx}`);
|
172
|
+
}
|
173
|
+
}
|
174
|
+
//# sourceMappingURL=FunctionExpressionParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"FunctionExpressionParser.js","sourceRoot":"","sources":["../../../src/parsers/FunctionExpressionParser.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import { GroupByClause } from "../models/Clause";
|
2
|
+
import { TokenType } from "../models/Lexeme";
|
3
|
+
import { SqlTokenizer } from "./SqlTokenizer";
|
4
|
+
import { ValueParser } from "./ValueParser";
|
5
|
+
export class GroupByClauseParser {
|
6
|
+
// Parse SQL string to AST (was: parse)
|
7
|
+
static parse(query) {
|
8
|
+
const tokenizer = new SqlTokenizer(query); // Initialize tokenizer
|
9
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
10
|
+
// Parse
|
11
|
+
const result = this.parseFromLexeme(lexemes, 0);
|
12
|
+
// Error if there are remaining tokens
|
13
|
+
if (result.newIndex < lexemes.length) {
|
14
|
+
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The GROUP BY clause is complete but there are additional tokens.`);
|
15
|
+
}
|
16
|
+
return result.value;
|
17
|
+
}
|
18
|
+
// Parse from lexeme array (was: parse)
|
19
|
+
static parseFromLexeme(lexemes, index) {
|
20
|
+
let idx = index;
|
21
|
+
if (lexemes[idx].value !== 'group by') {
|
22
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'GROUP BY' keyword but found "${lexemes[idx].value}". GROUP BY clauses must start with the GROUP BY keywords.`);
|
23
|
+
}
|
24
|
+
idx++;
|
25
|
+
if (idx >= lexemes.length) {
|
26
|
+
throw new Error(`Syntax error: Unexpected end of input after 'GROUP BY' keyword. The GROUP BY clause requires at least one expression to group by.`);
|
27
|
+
}
|
28
|
+
const items = [];
|
29
|
+
const item = this.parseItem(lexemes, idx);
|
30
|
+
items.push(item.value);
|
31
|
+
idx = item.newIndex;
|
32
|
+
while (idx < lexemes.length && lexemes[idx].type === TokenType.Comma) {
|
33
|
+
idx++;
|
34
|
+
const item = this.parseItem(lexemes, idx);
|
35
|
+
items.push(item.value);
|
36
|
+
idx = item.newIndex;
|
37
|
+
}
|
38
|
+
if (items.length === 0) {
|
39
|
+
throw new Error(`Syntax error at position ${index}: No grouping expressions found. The GROUP BY clause requires at least one expression to group by.`);
|
40
|
+
}
|
41
|
+
else {
|
42
|
+
const clause = new GroupByClause(items);
|
43
|
+
return { value: clause, newIndex: idx };
|
44
|
+
}
|
45
|
+
}
|
46
|
+
static parseItem(lexemes, index) {
|
47
|
+
let idx = index;
|
48
|
+
const parsedValue = ValueParser.parseFromLexeme(lexemes, idx);
|
49
|
+
const value = parsedValue.value;
|
50
|
+
idx = parsedValue.newIndex;
|
51
|
+
return { value, newIndex: idx };
|
52
|
+
}
|
53
|
+
}
|
54
|
+
//# sourceMappingURL=GroupByParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"GroupByParser.js","sourceRoot":"","sources":["../../../src/parsers/GroupByParser.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { HavingClause } from "../models/Clause";
|
2
|
+
import { SqlTokenizer } from "./SqlTokenizer";
|
3
|
+
import { ValueParser } from "./ValueParser";
|
4
|
+
export class HavingClauseParser {
|
5
|
+
// Parse SQL string to AST (was: parse)
|
6
|
+
static parse(query) {
|
7
|
+
const tokenizer = new SqlTokenizer(query); // Initialize tokenizer
|
8
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
9
|
+
// Parse
|
10
|
+
const result = this.parseFromLexeme(lexemes, 0);
|
11
|
+
// Error if there are remaining tokens
|
12
|
+
if (result.newIndex < lexemes.length) {
|
13
|
+
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The HAVING clause is complete but there are additional tokens.`);
|
14
|
+
}
|
15
|
+
return result.value;
|
16
|
+
}
|
17
|
+
// Parse from lexeme array (was: parse)
|
18
|
+
static parseFromLexeme(lexemes, index) {
|
19
|
+
let idx = index;
|
20
|
+
if (lexemes[idx].value !== 'having') {
|
21
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'HAVING' keyword but found "${lexemes[idx].value}". HAVING clauses must start with the HAVING keyword.`);
|
22
|
+
}
|
23
|
+
idx++;
|
24
|
+
if (idx >= lexemes.length) {
|
25
|
+
throw new Error(`Syntax error: Unexpected end of input after 'HAVING' keyword. The HAVING clause requires a condition expression.`);
|
26
|
+
}
|
27
|
+
const item = ValueParser.parseFromLexeme(lexemes, idx);
|
28
|
+
const clause = new HavingClause(item.value);
|
29
|
+
return { value: clause, newIndex: item.newIndex };
|
30
|
+
}
|
31
|
+
}
|
32
|
+
//# sourceMappingURL=HavingParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"HavingParser.js","sourceRoot":"","sources":["../../../src/parsers/HavingParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,OAAO,kBAAkB;IAC3B,uCAAuC;IAChC,MAAM,CAAC,KAAK,CAAC,KAAa;QAC7B,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB;QAClE,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,aAAa;QAErD,QAAQ;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEhD,sCAAsC;QACtC,IAAI,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,iBAAiB,MAAM,CAAC,QAAQ,kEAAkE,CAAC,CAAC;QACzL,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;IAED,uCAAuC;IAChC,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,0CAA0C,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,uDAAuD,CAAC,CAAC;QACxK,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,kHAAkH,CAAC,CAAC;QACxI,CAAC;QAED,MAAM,IAAI,GAAG,WAAW,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;CACJ"}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { TokenType } from "../models/Lexeme";
|
2
|
+
import { ColumnReference } from "../models/ValueComponent";
|
3
|
+
export class IdentifierParser {
|
4
|
+
static parseFromLexeme(lexemes, index) {
|
5
|
+
// Check for column reference pattern ([identifier dot] * n + identifier)
|
6
|
+
let idx = index;
|
7
|
+
const identifiers = [];
|
8
|
+
// Add the first identifier
|
9
|
+
identifiers.push(lexemes[idx].value);
|
10
|
+
idx++;
|
11
|
+
// Look for dot and identifier pattern
|
12
|
+
// support wildcard '*' as identifier (e.g. select t.* from t)
|
13
|
+
while (idx < lexemes.length &&
|
14
|
+
idx + 1 < lexemes.length &&
|
15
|
+
lexemes[idx].type === TokenType.Dot &&
|
16
|
+
(lexemes[idx + 1].type === TokenType.Identifier || lexemes[idx + 1].value === "*")) {
|
17
|
+
// Skip the dot and add the next identifier
|
18
|
+
idx++;
|
19
|
+
identifiers.push(lexemes[idx].value);
|
20
|
+
idx++;
|
21
|
+
}
|
22
|
+
if (identifiers.length > 1) {
|
23
|
+
// If there are multiple identifiers, treat it as a column reference
|
24
|
+
const lastIdentifier = identifiers.pop() || '';
|
25
|
+
const value = new ColumnReference(identifiers, lastIdentifier);
|
26
|
+
return { value, newIndex: idx };
|
27
|
+
}
|
28
|
+
else {
|
29
|
+
// If there is a single identifier, treat it as a simple identifier
|
30
|
+
const value = new ColumnReference(null, identifiers[0]);
|
31
|
+
return { value, newIndex: idx };
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
//# sourceMappingURL=IdentifierParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"IdentifierParser.js","sourceRoot":"","sources":["../../../src/parsers/IdentifierParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,0BAA0B,CAAC;AAE3E,MAAM,OAAO,gBAAgB;IAClB,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,yEAAyE;QACzE,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,2BAA2B;QAC3B,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QACrC,GAAG,EAAE,CAAC;QAEN,sCAAsC;QACtC,8DAA8D;QAC9D,OACI,GAAG,GAAG,OAAO,CAAC,MAAM;YACpB,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM;YACxB,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,GAAG;YACnC,CAAC,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,EACpF,CAAC;YACC,2CAA2C;YAC3C,GAAG,EAAE,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YACrC,GAAG,EAAE,CAAC;QACV,CAAC;QAED,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,oEAAoE;YACpE,MAAM,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;YAC/D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACpC,CAAC;aAAM,CAAC;YACJ,mEAAmE;YACnE,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YACxD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACpC,CAAC;IACL,CAAC;CACJ"}
|