rawsql-ts 0.1.0-beta.3 → 0.1.0-beta.5
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 +143 -199
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/models/BinarySelectQuery.js +140 -0
- package/dist/models/BinarySelectQuery.js.map +1 -0
- package/dist/models/Clause.js +318 -0
- package/dist/models/Clause.js.map +1 -0
- package/dist/models/KeywordTrie.js +52 -0
- package/dist/models/KeywordTrie.js.map +1 -0
- package/dist/models/Lexeme.js +21 -0
- package/dist/models/Lexeme.js.map +1 -0
- package/dist/models/SelectQuery.js +10 -0
- package/dist/models/SelectQuery.js.map +1 -0
- package/dist/models/SimpleSelectQuery.js +290 -0
- package/dist/models/SimpleSelectQuery.js.map +1 -0
- package/dist/models/SqlComponent.js +27 -0
- package/dist/models/SqlComponent.js.map +1 -0
- package/dist/models/ValueComponent.js +250 -0
- package/dist/models/ValueComponent.js.map +1 -0
- package/dist/models/ValuesQuery.js +16 -0
- package/dist/models/ValuesQuery.js.map +1 -0
- package/dist/parsers/CommandExpressionParser.js +124 -0
- package/dist/parsers/CommandExpressionParser.js.map +1 -0
- package/dist/parsers/CommonTableParser.js +60 -0
- package/dist/parsers/CommonTableParser.js.map +1 -0
- package/dist/parsers/ForClauseParser.js +56 -0
- package/dist/parsers/ForClauseParser.js.map +1 -0
- package/dist/parsers/FromClauseParser.js +45 -0
- package/dist/parsers/FromClauseParser.js.map +1 -0
- package/dist/parsers/FunctionExpressionParser.js +178 -0
- package/dist/parsers/FunctionExpressionParser.js.map +1 -0
- package/dist/parsers/GroupByParser.js +56 -0
- package/dist/parsers/GroupByParser.js.map +1 -0
- package/dist/parsers/HavingParser.js +34 -0
- package/dist/parsers/HavingParser.js.map +1 -0
- package/dist/parsers/IdentifierParser.js +39 -0
- package/dist/parsers/IdentifierParser.js.map +1 -0
- package/dist/parsers/JoinClauseParser.js +105 -0
- package/dist/parsers/JoinClauseParser.js.map +1 -0
- package/dist/parsers/KeywordParser.js +91 -0
- package/dist/parsers/KeywordParser.js.map +1 -0
- package/dist/parsers/LimitClauseParser.js +48 -0
- package/dist/parsers/LimitClauseParser.js.map +1 -0
- package/dist/parsers/LiteralParser.js +38 -0
- package/dist/parsers/LiteralParser.js.map +1 -0
- package/dist/parsers/OrderByClauseParser.js +75 -0
- package/dist/parsers/OrderByClauseParser.js.map +1 -0
- package/dist/parsers/OverExpressionParser.js +44 -0
- package/dist/parsers/OverExpressionParser.js.map +1 -0
- package/dist/parsers/ParameterExpressionParser.js +15 -0
- package/dist/parsers/ParameterExpressionParser.js.map +1 -0
- package/dist/parsers/ParenExpressionParser.js +33 -0
- package/dist/parsers/ParenExpressionParser.js.map +1 -0
- package/dist/parsers/PartitionByParser.js +51 -0
- package/dist/parsers/PartitionByParser.js.map +1 -0
- package/dist/parsers/SelectClauseParser.js +82 -0
- package/dist/parsers/SelectClauseParser.js.map +1 -0
- package/dist/parsers/SelectQueryParser.js +151 -0
- package/dist/parsers/SelectQueryParser.js.map +1 -0
- package/dist/parsers/SourceAliasExpressionParser.js +48 -0
- package/dist/parsers/SourceAliasExpressionParser.js.map +1 -0
- package/dist/parsers/SourceExpressionParser.js +34 -0
- package/dist/parsers/SourceExpressionParser.js.map +1 -0
- package/dist/parsers/SourceParser.js +116 -0
- package/dist/parsers/SourceParser.js.map +1 -0
- package/dist/parsers/SqlTokenizer.js +174 -0
- package/dist/parsers/SqlTokenizer.js.map +1 -0
- package/dist/parsers/StringSpecifierExpressionParser.js +22 -0
- package/dist/parsers/StringSpecifierExpressionParser.js.map +1 -0
- package/dist/parsers/UnaryExpressionParser.js +30 -0
- package/dist/parsers/UnaryExpressionParser.js.map +1 -0
- package/dist/parsers/ValueParser.js +134 -0
- package/dist/parsers/ValueParser.js.map +1 -0
- package/dist/parsers/ValuesQueryParser.js +86 -0
- package/dist/parsers/ValuesQueryParser.js.map +1 -0
- package/dist/parsers/WhereClauseParser.js +34 -0
- package/dist/parsers/WhereClauseParser.js.map +1 -0
- package/dist/parsers/WindowClauseParser.js +43 -0
- package/dist/parsers/WindowClauseParser.js.map +1 -0
- package/dist/parsers/WindowExpressionParser.js +151 -0
- package/dist/parsers/WindowExpressionParser.js.map +1 -0
- package/dist/parsers/WithClauseParser.js +55 -0
- package/dist/parsers/WithClauseParser.js.map +1 -0
- package/dist/tokenReaders/BaseTokenReader.js +82 -0
- package/dist/tokenReaders/BaseTokenReader.js.map +1 -0
- package/dist/tokenReaders/CommandTokenReader.js +145 -0
- package/dist/tokenReaders/CommandTokenReader.js.map +1 -0
- package/dist/tokenReaders/FunctionTokenReader.js +45 -0
- package/dist/tokenReaders/FunctionTokenReader.js.map +1 -0
- package/dist/tokenReaders/IdentifierTokenReader.js +70 -0
- package/dist/tokenReaders/IdentifierTokenReader.js.map +1 -0
- package/dist/tokenReaders/LiteralTokenReader.js +189 -0
- package/dist/tokenReaders/LiteralTokenReader.js.map +1 -0
- package/dist/tokenReaders/OperatorTokenReader.js +98 -0
- package/dist/tokenReaders/OperatorTokenReader.js.map +1 -0
- package/dist/tokenReaders/ParameterTokenReader.js +44 -0
- package/dist/tokenReaders/ParameterTokenReader.js.map +1 -0
- package/dist/tokenReaders/StringSpecifierTokenReader.js +31 -0
- package/dist/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
- package/dist/tokenReaders/SymbolTokenReader.js +35 -0
- package/dist/tokenReaders/SymbolTokenReader.js.map +1 -0
- package/dist/tokenReaders/TokenReaderManager.js +110 -0
- package/dist/tokenReaders/TokenReaderManager.js.map +1 -0
- package/dist/tokenReaders/TypeTokenReader.js +59 -0
- package/dist/tokenReaders/TypeTokenReader.js.map +1 -0
- package/dist/transformers/CTEBuilder.js +188 -0
- package/dist/transformers/CTEBuilder.js.map +1 -0
- package/dist/transformers/CTECollector.js +384 -0
- package/dist/transformers/CTECollector.js.map +1 -0
- package/dist/transformers/CTEDisabler.js +325 -0
- package/dist/transformers/CTEDisabler.js.map +1 -0
- package/dist/transformers/CTEInjector.js +83 -0
- package/dist/transformers/CTEInjector.js.map +1 -0
- package/dist/transformers/CTENormalizer.js +42 -0
- package/dist/transformers/CTENormalizer.js.map +1 -0
- package/dist/transformers/Formatter.js +452 -0
- package/dist/transformers/Formatter.js.map +1 -0
- package/dist/transformers/QueryNormalizer.js +114 -0
- package/dist/transformers/QueryNormalizer.js.map +1 -0
- package/dist/transformers/SelectValueCollector.js +249 -0
- package/dist/transformers/SelectValueCollector.js.map +1 -0
- package/dist/transformers/SelectableColumnCollector.js +308 -0
- package/dist/transformers/SelectableColumnCollector.js.map +1 -0
- package/dist/transformers/TableSourceCollector.js +384 -0
- package/dist/transformers/TableSourceCollector.js.map +1 -0
- package/dist/transformers/UpstreamSelectQueryFinder.js +129 -0
- package/dist/transformers/UpstreamSelectQueryFinder.js.map +1 -0
- package/dist/utils/charLookupTable.js +73 -0
- package/dist/utils/charLookupTable.js.map +1 -0
- package/dist/utils/stringUtils.js +168 -0
- package/dist/utils/stringUtils.js.map +1 -0
- package/package.json +2 -2
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/vitest.config.js +0 -15
- package/dist/vitest.config.js.map +0 -1
@@ -0,0 +1,124 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.CommandExpressionParser = void 0;
|
4
|
+
const Lexeme_1 = require("../models/Lexeme");
|
5
|
+
const ValueComponent_1 = require("../models/ValueComponent");
|
6
|
+
const ValueParser_1 = require("./ValueParser");
|
7
|
+
class CommandExpressionParser {
|
8
|
+
static parse(lexemes, index) {
|
9
|
+
let idx = index;
|
10
|
+
const current = lexemes[idx];
|
11
|
+
if (current.value === "case") {
|
12
|
+
idx++;
|
13
|
+
return this.parseCaseExpression(lexemes, idx);
|
14
|
+
}
|
15
|
+
else if (current.value === "case when") {
|
16
|
+
idx++;
|
17
|
+
return this.parseCaseWhenExpression(lexemes, idx);
|
18
|
+
}
|
19
|
+
else if (current.value === "array") {
|
20
|
+
idx++;
|
21
|
+
return this.parseArrayExpression(lexemes, idx);
|
22
|
+
}
|
23
|
+
return this.parseModifierUnaryExpression(lexemes, idx);
|
24
|
+
}
|
25
|
+
static parseModifierUnaryExpression(lexemes, index) {
|
26
|
+
let idx = index;
|
27
|
+
// Check for modifier unary expression
|
28
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Command) {
|
29
|
+
const command = lexemes[idx].value;
|
30
|
+
idx++;
|
31
|
+
const result = ValueParser_1.ValueParser.parse(lexemes, idx);
|
32
|
+
return { value: new ValueComponent_1.UnaryExpression(command, result.value), newIndex: result.newIndex };
|
33
|
+
}
|
34
|
+
throw new Error(`Invalid modifier unary expression at index ${idx}, Lexeme: ${lexemes[idx].value}`);
|
35
|
+
}
|
36
|
+
static parseCaseExpression(lexemes, index) {
|
37
|
+
let idx = index;
|
38
|
+
const condition = ValueParser_1.ValueParser.parse(lexemes, idx);
|
39
|
+
idx = condition.newIndex;
|
40
|
+
const switchCaseResult = this.parseSwitchCaseArgument(lexemes, idx, []);
|
41
|
+
idx = switchCaseResult.newIndex;
|
42
|
+
// Create CASE expression
|
43
|
+
const result = new ValueComponent_1.CaseExpression(condition.value, switchCaseResult.value);
|
44
|
+
return { value: result, newIndex: idx };
|
45
|
+
}
|
46
|
+
static parseCaseWhenExpression(lexemes, index) {
|
47
|
+
let idx = index;
|
48
|
+
// Parse the first WHEN clause
|
49
|
+
const casewhenResult = this.parseCaseConditionValuePair(lexemes, idx);
|
50
|
+
idx = casewhenResult.newIndex;
|
51
|
+
// Add the initial WHEN-THEN pair to the list
|
52
|
+
const caseWhenList = [casewhenResult.value];
|
53
|
+
// Process remaining WHEN-ELSE-END parts
|
54
|
+
const switchCaseResult = this.parseSwitchCaseArgument(lexemes, idx, caseWhenList);
|
55
|
+
idx = switchCaseResult.newIndex;
|
56
|
+
// Create CASE expression with condition null (uses WHEN conditions instead of a simple CASE)
|
57
|
+
const result = new ValueComponent_1.CaseExpression(null, switchCaseResult.value);
|
58
|
+
return { value: result, newIndex: idx };
|
59
|
+
}
|
60
|
+
// parseSwitchCaseArgument method processes the WHEN, ELSE, and END clauses of a CASE expression.
|
61
|
+
static parseSwitchCaseArgument(lexemes, index, initialWhenThenList) {
|
62
|
+
let idx = index;
|
63
|
+
const whenThenList = [...initialWhenThenList];
|
64
|
+
let elseValue = null;
|
65
|
+
// Process WHEN clauses
|
66
|
+
while (idx < lexemes.length && this.isCommandWithValue(lexemes[idx], "when")) {
|
67
|
+
idx++;
|
68
|
+
const whenResult = this.parseCaseConditionValuePair(lexemes, idx);
|
69
|
+
idx = whenResult.newIndex;
|
70
|
+
whenThenList.push(whenResult.value);
|
71
|
+
}
|
72
|
+
// Process ELSE
|
73
|
+
if (idx < lexemes.length && this.isCommandWithValue(lexemes[idx], "else")) {
|
74
|
+
idx++;
|
75
|
+
const elseResult = ValueParser_1.ValueParser.parse(lexemes, idx);
|
76
|
+
elseValue = elseResult.value;
|
77
|
+
idx = elseResult.newIndex;
|
78
|
+
}
|
79
|
+
// Process END
|
80
|
+
if (idx < lexemes.length && this.isCommandWithValue(lexemes[idx], "end")) {
|
81
|
+
idx++;
|
82
|
+
}
|
83
|
+
else {
|
84
|
+
throw new Error(`The CASE expression requires 'end' keyword at the end (index ${idx})`);
|
85
|
+
}
|
86
|
+
if (whenThenList.length === 0) {
|
87
|
+
throw new Error(`The CASE expression requires at least one WHEN clause (index ${idx})`);
|
88
|
+
}
|
89
|
+
// Create SwitchCaseArgument
|
90
|
+
const value = new ValueComponent_1.SwitchCaseArgument(whenThenList, elseValue);
|
91
|
+
return { value, newIndex: idx };
|
92
|
+
}
|
93
|
+
// Helper method: Check if a lexeme is a Command token with the specified value
|
94
|
+
static isCommandWithValue(lexeme, value) {
|
95
|
+
return lexeme.type === Lexeme_1.TokenType.Command && lexeme.value === value;
|
96
|
+
}
|
97
|
+
static parseCaseConditionValuePair(lexemes, index) {
|
98
|
+
let idx = index;
|
99
|
+
const condition = ValueParser_1.ValueParser.parse(lexemes, idx);
|
100
|
+
idx = condition.newIndex;
|
101
|
+
// Check for the existence of the THEN keyword
|
102
|
+
if (idx >= lexemes.length || lexemes[idx].type !== Lexeme_1.TokenType.Command || lexemes[idx].value !== "then") {
|
103
|
+
throw new Error(`Expected 'then' after WHEN condition at index ${idx}`);
|
104
|
+
}
|
105
|
+
idx++; // Skip the THEN keyword
|
106
|
+
// Parse the value after THEN
|
107
|
+
const value = ValueParser_1.ValueParser.parse(lexemes, idx);
|
108
|
+
idx = value.newIndex;
|
109
|
+
return { value: new ValueComponent_1.CaseKeyValuePair(condition.value, value.value), newIndex: idx };
|
110
|
+
}
|
111
|
+
static parseArrayExpression(lexemes, index) {
|
112
|
+
let idx = index;
|
113
|
+
// Array function is enclosed in []
|
114
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.OpenBracket) {
|
115
|
+
const arg = ValueParser_1.ValueParser.parseArgument(Lexeme_1.TokenType.OpenBracket, Lexeme_1.TokenType.CloseBracket, lexemes, idx);
|
116
|
+
idx = arg.newIndex;
|
117
|
+
const value = new ValueComponent_1.ArrayExpression(arg.value);
|
118
|
+
return { value, newIndex: idx };
|
119
|
+
}
|
120
|
+
throw new Error(`Expected opening bracket '[' for array expression at index ${idx}`);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
exports.CommandExpressionParser = CommandExpressionParser;
|
124
|
+
//# 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,60 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.CommonTableParser = void 0;
|
4
|
+
const Clause_1 = require("../models/Clause");
|
5
|
+
const Lexeme_1 = require("../models/Lexeme");
|
6
|
+
const SqlTokenizer_1 = require("./SqlTokenizer");
|
7
|
+
const SelectQueryParser_1 = require("./SelectQueryParser");
|
8
|
+
const SourceAliasExpressionParser_1 = require("./SourceAliasExpressionParser");
|
9
|
+
class CommonTableParser {
|
10
|
+
static parseFromText(query) {
|
11
|
+
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query); // Initialize tokenizer
|
12
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
13
|
+
// Parse
|
14
|
+
const result = this.parse(lexemes, 0);
|
15
|
+
// Error if there are remaining tokens
|
16
|
+
if (result.newIndex < lexemes.length) {
|
17
|
+
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.`);
|
18
|
+
}
|
19
|
+
return result.value;
|
20
|
+
}
|
21
|
+
static parse(lexemes, index) {
|
22
|
+
let idx = index;
|
23
|
+
// Parse alias and optional column aliases
|
24
|
+
// SourceAliasExpressionParser already handles column aliases if present
|
25
|
+
const aliasResult = SourceAliasExpressionParser_1.SourceAliasExpressionParser.parse(lexemes, idx);
|
26
|
+
idx = aliasResult.newIndex;
|
27
|
+
if (idx < lexemes.length && lexemes[idx].value !== "as") {
|
28
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'AS' keyword after CTE name but found "${lexemes[idx].value}".`);
|
29
|
+
}
|
30
|
+
idx++; // Skip 'AS' keyword
|
31
|
+
// Materialized flag
|
32
|
+
let materialized = null;
|
33
|
+
// Parse optional MATERIALIZED or NOT MATERIALIZED keywords
|
34
|
+
if (idx < lexemes.length) {
|
35
|
+
const currentValue = lexemes[idx].value;
|
36
|
+
if (currentValue === "materialized") {
|
37
|
+
materialized = true;
|
38
|
+
idx++;
|
39
|
+
}
|
40
|
+
else if (currentValue === "not materialized") {
|
41
|
+
materialized = false;
|
42
|
+
idx++;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
if (idx < lexemes.length && lexemes[idx].type !== Lexeme_1.TokenType.OpenParen) {
|
46
|
+
throw new Error(`Syntax error at position ${idx}: Expected '(' after CTE name but found "${lexemes[idx].value}".`);
|
47
|
+
}
|
48
|
+
idx++; // Skip opening parenthesis
|
49
|
+
const queryResult = SelectQueryParser_1.SelectQueryParser.parse(lexemes, idx);
|
50
|
+
idx = queryResult.newIndex;
|
51
|
+
if (idx < lexemes.length && lexemes[idx].type !== Lexeme_1.TokenType.CloseParen) {
|
52
|
+
throw new Error(`Syntax error at position ${idx}: Expected ')' after CTE query but found "${lexemes[idx].value}".`);
|
53
|
+
}
|
54
|
+
idx++; // Skip closing parenthesis
|
55
|
+
const value = new Clause_1.CommonTable(queryResult.value, aliasResult.value, materialized);
|
56
|
+
return { value, newIndex: idx };
|
57
|
+
}
|
58
|
+
}
|
59
|
+
exports.CommonTableParser = CommonTableParser;
|
60
|
+
//# 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,56 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.ForClauseParser = void 0;
|
4
|
+
const Clause_1 = require("../models/Clause");
|
5
|
+
const SqlTokenizer_1 = require("./SqlTokenizer");
|
6
|
+
class ForClauseParser {
|
7
|
+
static parseFromText(query) {
|
8
|
+
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query);
|
9
|
+
const lexemes = tokenizer.readLexmes();
|
10
|
+
// Parse
|
11
|
+
const result = this.parse(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 FOR clause is complete but there are additional tokens.`);
|
15
|
+
}
|
16
|
+
return result.value;
|
17
|
+
}
|
18
|
+
static parse(lexemes, index) {
|
19
|
+
let idx = index;
|
20
|
+
// Check for FOR keyword
|
21
|
+
if (lexemes[idx].value.toLowerCase() !== 'for') {
|
22
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'FOR' keyword but found "${lexemes[idx].value}". FOR clauses must start with the FOR keyword.`);
|
23
|
+
}
|
24
|
+
idx++;
|
25
|
+
if (idx >= lexemes.length) {
|
26
|
+
throw new Error(`Syntax error: Unexpected end of input after 'FOR' keyword. The FOR clause requires a lock mode specification.`);
|
27
|
+
}
|
28
|
+
// Parse lock mode
|
29
|
+
const lockModeValue = lexemes[idx].value;
|
30
|
+
let lockMode;
|
31
|
+
switch (lockModeValue) {
|
32
|
+
case 'update':
|
33
|
+
lockMode = Clause_1.LockMode.Update;
|
34
|
+
idx++;
|
35
|
+
break;
|
36
|
+
case 'share':
|
37
|
+
lockMode = Clause_1.LockMode.Share;
|
38
|
+
idx++;
|
39
|
+
break;
|
40
|
+
case 'key share':
|
41
|
+
lockMode = Clause_1.LockMode.KeyShare;
|
42
|
+
idx++;
|
43
|
+
break;
|
44
|
+
case 'no key update':
|
45
|
+
lockMode = Clause_1.LockMode.NokeyUpdate;
|
46
|
+
idx++;
|
47
|
+
break;
|
48
|
+
default:
|
49
|
+
throw new Error(`Syntax error at position ${idx}: Invalid lock mode "${lockModeValue}". Valid lock modes are: UPDATE, SHARE, KEY SHARE, NO KEY UPDATE.`);
|
50
|
+
}
|
51
|
+
const clause = new Clause_1.ForClause(lockMode);
|
52
|
+
return { value: clause, newIndex: idx };
|
53
|
+
}
|
54
|
+
}
|
55
|
+
exports.ForClauseParser = ForClauseParser;
|
56
|
+
//# sourceMappingURL=ForClauseParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ForClauseParser.js","sourceRoot":"","sources":["../../src/parsers/ForClauseParser.ts"],"names":[],"mappings":";;;AAAA,6CAAuD;AAEvD,iDAA8C;AAE9C,MAAa,eAAe;IACjB,MAAM,CAAC,aAAa,CAAC,KAAa;QACrC,MAAM,SAAS,GAAG,IAAI,2BAAY,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,EAAE,CAAC;QAEvC,QAAQ;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtC,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;IAEM,MAAM,CAAC,KAAK,CAAC,OAAiB,EAAE,KAAa;QAChD,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,iBAAQ,CAAC,MAAM,CAAC;gBAC3B,GAAG,EAAE,CAAC;gBACN,MAAM;YACV,KAAK,OAAO;gBACR,QAAQ,GAAG,iBAAQ,CAAC,KAAK,CAAC;gBAC1B,GAAG,EAAE,CAAC;gBACN,MAAM;YACV,KAAK,WAAW;gBACZ,QAAQ,GAAG,iBAAQ,CAAC,QAAQ,CAAC;gBAC7B,GAAG,EAAE,CAAC;gBACN,MAAM;YACV,KAAK,eAAe;gBAChB,QAAQ,GAAG,iBAAQ,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,kBAAS,CAAC,QAAQ,CAAC,CAAC;QACvC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IAC5C,CAAC;CACJ;AAzDD,0CAyDC"}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.FromClauseParser = void 0;
|
4
|
+
const Clause_1 = require("../models/Clause");
|
5
|
+
const SqlTokenizer_1 = require("./SqlTokenizer");
|
6
|
+
const JoinClauseParser_1 = require("./JoinClauseParser");
|
7
|
+
const SourceExpressionParser_1 = require("./SourceExpressionParser");
|
8
|
+
class FromClauseParser {
|
9
|
+
static parseFromText(query) {
|
10
|
+
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query); // Initialize tokenizer
|
11
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
12
|
+
// Parse
|
13
|
+
const result = this.parse(lexemes, 0);
|
14
|
+
// Error if there are remaining tokens
|
15
|
+
if (result.newIndex < lexemes.length) {
|
16
|
+
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.`);
|
17
|
+
}
|
18
|
+
return result.value;
|
19
|
+
}
|
20
|
+
static parse(lexemes, index) {
|
21
|
+
let idx = index;
|
22
|
+
if (lexemes[idx].value !== 'from') {
|
23
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'FROM' keyword but found "${lexemes[idx].value}". FROM clauses must start with the FROM keyword.`);
|
24
|
+
}
|
25
|
+
idx++;
|
26
|
+
if (idx >= lexemes.length) {
|
27
|
+
throw new Error(`Syntax error: Unexpected end of input after 'FROM' keyword. The FROM clause requires a table reference.`);
|
28
|
+
}
|
29
|
+
// Parse the main source expression
|
30
|
+
const sourceExpression = SourceExpressionParser_1.SourceExpressionParser.parse(lexemes, idx);
|
31
|
+
idx = sourceExpression.newIndex;
|
32
|
+
const join = JoinClauseParser_1.JoinClauseParser.tryParse(lexemes, idx);
|
33
|
+
idx = (join === null || join === void 0 ? void 0 : join.newIndex) || idx;
|
34
|
+
if (join !== null) {
|
35
|
+
const clause = new Clause_1.FromClause(sourceExpression.value, join.value);
|
36
|
+
return { value: clause, newIndex: idx };
|
37
|
+
}
|
38
|
+
else {
|
39
|
+
const clause = new Clause_1.FromClause(sourceExpression.value, null);
|
40
|
+
return { value: clause, newIndex: idx };
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
exports.FromClauseParser = FromClauseParser;
|
45
|
+
//# sourceMappingURL=FromClauseParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"FromClauseParser.js","sourceRoot":"","sources":["../../src/parsers/FromClauseParser.ts"],"names":[],"mappings":";;;AAAA,6CAA8C;AAE9C,iDAA8C;AAC9C,yDAAsD;AACtD,qEAAkE;AAElE,MAAa,gBAAgB;IAClB,MAAM,CAAC,aAAa,CAAC,KAAa;QACrC,MAAM,SAAS,GAAG,IAAI,2BAAY,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,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtC,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;IAEM,MAAM,CAAC,KAAK,CAAC,OAAiB,EAAE,KAAa;QAChD,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,+CAAsB,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACpE,GAAG,GAAG,gBAAgB,CAAC,QAAQ,CAAC;QAEhC,MAAM,IAAI,GAAG,mCAAgB,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,mBAAU,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,mBAAU,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;AA3CD,4CA2CC"}
|
@@ -0,0 +1,178 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.FunctionExpressionParser = void 0;
|
4
|
+
const Lexeme_1 = require("../models/Lexeme");
|
5
|
+
const ValueComponent_1 = require("../models/ValueComponent");
|
6
|
+
const OverExpressionParser_1 = require("./OverExpressionParser");
|
7
|
+
const ValueParser_1 = require("./ValueParser");
|
8
|
+
class FunctionExpressionParser {
|
9
|
+
static parse(lexemes, index) {
|
10
|
+
let idx = index;
|
11
|
+
const current = lexemes[idx];
|
12
|
+
if (current.value === "substring" || current.value === "overlay") {
|
13
|
+
return this.parseKeywordFunction(lexemes, idx, [
|
14
|
+
{ key: "from", required: false },
|
15
|
+
{ key: "for", required: false }
|
16
|
+
]);
|
17
|
+
}
|
18
|
+
else if (current.value === "cast") {
|
19
|
+
return this.parseKeywordFunction(lexemes, idx, [
|
20
|
+
{ key: "as", required: true }
|
21
|
+
]);
|
22
|
+
}
|
23
|
+
else if (current.value === "trim") {
|
24
|
+
return this.parseKeywordFunction(lexemes, idx, [
|
25
|
+
{ key: "from", required: false }
|
26
|
+
]);
|
27
|
+
}
|
28
|
+
return this.parseFunctionCall(lexemes, idx);
|
29
|
+
}
|
30
|
+
static tryParseBinaryExpression(lexemes, index, left, allowAndOperator = true) {
|
31
|
+
let idx = index;
|
32
|
+
// If the next element is an operator, process it as a binary expression
|
33
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Operator) {
|
34
|
+
if (!allowAndOperator && lexemes[idx].value === "and") {
|
35
|
+
// Handle special case for "and" operator
|
36
|
+
return null;
|
37
|
+
}
|
38
|
+
const operator = lexemes[idx].value;
|
39
|
+
idx++;
|
40
|
+
// between
|
41
|
+
if (operator === "between") {
|
42
|
+
return this.parseBetweenExpression(lexemes, idx, left, false);
|
43
|
+
}
|
44
|
+
else if (operator === "not between") {
|
45
|
+
return this.parseBetweenExpression(lexemes, idx, left, true);
|
46
|
+
}
|
47
|
+
// ::
|
48
|
+
if (operator === "::") {
|
49
|
+
const typeValue = this.parseTypeValue(lexemes, idx);
|
50
|
+
idx = typeValue.newIndex;
|
51
|
+
const exp = new ValueComponent_1.CastExpression(left, typeValue.value);
|
52
|
+
return { value: exp, newIndex: idx };
|
53
|
+
}
|
54
|
+
// Get the right-hand side value
|
55
|
+
const rightResult = ValueParser_1.ValueParser.parse(lexemes, idx);
|
56
|
+
idx = rightResult.newIndex;
|
57
|
+
// Create binary expression
|
58
|
+
const value = new ValueComponent_1.BinaryExpression(left, operator, rightResult.value);
|
59
|
+
return { value, newIndex: idx };
|
60
|
+
}
|
61
|
+
return null;
|
62
|
+
}
|
63
|
+
static parseBetweenExpression(lexemes, index, value, negated) {
|
64
|
+
let idx = index;
|
65
|
+
const lower = ValueParser_1.ValueParser.parse(lexemes, idx, false);
|
66
|
+
idx = lower.newIndex;
|
67
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Operator && lexemes[idx].value !== "and") {
|
68
|
+
throw new Error(`Expected 'and' after 'between' at index ${idx}`);
|
69
|
+
}
|
70
|
+
idx++;
|
71
|
+
const upper = ValueParser_1.ValueParser.parse(lexemes, idx);
|
72
|
+
idx = upper.newIndex;
|
73
|
+
const result = new ValueComponent_1.BetweenExpression(value, lower.value, upper.value, negated);
|
74
|
+
return { value: result, newIndex: idx };
|
75
|
+
}
|
76
|
+
static parseFunctionCall(lexemes, index) {
|
77
|
+
let idx = index;
|
78
|
+
// Get function name
|
79
|
+
const result = lexemes[idx];
|
80
|
+
const functionName = result.value;
|
81
|
+
idx++;
|
82
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.OpenParen) {
|
83
|
+
// General argument parsing
|
84
|
+
const arg = ValueParser_1.ValueParser.parseArgument(Lexeme_1.TokenType.OpenParen, Lexeme_1.TokenType.CloseParen, lexemes, idx);
|
85
|
+
idx = arg.newIndex;
|
86
|
+
if (idx < lexemes.length && lexemes[idx].value === "over") {
|
87
|
+
const over = OverExpressionParser_1.OverExpressionParser.parse(lexemes, idx);
|
88
|
+
idx = over.newIndex;
|
89
|
+
const value = new ValueComponent_1.FunctionCall(functionName, arg.value, over.value);
|
90
|
+
return { value, newIndex: idx };
|
91
|
+
}
|
92
|
+
else {
|
93
|
+
const value = new ValueComponent_1.FunctionCall(functionName, arg.value, null);
|
94
|
+
return { value, newIndex: idx };
|
95
|
+
}
|
96
|
+
}
|
97
|
+
else {
|
98
|
+
throw new Error(`Expected opening parenthesis after function name '${functionName}' at index ${idx}`);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
static parseKeywordFunction(lexemes, index, keywords) {
|
102
|
+
let idx = index;
|
103
|
+
const functionName = lexemes[idx].value;
|
104
|
+
idx++;
|
105
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.OpenParen) {
|
106
|
+
idx++;
|
107
|
+
const input = ValueParser_1.ValueParser.parse(lexemes, idx);
|
108
|
+
let arg = input.value;
|
109
|
+
idx = input.newIndex;
|
110
|
+
// Delegate to the standard function parser if parsing by comma
|
111
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Comma) {
|
112
|
+
return this.parseFunctionCall(lexemes, index);
|
113
|
+
}
|
114
|
+
// Check keywords
|
115
|
+
for (const { key, required } of keywords) {
|
116
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Command && lexemes[idx].value === key) {
|
117
|
+
idx++;
|
118
|
+
if (idx < lexemes.length && (lexemes[idx].type === Lexeme_1.TokenType.Type || lexemes[idx].maybeType === true)) {
|
119
|
+
const typeValue = this.parseTypeValue(lexemes, idx);
|
120
|
+
arg = new ValueComponent_1.BinaryExpression(arg, key, typeValue.value);
|
121
|
+
idx = typeValue.newIndex;
|
122
|
+
}
|
123
|
+
else {
|
124
|
+
const right = ValueParser_1.ValueParser.parse(lexemes, idx);
|
125
|
+
arg = new ValueComponent_1.BinaryExpression(arg, key, right.value);
|
126
|
+
idx = right.newIndex;
|
127
|
+
}
|
128
|
+
}
|
129
|
+
else if (required) {
|
130
|
+
throw new Error(`Keyword '${key}' is required at index ${idx}`);
|
131
|
+
}
|
132
|
+
}
|
133
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.CloseParen) {
|
134
|
+
idx++;
|
135
|
+
if (idx < lexemes.length && lexemes[idx].value === "over") {
|
136
|
+
idx++;
|
137
|
+
const over = OverExpressionParser_1.OverExpressionParser.parse(lexemes, idx);
|
138
|
+
idx = over.newIndex;
|
139
|
+
const value = new ValueComponent_1.FunctionCall(functionName, arg, over.value);
|
140
|
+
return { value, newIndex: idx };
|
141
|
+
}
|
142
|
+
else {
|
143
|
+
const value = new ValueComponent_1.FunctionCall(functionName, arg, null);
|
144
|
+
return { value, newIndex: idx };
|
145
|
+
}
|
146
|
+
}
|
147
|
+
else {
|
148
|
+
throw new Error(`Missing closing parenthesis for function '${functionName}' at index ${idx}`);
|
149
|
+
}
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
throw new Error(`Missing opening parenthesis for function '${functionName}' at index ${idx}`);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
static parseTypeValue(lexemes, index) {
|
156
|
+
let idx = index;
|
157
|
+
// Check for type value
|
158
|
+
if (idx < lexemes.length && (lexemes[idx].type === Lexeme_1.TokenType.Type || lexemes[idx].maybeType === true)) {
|
159
|
+
const typeName = lexemes[idx].value;
|
160
|
+
idx++;
|
161
|
+
// Check for array type
|
162
|
+
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.OpenParen) {
|
163
|
+
const arg = ValueParser_1.ValueParser.parseArgument(Lexeme_1.TokenType.OpenParen, Lexeme_1.TokenType.CloseParen, lexemes, idx);
|
164
|
+
idx = arg.newIndex;
|
165
|
+
const value = new ValueComponent_1.TypeValue(typeName, arg.value);
|
166
|
+
return { value, newIndex: idx };
|
167
|
+
}
|
168
|
+
else {
|
169
|
+
// Create TypeValue
|
170
|
+
const value = new ValueComponent_1.TypeValue(typeName);
|
171
|
+
return { value, newIndex: idx };
|
172
|
+
}
|
173
|
+
}
|
174
|
+
throw new Error(`Expected type value at index ${idx}`);
|
175
|
+
}
|
176
|
+
}
|
177
|
+
exports.FunctionExpressionParser = FunctionExpressionParser;
|
178
|
+
//# sourceMappingURL=FunctionExpressionParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"FunctionExpressionParser.js","sourceRoot":"","sources":["../../src/parsers/FunctionExpressionParser.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AACrD,6DAAwI;AACxI,iEAA8D;AAC9D,+CAA4C;AAE5C,MAAa,wBAAwB;IAC1B,MAAM,CAAC,KAAK,CAAC,OAAiB,EAAE,KAAa;QAChD,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAE7B,IAAI,OAAO,CAAC,KAAK,KAAK,WAAW,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/D,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,EAAE;gBAC3C,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;gBAChC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;aAClC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,EAAE;gBAC3C,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;aAChC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,GAAG,EAAE;gBAC3C,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;aACnC,CAAC,CAAC;QACP,CAAC;QAED,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IAEM,MAAM,CAAC,wBAAwB,CAAC,OAAiB,EAAE,KAAa,EAAE,IAAoB,EAAE,mBAA4B,IAAI;QAC3H,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,wEAAwE;QACxE,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,QAAQ,EAAE,CAAC;YACnE,IAAI,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;gBACpD,yCAAyC;gBACzC,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAe,CAAC;YAC9C,GAAG,EAAE,CAAC;YAEN,UAAU;YACV,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAClE,CAAC;iBAAM,IAAI,QAAQ,KAAK,aAAa,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,sBAAsB,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YACjE,CAAC;YAED,KAAK;YACL,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACpD,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC;gBACzB,MAAM,GAAG,GAAG,IAAI,+BAAc,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;gBACtD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;YACzC,CAAC;YAED,gCAAgC;YAChC,MAAM,WAAW,GAAG,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACpD,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC;YAE3B,2BAA2B;YAC3B,MAAM,KAAK,GAAG,IAAI,iCAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC;YACtE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACpC,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,MAAM,CAAC,sBAAsB,CAAC,OAAiB,EAAE,KAAa,EAAE,KAAqB,EAAE,OAAgB;QAC1G,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,KAAK,GAAG,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACrD,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;QAErB,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YACnG,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,MAAM,KAAK,GAAG,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9C,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;QACrB,MAAM,MAAM,GAAG,IAAI,kCAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/E,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IAC5C,CAAC;IAEO,MAAM,CAAC,iBAAiB,CAAC,OAAiB,EAAE,KAAa;QAC7D,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,oBAAoB;QACpB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC;QAClC,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,SAAS,EAAE,CAAC;YACpE,2BAA2B;YAC3B,MAAM,GAAG,GAAG,yBAAW,CAAC,aAAa,CAAC,kBAAS,CAAC,SAAS,EAAE,kBAAS,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC/F,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;YAEnB,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;gBACxD,MAAM,IAAI,GAAG,2CAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACtD,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;gBACpB,MAAM,KAAK,GAAG,IAAI,6BAAY,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBACpE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACJ,MAAM,KAAK,GAAG,IAAI,6BAAY,CAAC,YAAY,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBAC9D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;YACpC,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,KAAK,CAAC,qDAAqD,YAAY,cAAc,GAAG,EAAE,CAAC,CAAC;QAC1G,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,oBAAoB,CAC/B,OAAiB,EACjB,KAAa,EACb,QAA8C;QAE9C,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QACxC,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,SAAS,EAAE,CAAC;YACpE,GAAG,EAAE,CAAC;YAEN,MAAM,KAAK,GAAG,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9C,IAAI,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC;YACtB,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;YAErB,+DAA+D;YAC/D,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,KAAK,EAAE,CAAC;gBAChE,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAClD,CAAC;YAED,iBAAiB;YACjB,KAAK,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,QAAQ,EAAE,CAAC;gBACvC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC;oBAChG,GAAG,EAAE,CAAC;oBAEN,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE,CAAC;wBACpG,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;wBACpD,GAAG,GAAG,IAAI,iCAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;wBACtD,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC;oBAC7B,CAAC;yBAAM,CAAC;wBACJ,MAAM,KAAK,GAAG,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;wBAC9C,GAAG,GAAG,IAAI,iCAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;wBAClD,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC;oBACzB,CAAC;gBAEL,CAAC;qBAAM,IAAI,QAAQ,EAAE,CAAC;oBAClB,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,0BAA0B,GAAG,EAAE,CAAC,CAAC;gBACpE,CAAC;YACL,CAAC;YAED,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,UAAU,EAAE,CAAC;gBACrE,GAAG,EAAE,CAAC;gBACN,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;oBACxD,GAAG,EAAE,CAAC;oBACN,MAAM,IAAI,GAAG,2CAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;oBACtD,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;oBACpB,MAAM,KAAK,GAAG,IAAI,6BAAY,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;oBAC9D,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACJ,MAAM,KAAK,GAAG,IAAI,6BAAY,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;oBACxD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;gBACpC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,MAAM,IAAI,KAAK,CAAC,6CAA6C,YAAY,cAAc,GAAG,EAAE,CAAC,CAAC;YAClG,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,KAAK,CAAC,6CAA6C,YAAY,cAAc,GAAG,EAAE,CAAC,CAAC;QAClG,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,cAAc,CAAC,OAAiB,EAAE,KAAa;QACzD,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,uBAAuB;QACvB,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE,CAAC;YACpG,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YACpC,GAAG,EAAE,CAAC;YAEN,uBAAuB;YACvB,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,SAAS,EAAE,CAAC;gBACpE,MAAM,GAAG,GAAG,yBAAW,CAAC,aAAa,CAAC,kBAAS,CAAC,SAAS,EAAE,kBAAS,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC/F,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;gBACnB,MAAM,KAAK,GAAG,IAAI,0BAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;gBACjD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACJ,mBAAmB;gBACnB,MAAM,KAAK,GAAG,IAAI,0BAAS,CAAC,QAAQ,CAAC,CAAC;gBACtC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;YACpC,CAAC;QACL,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;IAC3D,CAAC;CACJ;AA5LD,4DA4LC"}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.GroupByClauseParser = void 0;
|
4
|
+
const Clause_1 = require("../models/Clause");
|
5
|
+
const Lexeme_1 = require("../models/Lexeme");
|
6
|
+
const SqlTokenizer_1 = require("./SqlTokenizer");
|
7
|
+
const ValueParser_1 = require("./ValueParser");
|
8
|
+
class GroupByClauseParser {
|
9
|
+
static parseFromText(query) {
|
10
|
+
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query); // Initialize tokenizer
|
11
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
12
|
+
// Parse
|
13
|
+
const result = this.parse(lexemes, 0);
|
14
|
+
// Error if there are remaining tokens
|
15
|
+
if (result.newIndex < lexemes.length) {
|
16
|
+
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.`);
|
17
|
+
}
|
18
|
+
return result.value;
|
19
|
+
}
|
20
|
+
static parse(lexemes, index) {
|
21
|
+
let idx = index;
|
22
|
+
if (lexemes[idx].value !== 'group by') {
|
23
|
+
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.`);
|
24
|
+
}
|
25
|
+
idx++;
|
26
|
+
if (idx >= lexemes.length) {
|
27
|
+
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.`);
|
28
|
+
}
|
29
|
+
const items = [];
|
30
|
+
const item = this.parseItem(lexemes, idx);
|
31
|
+
items.push(item.value);
|
32
|
+
idx = item.newIndex;
|
33
|
+
while (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.Comma) {
|
34
|
+
idx++;
|
35
|
+
const item = this.parseItem(lexemes, idx);
|
36
|
+
items.push(item.value);
|
37
|
+
idx = item.newIndex;
|
38
|
+
}
|
39
|
+
if (items.length === 0) {
|
40
|
+
throw new Error(`Syntax error at position ${index}: No grouping expressions found. The GROUP BY clause requires at least one expression to group by.`);
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
const clause = new Clause_1.GroupByClause(items);
|
44
|
+
return { value: clause, newIndex: idx };
|
45
|
+
}
|
46
|
+
}
|
47
|
+
static parseItem(lexemes, index) {
|
48
|
+
let idx = index;
|
49
|
+
const parsedValue = ValueParser_1.ValueParser.parse(lexemes, idx);
|
50
|
+
const value = parsedValue.value;
|
51
|
+
idx = parsedValue.newIndex;
|
52
|
+
return { value, newIndex: idx };
|
53
|
+
}
|
54
|
+
}
|
55
|
+
exports.GroupByClauseParser = GroupByClauseParser;
|
56
|
+
//# sourceMappingURL=GroupByParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"GroupByParser.js","sourceRoot":"","sources":["../../src/parsers/GroupByParser.ts"],"names":[],"mappings":";;;AAAA,6CAAiD;AACjD,6CAAqD;AAErD,iDAA8C;AAC9C,+CAA4C;AAE5C,MAAa,mBAAmB;IACrB,MAAM,CAAC,aAAa,CAAC,KAAa;QACrC,MAAM,SAAS,GAAG,IAAI,2BAAY,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,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtC,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,oEAAoE,CAAC,CAAC;QAC3L,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,OAAiB,EAAE,KAAa;QAChD,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,4CAA4C,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,4DAA4D,CAAC,CAAC;QAC/K,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,mIAAmI,CAAC,CAAC;QACzJ,CAAC;QAED,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QAEpB,OAAO,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,kBAAS,CAAC,KAAK,EAAE,CAAC;YACnE,GAAG,EAAE,CAAC;YACN,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxB,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,oGAAoG,CAAC,CAAC;QAC3J,CAAC;aAAM,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,sBAAa,CAAC,KAAK,CAAC,CAAC;YACxC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC5C,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,SAAS,CAAC,OAAiB,EAAE,KAAa;QACrD,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,MAAM,WAAW,GAAG,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC;QAChC,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC;QAE3B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IACpC,CAAC;CACJ;AAzDD,kDAyDC"}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.HavingClauseParser = void 0;
|
4
|
+
const Clause_1 = require("../models/Clause");
|
5
|
+
const SqlTokenizer_1 = require("./SqlTokenizer");
|
6
|
+
const ValueParser_1 = require("./ValueParser");
|
7
|
+
class HavingClauseParser {
|
8
|
+
static parseFromText(query) {
|
9
|
+
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query); // Initialize tokenizer
|
10
|
+
const lexemes = tokenizer.readLexmes(); // Get tokens
|
11
|
+
// Parse
|
12
|
+
const result = this.parse(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 HAVING clause is complete but there are additional tokens.`);
|
16
|
+
}
|
17
|
+
return result.value;
|
18
|
+
}
|
19
|
+
static parse(lexemes, index) {
|
20
|
+
let idx = index;
|
21
|
+
if (lexemes[idx].value !== 'having') {
|
22
|
+
throw new Error(`Syntax error at position ${idx}: Expected 'HAVING' keyword but found "${lexemes[idx].value}". HAVING clauses must start with the HAVING keyword.`);
|
23
|
+
}
|
24
|
+
idx++;
|
25
|
+
if (idx >= lexemes.length) {
|
26
|
+
throw new Error(`Syntax error: Unexpected end of input after 'HAVING' keyword. The HAVING clause requires a condition expression.`);
|
27
|
+
}
|
28
|
+
const item = ValueParser_1.ValueParser.parse(lexemes, idx);
|
29
|
+
const clause = new Clause_1.HavingClause(item.value);
|
30
|
+
return { value: clause, newIndex: item.newIndex };
|
31
|
+
}
|
32
|
+
}
|
33
|
+
exports.HavingClauseParser = HavingClauseParser;
|
34
|
+
//# sourceMappingURL=HavingParser.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"HavingParser.js","sourceRoot":"","sources":["../../src/parsers/HavingParser.ts"],"names":[],"mappings":";;;AAAA,6CAAgD;AAEhD,iDAA8C;AAC9C,+CAA4C;AAE5C,MAAa,kBAAkB;IACpB,MAAM,CAAC,aAAa,CAAC,KAAa;QACrC,MAAM,SAAS,GAAG,IAAI,2BAAY,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,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAEtC,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;IAEM,MAAM,CAAC,KAAK,CAAC,OAAiB,EAAE,KAAa;QAChD,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,yBAAW,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,qBAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE5C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;CACJ;AAjCD,gDAiCC"}
|