rawsql-ts 0.1.1-beta.1 → 0.1.1-beta.2

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.
Files changed (199) hide show
  1. package/dist/esm/index.js +17 -0
  2. package/dist/esm/index.js.map +1 -0
  3. package/dist/esm/models/BinarySelectQuery.js +137 -0
  4. package/dist/esm/models/BinarySelectQuery.js.map +1 -0
  5. package/dist/esm/models/Clause.js +289 -0
  6. package/dist/esm/models/Clause.js.map +1 -0
  7. package/dist/esm/models/KeywordTrie.js +48 -0
  8. package/dist/esm/models/KeywordTrie.js.map +1 -0
  9. package/dist/esm/models/Lexeme.js +18 -0
  10. package/dist/esm/models/Lexeme.js.map +1 -0
  11. package/dist/esm/models/SelectQuery.js +5 -0
  12. package/dist/esm/models/SelectQuery.js.map +1 -0
  13. package/dist/esm/models/SimpleSelectQuery.js +288 -0
  14. package/dist/esm/models/SimpleSelectQuery.js.map +1 -0
  15. package/dist/esm/models/SqlComponent.js +22 -0
  16. package/dist/esm/models/SqlComponent.js.map +1 -0
  17. package/dist/esm/models/ValueComponent.js +223 -0
  18. package/dist/esm/models/ValueComponent.js.map +1 -0
  19. package/dist/esm/models/ValuesQuery.js +12 -0
  20. package/dist/esm/models/ValuesQuery.js.map +1 -0
  21. package/dist/esm/parsers/CommandExpressionParser.js +120 -0
  22. package/dist/esm/parsers/CommandExpressionParser.js.map +1 -0
  23. package/dist/esm/parsers/CommonTableParser.js +58 -0
  24. package/dist/esm/parsers/CommonTableParser.js.map +1 -0
  25. package/dist/esm/parsers/ForClauseParser.js +54 -0
  26. package/dist/esm/parsers/ForClauseParser.js.map +1 -0
  27. package/dist/esm/parsers/FromClauseParser.js +43 -0
  28. package/dist/esm/parsers/FromClauseParser.js.map +1 -0
  29. package/dist/esm/parsers/FunctionExpressionParser.js +174 -0
  30. package/dist/esm/parsers/FunctionExpressionParser.js.map +1 -0
  31. package/dist/esm/parsers/GroupByParser.js +54 -0
  32. package/dist/esm/parsers/GroupByParser.js.map +1 -0
  33. package/dist/esm/parsers/HavingParser.js +32 -0
  34. package/dist/esm/parsers/HavingParser.js.map +1 -0
  35. package/dist/esm/parsers/IdentifierParser.js +35 -0
  36. package/dist/esm/parsers/IdentifierParser.js.map +1 -0
  37. package/dist/esm/parsers/JoinClauseParser.js +101 -0
  38. package/dist/esm/parsers/JoinClauseParser.js.map +1 -0
  39. package/dist/esm/parsers/KeywordParser.js +87 -0
  40. package/dist/esm/parsers/KeywordParser.js.map +1 -0
  41. package/dist/esm/parsers/LimitClauseParser.js +46 -0
  42. package/dist/esm/parsers/LimitClauseParser.js.map +1 -0
  43. package/dist/esm/parsers/LiteralParser.js +34 -0
  44. package/dist/esm/parsers/LiteralParser.js.map +1 -0
  45. package/dist/esm/parsers/OrderByClauseParser.js +73 -0
  46. package/dist/esm/parsers/OrderByClauseParser.js.map +1 -0
  47. package/dist/esm/parsers/OverExpressionParser.js +40 -0
  48. package/dist/esm/parsers/OverExpressionParser.js.map +1 -0
  49. package/dist/esm/parsers/ParameterExpressionParser.js +11 -0
  50. package/dist/esm/parsers/ParameterExpressionParser.js.map +1 -0
  51. package/dist/esm/parsers/ParenExpressionParser.js +29 -0
  52. package/dist/esm/parsers/ParenExpressionParser.js.map +1 -0
  53. package/dist/esm/parsers/PartitionByParser.js +49 -0
  54. package/dist/esm/parsers/PartitionByParser.js.map +1 -0
  55. package/dist/esm/parsers/SelectClauseParser.js +80 -0
  56. package/dist/esm/parsers/SelectClauseParser.js.map +1 -0
  57. package/dist/esm/parsers/SelectQueryParser.js +149 -0
  58. package/dist/esm/parsers/SelectQueryParser.js.map +1 -0
  59. package/dist/esm/parsers/SourceAliasExpressionParser.js +45 -0
  60. package/dist/esm/parsers/SourceAliasExpressionParser.js.map +1 -0
  61. package/dist/esm/parsers/SourceExpressionParser.js +31 -0
  62. package/dist/esm/parsers/SourceExpressionParser.js.map +1 -0
  63. package/dist/esm/parsers/SourceParser.js +115 -0
  64. package/dist/esm/parsers/SourceParser.js.map +1 -0
  65. package/dist/esm/parsers/SqlTokenizer.js +170 -0
  66. package/dist/esm/parsers/SqlTokenizer.js.map +1 -0
  67. package/dist/esm/parsers/StringSpecifierExpressionParser.js +18 -0
  68. package/dist/esm/parsers/StringSpecifierExpressionParser.js.map +1 -0
  69. package/dist/esm/parsers/UnaryExpressionParser.js +26 -0
  70. package/dist/esm/parsers/UnaryExpressionParser.js.map +1 -0
  71. package/dist/esm/parsers/ValueParser.js +132 -0
  72. package/dist/esm/parsers/ValueParser.js.map +1 -0
  73. package/dist/esm/parsers/ValuesQueryParser.js +82 -0
  74. package/dist/esm/parsers/ValuesQueryParser.js.map +1 -0
  75. package/dist/esm/parsers/WhereClauseParser.js +32 -0
  76. package/dist/esm/parsers/WhereClauseParser.js.map +1 -0
  77. package/dist/esm/parsers/WindowClauseParser.js +41 -0
  78. package/dist/esm/parsers/WindowClauseParser.js.map +1 -0
  79. package/dist/esm/parsers/WindowExpressionParser.js +159 -0
  80. package/dist/esm/parsers/WindowExpressionParser.js.map +1 -0
  81. package/dist/esm/parsers/WithClauseParser.js +53 -0
  82. package/dist/esm/parsers/WithClauseParser.js.map +1 -0
  83. package/dist/esm/tokenReaders/BaseTokenReader.js +78 -0
  84. package/dist/esm/tokenReaders/BaseTokenReader.js.map +1 -0
  85. package/dist/esm/tokenReaders/CommandTokenReader.js +141 -0
  86. package/dist/esm/tokenReaders/CommandTokenReader.js.map +1 -0
  87. package/dist/esm/tokenReaders/FunctionTokenReader.js +41 -0
  88. package/dist/esm/tokenReaders/FunctionTokenReader.js.map +1 -0
  89. package/dist/esm/tokenReaders/IdentifierTokenReader.js +66 -0
  90. package/dist/esm/tokenReaders/IdentifierTokenReader.js.map +1 -0
  91. package/dist/esm/tokenReaders/LiteralTokenReader.js +185 -0
  92. package/dist/esm/tokenReaders/LiteralTokenReader.js.map +1 -0
  93. package/dist/esm/tokenReaders/OperatorTokenReader.js +94 -0
  94. package/dist/esm/tokenReaders/OperatorTokenReader.js.map +1 -0
  95. package/dist/esm/tokenReaders/ParameterTokenReader.js +40 -0
  96. package/dist/esm/tokenReaders/ParameterTokenReader.js.map +1 -0
  97. package/dist/esm/tokenReaders/StringSpecifierTokenReader.js +27 -0
  98. package/dist/esm/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
  99. package/dist/esm/tokenReaders/SymbolTokenReader.js +31 -0
  100. package/dist/esm/tokenReaders/SymbolTokenReader.js.map +1 -0
  101. package/dist/esm/tokenReaders/TokenReaderManager.js +106 -0
  102. package/dist/esm/tokenReaders/TokenReaderManager.js.map +1 -0
  103. package/dist/esm/tokenReaders/TypeTokenReader.js +55 -0
  104. package/dist/esm/tokenReaders/TypeTokenReader.js.map +1 -0
  105. package/dist/esm/transformers/CTEBuilder.js +184 -0
  106. package/dist/esm/transformers/CTEBuilder.js.map +1 -0
  107. package/dist/esm/transformers/CTECollector.js +384 -0
  108. package/dist/esm/transformers/CTECollector.js.map +1 -0
  109. package/dist/esm/transformers/CTEDisabler.js +321 -0
  110. package/dist/esm/transformers/CTEDisabler.js.map +1 -0
  111. package/dist/esm/transformers/CTEInjector.js +79 -0
  112. package/dist/esm/transformers/CTEInjector.js.map +1 -0
  113. package/dist/esm/transformers/CTENormalizer.js +42 -0
  114. package/dist/esm/transformers/CTENormalizer.js.map +1 -0
  115. package/dist/esm/transformers/Formatter.js +463 -0
  116. package/dist/esm/transformers/Formatter.js.map +1 -0
  117. package/dist/esm/transformers/QueryConverter.js +115 -0
  118. package/dist/esm/transformers/QueryConverter.js.map +1 -0
  119. package/dist/esm/transformers/SelectValueCollector.js +245 -0
  120. package/dist/esm/transformers/SelectValueCollector.js.map +1 -0
  121. package/dist/esm/transformers/SelectableColumnCollector.js +318 -0
  122. package/dist/esm/transformers/SelectableColumnCollector.js.map +1 -0
  123. package/dist/esm/transformers/TableColumnResolver.js +2 -0
  124. package/dist/esm/transformers/TableColumnResolver.js.map +1 -0
  125. package/dist/esm/transformers/TableSourceCollector.js +380 -0
  126. package/dist/esm/transformers/TableSourceCollector.js.map +1 -0
  127. package/dist/esm/transformers/UpstreamSelectQueryFinder.js +125 -0
  128. package/dist/esm/transformers/UpstreamSelectQueryFinder.js.map +1 -0
  129. package/dist/esm/types/index.d.ts +14 -0
  130. package/dist/esm/types/models/BinarySelectQuery.d.ts +91 -0
  131. package/dist/esm/types/models/Clause.d.ts +189 -0
  132. package/dist/esm/types/models/KeywordTrie.d.ts +11 -0
  133. package/dist/esm/types/models/Lexeme.d.ts +25 -0
  134. package/dist/esm/types/models/SelectQuery.d.ts +5 -0
  135. package/dist/esm/types/models/SimpleSelectQuery.d.ts +167 -0
  136. package/dist/esm/types/models/SqlComponent.d.ts +18 -0
  137. package/dist/esm/types/models/ValueComponent.d.ts +158 -0
  138. package/dist/esm/types/models/ValuesQuery.d.ts +10 -0
  139. package/dist/esm/types/parsers/CommandExpressionParser.d.ts +15 -0
  140. package/dist/esm/types/parsers/CommonTableParser.d.ts +9 -0
  141. package/dist/esm/types/parsers/ForClauseParser.d.ts +9 -0
  142. package/dist/esm/types/parsers/FromClauseParser.d.ts +9 -0
  143. package/dist/esm/types/parsers/FunctionExpressionParser.d.ts +22 -0
  144. package/dist/esm/types/parsers/GroupByParser.d.ts +10 -0
  145. package/dist/esm/types/parsers/HavingParser.d.ts +9 -0
  146. package/dist/esm/types/parsers/IdentifierParser.d.ts +8 -0
  147. package/dist/esm/types/parsers/JoinClauseParser.d.ts +14 -0
  148. package/dist/esm/types/parsers/KeywordParser.d.ts +17 -0
  149. package/dist/esm/types/parsers/LimitClauseParser.d.ts +9 -0
  150. package/dist/esm/types/parsers/LiteralParser.d.ts +8 -0
  151. package/dist/esm/types/parsers/OrderByClauseParser.d.ts +10 -0
  152. package/dist/esm/types/parsers/OverExpressionParser.d.ts +9 -0
  153. package/dist/esm/types/parsers/ParameterExpressionParser.d.ts +8 -0
  154. package/dist/esm/types/parsers/ParenExpressionParser.d.ts +8 -0
  155. package/dist/esm/types/parsers/PartitionByParser.d.ts +9 -0
  156. package/dist/esm/types/parsers/SelectClauseParser.d.ts +10 -0
  157. package/dist/esm/types/parsers/SelectQueryParser.d.ts +13 -0
  158. package/dist/esm/types/parsers/SourceAliasExpressionParser.d.ts +8 -0
  159. package/dist/esm/types/parsers/SourceExpressionParser.d.ts +8 -0
  160. package/dist/esm/types/parsers/SourceParser.d.ts +13 -0
  161. package/dist/esm/types/parsers/SqlTokenizer.d.ts +64 -0
  162. package/dist/esm/types/parsers/StringSpecifierExpressionParser.d.ts +8 -0
  163. package/dist/esm/types/parsers/UnaryExpressionParser.d.ts +8 -0
  164. package/dist/esm/types/parsers/ValueParser.d.ts +14 -0
  165. package/dist/esm/types/parsers/ValuesQueryParser.d.ts +10 -0
  166. package/dist/esm/types/parsers/WhereClauseParser.d.ts +9 -0
  167. package/dist/esm/types/parsers/WindowClauseParser.d.ts +9 -0
  168. package/dist/esm/types/parsers/WindowExpressionParser.d.ts +12 -0
  169. package/dist/esm/types/parsers/WithClauseParser.d.ts +9 -0
  170. package/dist/esm/types/tokenReaders/BaseTokenReader.d.ts +43 -0
  171. package/dist/esm/types/tokenReaders/CommandTokenReader.d.ts +7 -0
  172. package/dist/esm/types/tokenReaders/FunctionTokenReader.d.ts +11 -0
  173. package/dist/esm/types/tokenReaders/IdentifierTokenReader.d.ts +15 -0
  174. package/dist/esm/types/tokenReaders/LiteralTokenReader.d.ts +23 -0
  175. package/dist/esm/types/tokenReaders/OperatorTokenReader.d.ts +5 -0
  176. package/dist/esm/types/tokenReaders/ParameterTokenReader.d.ts +11 -0
  177. package/dist/esm/types/tokenReaders/StringSpecifierTokenReader.d.ts +8 -0
  178. package/dist/esm/types/tokenReaders/SymbolTokenReader.d.ts +12 -0
  179. package/dist/esm/types/tokenReaders/TokenReaderManager.d.ts +53 -0
  180. package/dist/esm/types/tokenReaders/TypeTokenReader.d.ts +11 -0
  181. package/dist/esm/types/transformers/CTEBuilder.d.ts +52 -0
  182. package/dist/esm/types/transformers/CTECollector.d.ts +82 -0
  183. package/dist/esm/types/transformers/CTEDisabler.d.ts +77 -0
  184. package/dist/esm/types/transformers/CTEInjector.d.ts +40 -0
  185. package/dist/esm/types/transformers/CTENormalizer.d.ts +25 -0
  186. package/dist/esm/types/transformers/Formatter.d.ts +82 -0
  187. package/dist/esm/types/transformers/QueryConverter.d.ts +41 -0
  188. package/dist/esm/types/transformers/SelectValueCollector.d.ts +60 -0
  189. package/dist/esm/types/transformers/SelectableColumnCollector.d.ts +72 -0
  190. package/dist/esm/types/transformers/TableColumnResolver.d.ts +10 -0
  191. package/dist/esm/types/transformers/TableSourceCollector.d.ts +92 -0
  192. package/dist/esm/types/transformers/UpstreamSelectQueryFinder.d.ts +27 -0
  193. package/dist/esm/types/utils/charLookupTable.d.ts +11 -0
  194. package/dist/esm/types/utils/stringUtils.d.ts +43 -0
  195. package/dist/esm/utils/charLookupTable.js +69 -0
  196. package/dist/esm/utils/charLookupTable.js.map +1 -0
  197. package/dist/esm/utils/stringUtils.js +164 -0
  198. package/dist/esm/utils/stringUtils.js.map +1 -0
  199. package/package.json +1 -1
@@ -0,0 +1,101 @@
1
+ import { JoinClause, JoinOnClause, JoinUsingClause } from "../models/Clause";
2
+ import { TokenType } from "../models/Lexeme";
3
+ import { joinkeywordParser } from "../tokenReaders/CommandTokenReader";
4
+ import { SourceExpressionParser } from "./SourceExpressionParser";
5
+ import { ValueParser } from "./ValueParser";
6
+ export class JoinClauseParser {
7
+ static tryParse(lexemes, index) {
8
+ let idx = index;
9
+ const joins = [];
10
+ while (this.isJoinCommand(lexemes, idx)) {
11
+ const joinClause = this.parseJoinClause(lexemes, idx);
12
+ joins.push(joinClause.value);
13
+ idx = joinClause.newIndex;
14
+ }
15
+ if (joins.length > 0) {
16
+ return { value: joins, newIndex: idx };
17
+ }
18
+ return null;
19
+ }
20
+ static isJoinKeyword(value) {
21
+ // Although performance is not ideal,
22
+ // we use keyword token reader to centralize keyword management
23
+ const result = joinkeywordParser.parse(value, 0);
24
+ if (result) {
25
+ return true;
26
+ }
27
+ return false;
28
+ }
29
+ static parseLateral(lexemes, index) {
30
+ let idx = index;
31
+ if (idx < lexemes.length && lexemes[idx].value === 'lateral') {
32
+ // Skip 'lateral' keyword
33
+ idx++;
34
+ return { value: true, newIndex: idx };
35
+ }
36
+ return { value: false, newIndex: idx };
37
+ }
38
+ static isJoinCommand(lexemes, index) {
39
+ if (index >= lexemes.length) {
40
+ return false;
41
+ }
42
+ if (lexemes[index].type === TokenType.Comma || this.isJoinKeyword(lexemes[index].value) === true) {
43
+ return true;
44
+ }
45
+ return false;
46
+ }
47
+ static parseJoinClause(lexemes, index) {
48
+ let idx = index;
49
+ // Get the join type
50
+ const joinType = lexemes[idx].value === "," ? "cross join" : lexemes[idx].value;
51
+ idx++;
52
+ // Check for lateral join
53
+ const lateralResult = this.parseLateral(lexemes, idx);
54
+ const lateral = lateralResult.value;
55
+ idx = lateralResult.newIndex;
56
+ // Parse the source expression to join with
57
+ const sourceResult = SourceExpressionParser.parseFromLexeme(lexemes, idx);
58
+ idx = sourceResult.newIndex;
59
+ if (idx < lexemes.length) {
60
+ let result = this.tryParseJoinOn(lexemes, idx, joinType, sourceResult.value, lateral);
61
+ if (result) {
62
+ return { value: result.value, newIndex: result.newIndex };
63
+ }
64
+ result = this.tryParseJoinUsing(lexemes, idx, joinType, sourceResult.value, lateral);
65
+ if (result) {
66
+ return { value: result.value, newIndex: result.newIndex };
67
+ }
68
+ }
69
+ // If we reach the end of the input, we can treat it as a natural join
70
+ const joinClause = new JoinClause(joinType, sourceResult.value, null, lateral);
71
+ return { value: joinClause, newIndex: idx };
72
+ }
73
+ static tryParseJoinOn(lexemes, index, joinType, source, lateral) {
74
+ let idx = index;
75
+ if (idx < lexemes.length && lexemes[idx].value === 'on') {
76
+ idx++; // Skip 'on' keyword
77
+ // Parse the condition expression
78
+ const condition = ValueParser.parseFromLexeme(lexemes, idx);
79
+ idx = condition.newIndex;
80
+ const joinOn = new JoinOnClause(condition.value);
81
+ const joinClause = new JoinClause(joinType, source, joinOn, lateral);
82
+ return { value: joinClause, newIndex: condition.newIndex };
83
+ }
84
+ return null;
85
+ }
86
+ static tryParseJoinUsing(lexemes, index, joinType, source, lateral) {
87
+ let idx = index;
88
+ if (idx < lexemes.length && lexemes[idx].value === 'using') {
89
+ idx++; // Skip 'using' keyword
90
+ // Parse the columns in parentheses
91
+ const result = ValueParser.parseArgument(TokenType.OpenParen, TokenType.CloseParen, lexemes, idx);
92
+ const usingColumns = result.value;
93
+ idx = result.newIndex;
94
+ const joinUsing = new JoinUsingClause(usingColumns);
95
+ const joinClause = new JoinClause(joinType, source, joinUsing, lateral);
96
+ return { value: joinClause, newIndex: result.newIndex };
97
+ }
98
+ return null;
99
+ }
100
+ }
101
+ //# sourceMappingURL=JoinClauseParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JoinClauseParser.js","sourceRoot":"","sources":["../../../src/parsers/JoinClauseParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { StringUtils } from "../utils/stringUtils";
2
+ export var KeywordMatchResult;
3
+ (function (KeywordMatchResult) {
4
+ KeywordMatchResult[KeywordMatchResult["NotAKeyword"] = 0] = "NotAKeyword";
5
+ KeywordMatchResult[KeywordMatchResult["PartialOnly"] = 1] = "PartialOnly";
6
+ KeywordMatchResult[KeywordMatchResult["PartialOrFinal"] = 2] = "PartialOrFinal";
7
+ KeywordMatchResult[KeywordMatchResult["Final"] = 3] = "Final"; // "Complete match (no longer keywords after this)"
8
+ })(KeywordMatchResult || (KeywordMatchResult = {}));
9
+ export class KeywordParser {
10
+ constructor(trie) {
11
+ this.trie = trie;
12
+ }
13
+ isEndOfInput(input, position, shift = 0) {
14
+ return position + shift >= input.length;
15
+ }
16
+ canParse(input, position, shift = 0) {
17
+ return !this.isEndOfInput(input, position, shift);
18
+ }
19
+ parse(input, position) {
20
+ if (this.isEndOfInput(input, position)) {
21
+ return null;
22
+ }
23
+ // reset trie node
24
+ this.trie.reset();
25
+ const result = StringUtils.tryReadRegularIdentifier(input, position);
26
+ if (result === null) {
27
+ return null;
28
+ }
29
+ let matchResult = this.trie.pushLexeme(result.identifier.toLowerCase());
30
+ if (matchResult === KeywordMatchResult.NotAKeyword) {
31
+ return null;
32
+ }
33
+ if (matchResult === KeywordMatchResult.Final) {
34
+ return {
35
+ keyword: result.identifier,
36
+ newPosition: result.newPosition
37
+ };
38
+ }
39
+ // multi-word keyword
40
+ let lexeme = result.identifier;
41
+ position = StringUtils.readWhiteSpaceAndComment(input, result.newPosition).position;
42
+ // end of input
43
+ if (this.isEndOfInput(input, position)) {
44
+ if (matchResult === KeywordMatchResult.PartialOrFinal) {
45
+ // if the last match was partial or final, it means that the keyword is finished
46
+ return {
47
+ keyword: lexeme,
48
+ newPosition: position
49
+ };
50
+ }
51
+ else {
52
+ return null;
53
+ }
54
+ }
55
+ while (this.canParse(input, position)) {
56
+ const previousMatchResult = matchResult;
57
+ const result = StringUtils.tryReadRegularIdentifier(input, position);
58
+ if (result !== null) {
59
+ matchResult = this.trie.pushLexeme(result.identifier.toLowerCase());
60
+ if (matchResult === KeywordMatchResult.NotAKeyword) {
61
+ if (previousMatchResult === KeywordMatchResult.PartialOrFinal) {
62
+ break;
63
+ }
64
+ else {
65
+ return null;
66
+ }
67
+ }
68
+ lexeme += ' ' + result.identifier;
69
+ position = StringUtils.readWhiteSpaceAndComment(input, result.newPosition).position;
70
+ if (matchResult === KeywordMatchResult.Final) {
71
+ break;
72
+ }
73
+ }
74
+ else if (previousMatchResult === KeywordMatchResult.PartialOrFinal) {
75
+ break;
76
+ }
77
+ else {
78
+ return null;
79
+ }
80
+ }
81
+ return {
82
+ keyword: lexeme,
83
+ newPosition: position
84
+ };
85
+ }
86
+ }
87
+ //# sourceMappingURL=KeywordParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"KeywordParser.js","sourceRoot":"","sources":["../../../src/parsers/KeywordParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { LimitClause as LimitClause } from "../models/Clause";
2
+ import { SqlTokenizer } from "./SqlTokenizer";
3
+ import { ValueParser } from "./ValueParser";
4
+ export class LimitClauseParser {
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 LIMIT 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 !== 'limit') {
21
+ throw new Error(`Syntax error at position ${idx}: Expected 'LIMIT' keyword but found "${lexemes[idx].value}". LIMIT clauses must start with the LIMIT keyword.`);
22
+ }
23
+ idx++;
24
+ if (idx >= lexemes.length) {
25
+ throw new Error(`Syntax error: Unexpected end of input after 'LIMIT' keyword. The LIMIT clause requires a numeric expression.`);
26
+ }
27
+ // Parse LIMIT value
28
+ const limitItem = ValueParser.parseFromLexeme(lexemes, idx);
29
+ idx = limitItem.newIndex;
30
+ let offsetItem = null;
31
+ // Check if there is an OFFSET clause
32
+ if (idx < lexemes.length && lexemes[idx].value === 'offset') {
33
+ idx++;
34
+ if (idx >= lexemes.length) {
35
+ throw new Error(`Syntax error: Unexpected end of input after 'OFFSET' keyword. The OFFSET clause requires a numeric expression.`);
36
+ }
37
+ // Parse OFFSET value
38
+ const offsetValueItem = ValueParser.parseFromLexeme(lexemes, idx);
39
+ offsetItem = offsetValueItem.value;
40
+ idx = offsetValueItem.newIndex;
41
+ }
42
+ const clause = new LimitClause(limitItem.value, offsetItem);
43
+ return { value: clause, newIndex: idx };
44
+ }
45
+ }
46
+ //# sourceMappingURL=LimitClauseParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LimitClauseParser.js","sourceRoot":"","sources":["../../../src/parsers/LimitClauseParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,OAAO,iBAAiB;IAC1B,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,iEAAiE,CAAC,CAAC;QACxL,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,OAAO,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,yCAAyC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,qDAAqD,CAAC,CAAC;QACrK,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,8GAA8G,CAAC,CAAC;QACpI,CAAC;QAED,oBAAoB;QACpB,MAAM,SAAS,GAAG,WAAW,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC5D,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC;QAEzB,IAAI,UAAU,GAAG,IAAI,CAAC;QAEtB,qCAAqC;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC1D,GAAG,EAAE,CAAC;YAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,gHAAgH,CAAC,CAAC;YACtI,CAAC;YAED,qBAAqB;YACrB,MAAM,eAAe,GAAG,WAAW,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAClE,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC;YACnC,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC;QACnC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAE5D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IAC5C,CAAC;CACJ"}
@@ -0,0 +1,34 @@
1
+ import { LiteralValue, RawString } from "../models/ValueComponent";
2
+ import { literalKeywordParser } from "../tokenReaders/LiteralTokenReader";
3
+ export class LiteralParser {
4
+ static parseFromLexeme(lexemes, index) {
5
+ // Process literal value
6
+ let idx = index;
7
+ const valueText = lexemes[idx].value;
8
+ let parsedValue;
9
+ const lex = literalKeywordParser.parse(valueText.toLowerCase(), 0);
10
+ if (lex) {
11
+ const value = new RawString(lex.keyword);
12
+ idx++;
13
+ return { value, newIndex: idx };
14
+ }
15
+ // Check if it is a number
16
+ if (/^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/.test(valueText)) {
17
+ parsedValue = Number(valueText);
18
+ }
19
+ // Otherwise, treat it as a string
20
+ else {
21
+ // Remove single quotes if enclosed
22
+ if (valueText.startsWith("'") && valueText.endsWith("'")) {
23
+ parsedValue = valueText.slice(1, -1);
24
+ }
25
+ else {
26
+ parsedValue = valueText;
27
+ }
28
+ }
29
+ idx++;
30
+ const value = new LiteralValue(parsedValue);
31
+ return { value, newIndex: idx };
32
+ }
33
+ }
34
+ //# sourceMappingURL=LiteralParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiteralParser.js","sourceRoot":"","sources":["../../../src/parsers/LiteralParser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAkB,MAAM,0BAA0B,CAAC;AACnF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,MAAM,OAAO,aAAa;IACf,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,wBAAwB;QACxB,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;QACrC,IAAI,WAA6C,CAAC;QAElD,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;QACnE,IAAI,GAAG,EAAE,CAAC;YACN,MAAM,KAAK,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACzC,GAAG,EAAE,CAAA;YACL,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACpC,CAAC;QAED,0BAA0B;QAC1B,IAAI,mCAAmC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACtD,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QACD,kCAAkC;aAC7B,CAAC;YACF,mCAAmC;YACnC,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvD,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACzC,CAAC;iBAAM,CAAC;gBACJ,WAAW,GAAG,SAAS,CAAC;YAC5B,CAAC;QACL,CAAC;QACD,GAAG,EAAE,CAAA;QACL,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;QAC5C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IACpC,CAAC;CACJ"}
@@ -0,0 +1,73 @@
1
+ import { NullsSortDirection, OrderByClause, OrderByItem, SortDirection } from "../models/Clause";
2
+ import { TokenType } from "../models/Lexeme";
3
+ import { SqlTokenizer } from "./SqlTokenizer";
4
+ import { ValueParser } from "./ValueParser";
5
+ export class OrderByClauseParser {
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 ORDER 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 !== 'order by') {
22
+ throw new Error(`Syntax error at position ${idx}: Expected 'ORDER BY' keyword but found "${lexemes[idx].value}". ORDER BY clauses must start with the ORDER BY keywords.`);
23
+ }
24
+ idx++;
25
+ const items = [];
26
+ const item = this.parseItem(lexemes, idx);
27
+ items.push(item.value);
28
+ idx = item.newIndex;
29
+ while (idx < lexemes.length && lexemes[idx].type === TokenType.Comma) {
30
+ idx++;
31
+ const item = this.parseItem(lexemes, idx);
32
+ items.push(item.value);
33
+ idx = item.newIndex;
34
+ }
35
+ if (items.length === 0) {
36
+ throw new Error(`Syntax error at position ${index}: No ordering expressions found. The ORDER BY clause requires at least one expression to order by.`);
37
+ }
38
+ else {
39
+ const clause = new OrderByClause(items);
40
+ return { value: clause, newIndex: idx };
41
+ }
42
+ }
43
+ static parseItem(lexemes, index) {
44
+ let idx = index;
45
+ const parsedValue = ValueParser.parseFromLexeme(lexemes, idx);
46
+ const value = parsedValue.value;
47
+ idx = parsedValue.newIndex;
48
+ if (idx >= lexemes.length) {
49
+ return { value: value, newIndex: idx };
50
+ }
51
+ // asc, desc
52
+ const sortDirection = idx >= lexemes.length
53
+ ? null
54
+ : lexemes[idx].value === 'asc'
55
+ ? (idx++, SortDirection.Ascending)
56
+ : lexemes[idx].value === 'desc'
57
+ ? (idx++, SortDirection.Descending)
58
+ : null;
59
+ // nulls first, nulls last
60
+ const nullsSortDirection = idx >= lexemes.length
61
+ ? null
62
+ : lexemes[idx].value === 'nulls first'
63
+ ? (idx++, NullsSortDirection.First)
64
+ : lexemes[idx].value === 'nulls last'
65
+ ? (idx++, NullsSortDirection.Last)
66
+ : null;
67
+ if (sortDirection === null && nullsSortDirection === null) {
68
+ return { value: value, newIndex: idx };
69
+ }
70
+ return { value: new OrderByItem(value, sortDirection, nullsSortDirection), newIndex: idx };
71
+ }
72
+ }
73
+ //# sourceMappingURL=OrderByClauseParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrderByClauseParser.js","sourceRoot":"","sources":["../../../src/parsers/OrderByClauseParser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { TokenType } from "../models/Lexeme";
2
+ import { IdentifierString } from "../models/ValueComponent";
3
+ import { SqlTokenizer } from "./SqlTokenizer";
4
+ import { WindowExpressionParser } from "./WindowExpressionParser";
5
+ export class OverExpressionParser {
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 OVER expression is complete but there are additional tokens.`);
14
+ }
15
+ return result.value;
16
+ }
17
+ static parseFromLexeme(lexemes, index) {
18
+ let idx = index;
19
+ if (lexemes[idx].value !== 'over') {
20
+ throw new Error(`Syntax error at position ${idx}: Expected 'OVER' keyword but found "${lexemes[idx].value}". OVER expressions must start with the OVER keyword.`);
21
+ }
22
+ idx++;
23
+ if (idx >= lexemes.length) {
24
+ throw new Error(`Syntax error: Unexpected end of input after 'OVER' keyword. Expected either a window name or an opening parenthesis '('.`);
25
+ }
26
+ if (lexemes[idx].type === TokenType.Identifier) {
27
+ // named window frame
28
+ const name = lexemes[idx].value;
29
+ idx++;
30
+ return { value: new IdentifierString(name), newIndex: idx };
31
+ }
32
+ if (lexemes[idx].type === TokenType.OpenParen) {
33
+ // Delegate processing to WindowFrameExpressionParser
34
+ const result = WindowExpressionParser.parseFromLexeme(lexemes, idx);
35
+ return result;
36
+ }
37
+ throw new Error(`Syntax error at position ${idx}: Expected a window name or opening parenthesis '(' after OVER keyword, but found "${lexemes[idx].value}".`);
38
+ }
39
+ }
40
+ //# sourceMappingURL=OverExpressionParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OverExpressionParser.js","sourceRoot":"","sources":["../../../src/parsers/OverExpressionParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAkB,MAAM,0BAA0B,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,OAAO,oBAAoB;IACtB,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,oEAAoE,CAAC,CAAC;QAC3L,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACxB,CAAC;IAEM,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,uDAAuD,CAAC,CAAC;QACtK,CAAC;QACD,GAAG,EAAE,CAAC;QAEN,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,0HAA0H,CAAC,CAAC;QAChJ,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,EAAE,CAAC;YAC7C,qBAAqB;YACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YAChC,GAAG,EAAE,CAAC;YACN,OAAO,EAAE,KAAK,EAAE,IAAI,gBAAgB,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAChE,CAAC;QAED,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,SAAS,EAAE,CAAC;YAC5C,qDAAqD;YACrD,MAAM,MAAM,GAAG,sBAAsB,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACpE,OAAO,MAAM,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,sFAAsF,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACjK,CAAC;CACJ"}
@@ -0,0 +1,11 @@
1
+ import { ParameterExpression } from "../models/ValueComponent";
2
+ export class ParameterExpressionParser {
3
+ static parseFromLexeme(lexemes, index) {
4
+ let idx = index;
5
+ // Exclude the parameter symbol (first character)
6
+ const value = new ParameterExpression(lexemes[idx].value.slice(1));
7
+ idx++;
8
+ return { value, newIndex: idx };
9
+ }
10
+ }
11
+ //# sourceMappingURL=ParameterExpressionParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParameterExpressionParser.js","sourceRoot":"","sources":["../../../src/parsers/ParameterExpressionParser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAkB,MAAM,0BAA0B,CAAC;AAE/E,MAAM,OAAO,yBAAyB;IAC3B,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,IAAI,GAAG,GAAG,KAAK,CAAC;QAChB,iDAAiD;QACjD,MAAM,KAAK,GAAG,IAAI,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,GAAG,EAAE,CAAC;QACN,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;IACpC,CAAC;CACJ"}
@@ -0,0 +1,29 @@
1
+ import { TokenType } from "../models/Lexeme";
2
+ import { InlineQuery, ParenExpression } from "../models/ValueComponent";
3
+ import { SelectQueryParser } from "./SelectQueryParser";
4
+ import { ValueParser } from "./ValueParser";
5
+ export class ParenExpressionParser {
6
+ static parseFromLexeme(lexemes, index) {
7
+ let idx = index;
8
+ // check inline query
9
+ if (idx + 1 < lexemes.length && lexemes[idx].type === TokenType.OpenParen && (lexemes[idx + 1].value === "select" || lexemes[idx + 1].value === "values" || lexemes[idx + 1].value === "with")) {
10
+ idx += 1; // Skip the '(' token
11
+ const result = SelectQueryParser.parseFromLexeme(lexemes, idx);
12
+ idx = result.newIndex;
13
+ // Check for closing parenthesis
14
+ if (idx >= lexemes.length || lexemes[idx].type !== TokenType.CloseParen) {
15
+ throw new Error(`Expected ')' at index ${idx}, but found ${lexemes[idx].value}`);
16
+ }
17
+ idx++; // Skip the ')' token
18
+ const value = new InlineQuery(result.value);
19
+ return { value, newIndex: idx };
20
+ }
21
+ else {
22
+ const result = ValueParser.parseArgument(TokenType.OpenParen, TokenType.CloseParen, lexemes, index);
23
+ idx = result.newIndex;
24
+ const value = new ParenExpression(result.value);
25
+ return { value, newIndex: idx };
26
+ }
27
+ }
28
+ }
29
+ //# sourceMappingURL=ParenExpressionParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParenExpressionParser.js","sourceRoot":"","sources":["../../../src/parsers/ParenExpressionParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAkB,MAAM,0BAA0B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,OAAO,qBAAqB;IACvB,MAAM,CAAC,eAAe,CAAC,OAAiB,EAAE,KAAa;QAC1D,IAAI,GAAG,GAAG,KAAK,CAAC;QAEhB,qBAAqB;QACrB,IAAI,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,SAAS,IAAI,CACzE,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAClH,EAAE,CAAC;YACA,GAAG,IAAI,CAAC,CAAC,CAAC,qBAAqB;YAC/B,MAAM,MAAM,GAAG,iBAAiB,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC/D,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEtB,gCAAgC;YAChC,IAAI,GAAG,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,EAAE,CAAC;gBACtE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,eAAe,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACrF,CAAC;YACD,GAAG,EAAE,CAAC,CAAC,qBAAqB;YAE5B,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACpC,CAAC;aAAM,CAAC;YACJ,MAAM,MAAM,GAAG,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YACpG,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEtB,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QACpC,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,49 @@
1
+ import { PartitionByClause } from "../models/Clause";
2
+ import { TokenType } from "../models/Lexeme";
3
+ import { ValueList } from "../models/ValueComponent";
4
+ import { SqlTokenizer } from "./SqlTokenizer";
5
+ import { ValueParser } from "./ValueParser";
6
+ export class PartitionByParser {
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 PARTITION BY clause 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
+ if (lexemes[idx].value !== 'partition by') {
23
+ throw new Error(`Syntax error at position ${idx}: Expected 'PARTITION BY' keyword but found "${lexemes[idx].value}". PARTITION BY clauses must start with the PARTITION BY keywords.`);
24
+ }
25
+ idx++;
26
+ const items = [];
27
+ const item = ValueParser.parseFromLexeme(lexemes, idx);
28
+ items.push(item.value);
29
+ idx = item.newIndex;
30
+ while (idx < lexemes.length && lexemes[idx].type === TokenType.Comma) {
31
+ idx++;
32
+ const item = ValueParser.parseFromLexeme(lexemes, idx);
33
+ items.push(item.value);
34
+ idx = item.newIndex;
35
+ }
36
+ if (items.length === 0) {
37
+ throw new Error(`Syntax error at position ${index}: No partition expressions found. The PARTITION BY clause requires at least one expression to partition by.`);
38
+ }
39
+ else if (items.length === 1) {
40
+ const clause = new PartitionByClause(items[0]);
41
+ return { value: clause, newIndex: idx };
42
+ }
43
+ else {
44
+ const clause = new PartitionByClause(new ValueList(items));
45
+ return { value: clause, newIndex: idx };
46
+ }
47
+ }
48
+ }
49
+ //# sourceMappingURL=PartitionByParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PartitionByParser.js","sourceRoot":"","sources":["../../../src/parsers/PartitionByParser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAkB,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,OAAO,iBAAiB;IAC1B,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,wEAAwE,CAAC,CAAC;QAC/L,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;QAChB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,cAAc,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,4BAA4B,GAAG,gDAAgD,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,oEAAoE,CAAC,CAAC;QAC3L,CAAC;QACD,GAAG,EAAE,CAAC;QACN,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,WAAW,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACpB,OAAO,GAAG,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,KAAK,EAAE,CAAC;YACnE,GAAG,EAAE,CAAC;YACN,MAAM,IAAI,GAAG,WAAW,CAAC,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACvD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxB,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,6GAA6G,CAAC,CAAC;QACpK,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC5C,CAAC;aAAM,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC;QAC5C,CAAC;IACL,CAAC;CACJ"}
@@ -0,0 +1,80 @@
1
+ import { Distinct, DistinctOn, SelectClause, SelectItem } from "../models/Clause";
2
+ import { TokenType } from "../models/Lexeme";
3
+ import { SqlTokenizer } from "./SqlTokenizer";
4
+ import { ValueParser } from "./ValueParser";
5
+ export class SelectClauseParser {
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 SELECT 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
+ let distinct = null;
22
+ if (lexemes[idx].value !== 'select') {
23
+ throw new Error(`Syntax error at position ${idx}: Expected 'SELECT' keyword but found "${lexemes[idx].value}". SELECT clauses must start with the SELECT keyword.`);
24
+ }
25
+ idx++;
26
+ if (idx < lexemes.length && lexemes[idx].value === 'distinct') {
27
+ idx++;
28
+ distinct = new Distinct();
29
+ }
30
+ else if (idx < lexemes.length && lexemes[idx].value === 'distinct on') {
31
+ idx++;
32
+ const argument = ValueParser.parseArgument(TokenType.OpenParen, TokenType.CloseParen, lexemes, idx);
33
+ distinct = new DistinctOn(argument.value);
34
+ idx = argument.newIndex;
35
+ }
36
+ const items = [];
37
+ const item = this.parseItem(lexemes, idx);
38
+ items.push(item.value);
39
+ idx = item.newIndex;
40
+ while (idx < lexemes.length && lexemes[idx].type === TokenType.Comma) {
41
+ idx++;
42
+ const item = this.parseItem(lexemes, idx);
43
+ items.push(item.value);
44
+ idx = item.newIndex;
45
+ }
46
+ if (items.length === 0) {
47
+ throw new Error(`Syntax error at position ${index}: No select items found. The SELECT clause requires at least one expression to select.`);
48
+ }
49
+ else {
50
+ const clause = new SelectClause(items, distinct);
51
+ return { value: clause, newIndex: idx };
52
+ }
53
+ }
54
+ static parseItem(lexemes, index) {
55
+ let idx = index;
56
+ const parsedValue = ValueParser.parseFromLexeme(lexemes, idx);
57
+ const value = parsedValue.value;
58
+ idx = parsedValue.newIndex;
59
+ if (idx < lexemes.length && lexemes[idx].value === 'as') {
60
+ // Skip 'AS' keyword
61
+ idx++;
62
+ }
63
+ if (idx < lexemes.length && lexemes[idx].type === TokenType.Identifier) {
64
+ const alias = lexemes[idx].value;
65
+ idx++;
66
+ return {
67
+ value: new SelectItem(value, alias),
68
+ newIndex: idx,
69
+ };
70
+ }
71
+ else {
72
+ // alias nameless
73
+ return {
74
+ value,
75
+ newIndex: idx,
76
+ };
77
+ }
78
+ }
79
+ }
80
+ //# sourceMappingURL=SelectClauseParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SelectClauseParser.js","sourceRoot":"","sources":["../../../src/parsers/SelectClauseParser.ts"],"names":[],"mappings":"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"}