rawsql-ts 0.1.0-beta.11 → 0.1.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +78 -18
  2. package/dist/esm/index.js +17 -0
  3. package/dist/esm/index.js.map +1 -0
  4. package/dist/esm/models/BinarySelectQuery.js +137 -0
  5. package/dist/esm/models/BinarySelectQuery.js.map +1 -0
  6. package/dist/esm/models/Clause.js +289 -0
  7. package/dist/esm/models/Clause.js.map +1 -0
  8. package/dist/esm/models/KeywordTrie.js +48 -0
  9. package/dist/esm/models/KeywordTrie.js.map +1 -0
  10. package/dist/esm/models/Lexeme.js +18 -0
  11. package/dist/esm/models/Lexeme.js.map +1 -0
  12. package/dist/esm/models/SelectQuery.js +5 -0
  13. package/dist/esm/models/SelectQuery.js.map +1 -0
  14. package/dist/esm/models/SimpleSelectQuery.js +288 -0
  15. package/dist/esm/models/SimpleSelectQuery.js.map +1 -0
  16. package/dist/esm/models/SqlComponent.js +22 -0
  17. package/dist/esm/models/SqlComponent.js.map +1 -0
  18. package/dist/esm/models/ValueComponent.js +223 -0
  19. package/dist/esm/models/ValueComponent.js.map +1 -0
  20. package/dist/esm/models/ValuesQuery.js +12 -0
  21. package/dist/esm/models/ValuesQuery.js.map +1 -0
  22. package/dist/esm/parsers/CommandExpressionParser.js +120 -0
  23. package/dist/esm/parsers/CommandExpressionParser.js.map +1 -0
  24. package/dist/esm/parsers/CommonTableParser.js +58 -0
  25. package/dist/esm/parsers/CommonTableParser.js.map +1 -0
  26. package/dist/esm/parsers/ForClauseParser.js +54 -0
  27. package/dist/esm/parsers/ForClauseParser.js.map +1 -0
  28. package/dist/esm/parsers/FromClauseParser.js +43 -0
  29. package/dist/esm/parsers/FromClauseParser.js.map +1 -0
  30. package/dist/esm/parsers/FunctionExpressionParser.js +174 -0
  31. package/dist/esm/parsers/FunctionExpressionParser.js.map +1 -0
  32. package/dist/esm/parsers/GroupByParser.js +54 -0
  33. package/dist/esm/parsers/GroupByParser.js.map +1 -0
  34. package/dist/esm/parsers/HavingParser.js +32 -0
  35. package/dist/esm/parsers/HavingParser.js.map +1 -0
  36. package/dist/esm/parsers/IdentifierParser.js +35 -0
  37. package/dist/esm/parsers/IdentifierParser.js.map +1 -0
  38. package/dist/esm/parsers/JoinClauseParser.js +101 -0
  39. package/dist/esm/parsers/JoinClauseParser.js.map +1 -0
  40. package/dist/esm/parsers/KeywordParser.js +87 -0
  41. package/dist/esm/parsers/KeywordParser.js.map +1 -0
  42. package/dist/esm/parsers/LimitClauseParser.js +46 -0
  43. package/dist/esm/parsers/LimitClauseParser.js.map +1 -0
  44. package/dist/esm/parsers/LiteralParser.js +34 -0
  45. package/dist/esm/parsers/LiteralParser.js.map +1 -0
  46. package/dist/esm/parsers/OrderByClauseParser.js +73 -0
  47. package/dist/esm/parsers/OrderByClauseParser.js.map +1 -0
  48. package/dist/esm/parsers/OverExpressionParser.js +40 -0
  49. package/dist/esm/parsers/OverExpressionParser.js.map +1 -0
  50. package/dist/esm/parsers/ParameterExpressionParser.js +11 -0
  51. package/dist/esm/parsers/ParameterExpressionParser.js.map +1 -0
  52. package/dist/esm/parsers/ParenExpressionParser.js +29 -0
  53. package/dist/esm/parsers/ParenExpressionParser.js.map +1 -0
  54. package/dist/esm/parsers/PartitionByParser.js +49 -0
  55. package/dist/esm/parsers/PartitionByParser.js.map +1 -0
  56. package/dist/esm/parsers/SelectClauseParser.js +80 -0
  57. package/dist/esm/parsers/SelectClauseParser.js.map +1 -0
  58. package/dist/esm/parsers/SelectQueryParser.js +149 -0
  59. package/dist/esm/parsers/SelectQueryParser.js.map +1 -0
  60. package/dist/esm/parsers/SourceAliasExpressionParser.js +45 -0
  61. package/dist/esm/parsers/SourceAliasExpressionParser.js.map +1 -0
  62. package/dist/esm/parsers/SourceExpressionParser.js +31 -0
  63. package/dist/esm/parsers/SourceExpressionParser.js.map +1 -0
  64. package/dist/esm/parsers/SourceParser.js +115 -0
  65. package/dist/esm/parsers/SourceParser.js.map +1 -0
  66. package/dist/esm/parsers/SqlTokenizer.js +170 -0
  67. package/dist/esm/parsers/SqlTokenizer.js.map +1 -0
  68. package/dist/esm/parsers/StringSpecifierExpressionParser.js +18 -0
  69. package/dist/esm/parsers/StringSpecifierExpressionParser.js.map +1 -0
  70. package/dist/esm/parsers/UnaryExpressionParser.js +26 -0
  71. package/dist/esm/parsers/UnaryExpressionParser.js.map +1 -0
  72. package/dist/esm/parsers/ValueParser.js +132 -0
  73. package/dist/esm/parsers/ValueParser.js.map +1 -0
  74. package/dist/esm/parsers/ValuesQueryParser.js +82 -0
  75. package/dist/esm/parsers/ValuesQueryParser.js.map +1 -0
  76. package/dist/esm/parsers/WhereClauseParser.js +32 -0
  77. package/dist/esm/parsers/WhereClauseParser.js.map +1 -0
  78. package/dist/esm/parsers/WindowClauseParser.js +41 -0
  79. package/dist/esm/parsers/WindowClauseParser.js.map +1 -0
  80. package/dist/esm/parsers/WindowExpressionParser.js +159 -0
  81. package/dist/esm/parsers/WindowExpressionParser.js.map +1 -0
  82. package/dist/esm/parsers/WithClauseParser.js +53 -0
  83. package/dist/esm/parsers/WithClauseParser.js.map +1 -0
  84. package/dist/esm/tokenReaders/BaseTokenReader.js +78 -0
  85. package/dist/esm/tokenReaders/BaseTokenReader.js.map +1 -0
  86. package/dist/esm/tokenReaders/CommandTokenReader.js +141 -0
  87. package/dist/esm/tokenReaders/CommandTokenReader.js.map +1 -0
  88. package/dist/esm/tokenReaders/FunctionTokenReader.js +41 -0
  89. package/dist/esm/tokenReaders/FunctionTokenReader.js.map +1 -0
  90. package/dist/esm/tokenReaders/IdentifierTokenReader.js +66 -0
  91. package/dist/esm/tokenReaders/IdentifierTokenReader.js.map +1 -0
  92. package/dist/esm/tokenReaders/LiteralTokenReader.js +185 -0
  93. package/dist/esm/tokenReaders/LiteralTokenReader.js.map +1 -0
  94. package/dist/esm/tokenReaders/OperatorTokenReader.js +94 -0
  95. package/dist/esm/tokenReaders/OperatorTokenReader.js.map +1 -0
  96. package/dist/esm/tokenReaders/ParameterTokenReader.js +40 -0
  97. package/dist/esm/tokenReaders/ParameterTokenReader.js.map +1 -0
  98. package/dist/esm/tokenReaders/StringSpecifierTokenReader.js +27 -0
  99. package/dist/esm/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
  100. package/dist/esm/tokenReaders/SymbolTokenReader.js +31 -0
  101. package/dist/esm/tokenReaders/SymbolTokenReader.js.map +1 -0
  102. package/dist/esm/tokenReaders/TokenReaderManager.js +106 -0
  103. package/dist/esm/tokenReaders/TokenReaderManager.js.map +1 -0
  104. package/dist/esm/tokenReaders/TypeTokenReader.js +55 -0
  105. package/dist/esm/tokenReaders/TypeTokenReader.js.map +1 -0
  106. package/dist/esm/transformers/CTEBuilder.js +184 -0
  107. package/dist/esm/transformers/CTEBuilder.js.map +1 -0
  108. package/dist/esm/transformers/CTECollector.js +380 -0
  109. package/dist/esm/transformers/CTECollector.js.map +1 -0
  110. package/dist/esm/transformers/CTEDisabler.js +321 -0
  111. package/dist/esm/transformers/CTEDisabler.js.map +1 -0
  112. package/dist/esm/transformers/CTEInjector.js +79 -0
  113. package/dist/esm/transformers/CTEInjector.js.map +1 -0
  114. package/dist/esm/transformers/CTENormalizer.js +42 -0
  115. package/dist/esm/transformers/CTENormalizer.js.map +1 -0
  116. package/dist/esm/transformers/Formatter.js +463 -0
  117. package/dist/esm/transformers/Formatter.js.map +1 -0
  118. package/dist/esm/transformers/QueryConverter.js +115 -0
  119. package/dist/esm/transformers/QueryConverter.js.map +1 -0
  120. package/dist/esm/transformers/SelectValueCollector.js +245 -0
  121. package/dist/esm/transformers/SelectValueCollector.js.map +1 -0
  122. package/dist/esm/transformers/SelectableColumnCollector.js +304 -0
  123. package/dist/esm/transformers/SelectableColumnCollector.js.map +1 -0
  124. package/dist/esm/transformers/TableColumnResolver.js +2 -0
  125. package/dist/esm/transformers/TableColumnResolver.js.map +1 -0
  126. package/dist/esm/transformers/TableSourceCollector.js +380 -0
  127. package/dist/esm/transformers/TableSourceCollector.js.map +1 -0
  128. package/dist/esm/transformers/UpstreamSelectQueryFinder.js +125 -0
  129. package/dist/esm/transformers/UpstreamSelectQueryFinder.js.map +1 -0
  130. package/dist/esm/types/index.d.ts +14 -0
  131. package/dist/esm/types/models/BinarySelectQuery.d.ts +91 -0
  132. package/dist/esm/types/models/Clause.d.ts +189 -0
  133. package/dist/esm/types/models/KeywordTrie.d.ts +11 -0
  134. package/dist/esm/types/models/Lexeme.d.ts +25 -0
  135. package/dist/esm/types/models/SelectQuery.d.ts +5 -0
  136. package/dist/esm/types/models/SimpleSelectQuery.d.ts +167 -0
  137. package/dist/esm/types/models/SqlComponent.d.ts +18 -0
  138. package/dist/esm/types/models/ValueComponent.d.ts +158 -0
  139. package/dist/esm/types/models/ValuesQuery.d.ts +10 -0
  140. package/dist/esm/types/parsers/CommandExpressionParser.d.ts +15 -0
  141. package/dist/esm/types/parsers/CommonTableParser.d.ts +9 -0
  142. package/dist/esm/types/parsers/ForClauseParser.d.ts +9 -0
  143. package/dist/esm/types/parsers/FromClauseParser.d.ts +9 -0
  144. package/dist/esm/types/parsers/FunctionExpressionParser.d.ts +22 -0
  145. package/dist/esm/types/parsers/GroupByParser.d.ts +10 -0
  146. package/dist/esm/types/parsers/HavingParser.d.ts +9 -0
  147. package/dist/esm/types/parsers/IdentifierParser.d.ts +8 -0
  148. package/dist/esm/types/parsers/JoinClauseParser.d.ts +14 -0
  149. package/dist/esm/types/parsers/KeywordParser.d.ts +17 -0
  150. package/dist/esm/types/parsers/LimitClauseParser.d.ts +9 -0
  151. package/dist/esm/types/parsers/LiteralParser.d.ts +8 -0
  152. package/dist/esm/types/parsers/OrderByClauseParser.d.ts +10 -0
  153. package/dist/esm/types/parsers/OverExpressionParser.d.ts +9 -0
  154. package/dist/esm/types/parsers/ParameterExpressionParser.d.ts +8 -0
  155. package/dist/esm/types/parsers/ParenExpressionParser.d.ts +8 -0
  156. package/dist/esm/types/parsers/PartitionByParser.d.ts +9 -0
  157. package/dist/esm/types/parsers/SelectClauseParser.d.ts +10 -0
  158. package/dist/esm/types/parsers/SelectQueryParser.d.ts +13 -0
  159. package/dist/esm/types/parsers/SourceAliasExpressionParser.d.ts +8 -0
  160. package/dist/esm/types/parsers/SourceExpressionParser.d.ts +8 -0
  161. package/dist/esm/types/parsers/SourceParser.d.ts +13 -0
  162. package/dist/esm/types/parsers/SqlTokenizer.d.ts +64 -0
  163. package/dist/esm/types/parsers/StringSpecifierExpressionParser.d.ts +8 -0
  164. package/dist/esm/types/parsers/UnaryExpressionParser.d.ts +8 -0
  165. package/dist/esm/types/parsers/ValueParser.d.ts +14 -0
  166. package/dist/esm/types/parsers/ValuesQueryParser.d.ts +10 -0
  167. package/dist/esm/types/parsers/WhereClauseParser.d.ts +9 -0
  168. package/dist/esm/types/parsers/WindowClauseParser.d.ts +9 -0
  169. package/dist/esm/types/parsers/WindowExpressionParser.d.ts +12 -0
  170. package/dist/esm/types/parsers/WithClauseParser.d.ts +9 -0
  171. package/dist/esm/types/tokenReaders/BaseTokenReader.d.ts +43 -0
  172. package/dist/esm/types/tokenReaders/CommandTokenReader.d.ts +7 -0
  173. package/dist/esm/types/tokenReaders/FunctionTokenReader.d.ts +11 -0
  174. package/dist/esm/types/tokenReaders/IdentifierTokenReader.d.ts +15 -0
  175. package/dist/esm/types/tokenReaders/LiteralTokenReader.d.ts +23 -0
  176. package/dist/esm/types/tokenReaders/OperatorTokenReader.d.ts +5 -0
  177. package/dist/esm/types/tokenReaders/ParameterTokenReader.d.ts +11 -0
  178. package/dist/esm/types/tokenReaders/StringSpecifierTokenReader.d.ts +8 -0
  179. package/dist/esm/types/tokenReaders/SymbolTokenReader.d.ts +12 -0
  180. package/dist/esm/types/tokenReaders/TokenReaderManager.d.ts +53 -0
  181. package/dist/esm/types/tokenReaders/TypeTokenReader.d.ts +11 -0
  182. package/dist/esm/types/transformers/CTEBuilder.d.ts +52 -0
  183. package/dist/esm/types/transformers/CTECollector.d.ts +81 -0
  184. package/dist/esm/types/transformers/CTEDisabler.d.ts +77 -0
  185. package/dist/esm/types/transformers/CTEInjector.d.ts +40 -0
  186. package/dist/esm/types/transformers/CTENormalizer.d.ts +25 -0
  187. package/dist/esm/types/transformers/Formatter.d.ts +82 -0
  188. package/dist/esm/types/transformers/QueryConverter.d.ts +41 -0
  189. package/dist/esm/types/transformers/SelectValueCollector.d.ts +60 -0
  190. package/dist/esm/types/transformers/SelectableColumnCollector.d.ts +70 -0
  191. package/dist/esm/types/transformers/TableColumnResolver.d.ts +10 -0
  192. package/dist/esm/types/transformers/TableSourceCollector.d.ts +92 -0
  193. package/dist/esm/types/transformers/UpstreamSelectQueryFinder.d.ts +27 -0
  194. package/dist/esm/types/utils/charLookupTable.d.ts +11 -0
  195. package/dist/esm/types/utils/stringUtils.d.ts +43 -0
  196. package/dist/esm/utils/charLookupTable.js +69 -0
  197. package/dist/esm/utils/charLookupTable.js.map +1 -0
  198. package/dist/esm/utils/stringUtils.js +164 -0
  199. package/dist/esm/utils/stringUtils.js.map +1 -0
  200. package/package.json +4 -1
@@ -0,0 +1,31 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ /**
4
+ * Reads SQL symbol tokens (., ,, (, ))
5
+ */
6
+ export class SpecialSymbolTokenReader extends BaseTokenReader {
7
+ /**
8
+ * Try to read a symbol token
9
+ */
10
+ tryRead(previous) {
11
+ if (this.isEndOfInput()) {
12
+ return null;
13
+ }
14
+ const char = this.input[this.position];
15
+ // symbol tokens
16
+ if (char in SpecialSymbolTokenReader.SPECIAL_SYMBOL_TOKENS) {
17
+ this.position++;
18
+ return this.createLexeme(SpecialSymbolTokenReader.SPECIAL_SYMBOL_TOKENS[char], char);
19
+ }
20
+ return null;
21
+ }
22
+ }
23
+ SpecialSymbolTokenReader.SPECIAL_SYMBOL_TOKENS = {
24
+ '.': TokenType.Dot,
25
+ ',': TokenType.Comma,
26
+ '(': TokenType.OpenParen,
27
+ ')': TokenType.CloseParen,
28
+ '[': TokenType.OpenBracket,
29
+ ']': TokenType.CloseBracket,
30
+ };
31
+ //# sourceMappingURL=SymbolTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SymbolTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/SymbolTokenReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAErD;;GAEG;AACH,MAAM,OAAO,wBAAyB,SAAQ,eAAe;IAUzD;;OAEG;IACI,OAAO,CAAC,QAAuB;QAClC,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAEvC,gBAAgB;QAChB,IAAI,IAAI,IAAI,wBAAwB,CAAC,qBAAqB,EAAE,CAAC;YACzD,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO,IAAI,CAAC,YAAY,CACpB,wBAAwB,CAAC,qBAAqB,CAAC,IAAI,CAAC,EACpD,IAAI,CACP,CAAC;QACN,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;;AA5BuB,8CAAqB,GAA8B;IACvE,GAAG,EAAE,SAAS,CAAC,GAAG;IAClB,GAAG,EAAE,SAAS,CAAC,KAAK;IACpB,GAAG,EAAE,SAAS,CAAC,SAAS;IACxB,GAAG,EAAE,SAAS,CAAC,UAAU;IACzB,GAAG,EAAE,SAAS,CAAC,WAAW;IAC1B,GAAG,EAAE,SAAS,CAAC,YAAY;CAC9B,CAAC"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Manages and coordinates multiple token readers
3
+ */
4
+ export class TokenReaderManager {
5
+ constructor(input, position = 0) {
6
+ this.cacheHits = 0;
7
+ this.cacheMisses = 0;
8
+ this.input = input;
9
+ this.position = position;
10
+ this.readers = [];
11
+ this.tokenCache = new Map();
12
+ }
13
+ /**
14
+ * Register a token reader
15
+ * @param reader The reader to register
16
+ * @returns This manager instance for chaining
17
+ */
18
+ register(reader) {
19
+ this.readers.push(reader);
20
+ return this;
21
+ }
22
+ /**
23
+ * Register multiple token readers
24
+ * @param readers The readers to register
25
+ * @returns This manager instance for chaining
26
+ */
27
+ registerAll(readers) {
28
+ readers.forEach(reader => this.register(reader));
29
+ return this;
30
+ }
31
+ /**
32
+ * Update the position for all readers
33
+ */
34
+ setPosition(position) {
35
+ this.position = position;
36
+ for (const reader of this.readers) {
37
+ reader.setPosition(position);
38
+ }
39
+ }
40
+ /**
41
+ * Try to read a token using all registered readers
42
+ * @param position The position to read from
43
+ * @param previous The previous token, if any
44
+ * @returns The lexeme if a reader could read it, null otherwise
45
+ */
46
+ tryRead(position, previous) {
47
+ // Check cache - using position as the key
48
+ if (this.tokenCache.has(position)) {
49
+ // Cache hit
50
+ this.cacheHits++;
51
+ const lexeme = this.tokenCache.get(position) || null;
52
+ return lexeme;
53
+ }
54
+ // Cache miss - create new entry
55
+ this.cacheMisses++;
56
+ this.setPosition(position);
57
+ // Try to read with each reader
58
+ let lexeme = null;
59
+ for (const reader of this.readers) {
60
+ lexeme = reader.tryRead(previous);
61
+ if (lexeme) {
62
+ this.position = reader.getPosition();
63
+ break;
64
+ }
65
+ }
66
+ // Update all readers' positions
67
+ for (const reader of this.readers) {
68
+ reader.setPosition(this.position);
69
+ }
70
+ // Save to cache (even if null)
71
+ this.tokenCache.set(position, lexeme);
72
+ return lexeme;
73
+ }
74
+ /**
75
+ * Get the maximum position among all readers
76
+ */
77
+ getMaxPosition() {
78
+ let maxPosition = this.position;
79
+ for (const reader of this.readers) {
80
+ const position = reader.getPosition();
81
+ if (position > maxPosition) {
82
+ maxPosition = position;
83
+ }
84
+ }
85
+ return maxPosition;
86
+ }
87
+ /**
88
+ * Get the input string
89
+ */
90
+ getInput() {
91
+ return this.input;
92
+ }
93
+ /**
94
+ * Get cache statistics
95
+ */
96
+ getCacheStats() {
97
+ const total = this.cacheHits + this.cacheMisses;
98
+ const ratio = total > 0 ? this.cacheHits / total : 0;
99
+ return {
100
+ hits: this.cacheHits,
101
+ misses: this.cacheMisses,
102
+ ratio: ratio
103
+ };
104
+ }
105
+ }
106
+ //# sourceMappingURL=TokenReaderManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenReaderManager.js","sourceRoot":"","sources":["../../../src/tokenReaders/TokenReaderManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { BaseTokenReader } from './BaseTokenReader';
2
+ import { TokenType } from '../models/Lexeme';
3
+ import { StringUtils } from '../utils/stringUtils';
4
+ import { KeywordTrie } from '../models/KeywordTrie';
5
+ import { KeywordParser } from '../parsers/KeywordParser';
6
+ // Use KeywordTrie to identify type names composed of multiple words.
7
+ const trie = new KeywordTrie([
8
+ // type
9
+ ["double", "precision"],
10
+ ["character", "varying"],
11
+ ["time", "without", "time", "zone"],
12
+ ["time", "with", "time", "zone"],
13
+ ["timestamp", "without", "time", "zone"],
14
+ ["timestamp", "with", "time", "zone"],
15
+ ]);
16
+ const typeParser = new KeywordParser(trie);
17
+ /**
18
+ * Reads SQL identifier tokens
19
+ */
20
+ export class TypeTokenReader extends BaseTokenReader {
21
+ /**
22
+ * Try to read an identifier token
23
+ */
24
+ tryRead(previous) {
25
+ if (this.isEndOfInput()) {
26
+ return null;
27
+ }
28
+ // Check for keyword identifiers
29
+ const keyword = typeParser.parse(this.input, this.position);
30
+ if (keyword !== null) {
31
+ this.position = keyword.newPosition;
32
+ return this.createLexeme(TokenType.Type, keyword.keyword);
33
+ }
34
+ // check pervious token
35
+ if (previous === null) {
36
+ return null;
37
+ }
38
+ const result = StringUtils.tryReadRegularIdentifier(this.input, this.position);
39
+ if (!result) {
40
+ return null;
41
+ }
42
+ this.position = result.newPosition;
43
+ // type cast command
44
+ if (previous.type === TokenType.Command && previous.value === "as") {
45
+ // If the previous token is the `as` keyword, it could be a type cast or an identifier
46
+ return this.createLexeme(TokenType.Identifier, result.identifier, true);
47
+ }
48
+ // postgres type conversion
49
+ if (previous.type === TokenType.Operator && previous.value === "::") {
50
+ return this.createLexeme(TokenType.Type, result.identifier);
51
+ }
52
+ return null;
53
+ }
54
+ }
55
+ //# sourceMappingURL=TypeTokenReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeTokenReader.js","sourceRoot":"","sources":["../../../src/tokenReaders/TypeTokenReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAU,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,qEAAqE;AACrE,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC;IACzB,OAAO;IACP,CAAC,QAAQ,EAAE,WAAW,CAAC;IACvB,CAAC,WAAW,EAAE,SAAS,CAAC;IACxB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;IACnC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAChC,CAAC,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC;IACxC,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;CACxC,CAAC,CAAC;AACH,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,OAAO,eAAgB,SAAQ,eAAe;IAChD;;OAEG;IACI,OAAO,CAAC,QAAuB;QAClC,IAAI,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5D,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACnB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;YACpC,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9D,CAAC;QAED,uBAAuB;QACvB,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,wBAAwB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/E,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC;QAEnC,oBAAoB;QACpB,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,OAAO,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACjE,sFAAsF;YACtF,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC5E,CAAC;QAED,2BAA2B;QAC3B,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QAChE,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;CACJ"}
@@ -0,0 +1,184 @@
1
+ import { WithClause } from "../models/Clause";
2
+ import { CTECollector } from "./CTECollector";
3
+ import { TableSourceCollector } from "./TableSourceCollector";
4
+ import { Formatter } from "./Formatter";
5
+ /**
6
+ * CTENameConflictResolver is responsible for resolving name conflicts among Common Table Expressions (CTEs).
7
+ * It also sorts the tables in the proper order based on dependencies and recursiveness.
8
+ */
9
+ export class CTEBuilder {
10
+ constructor() {
11
+ this.sourceCollector = new TableSourceCollector(true);
12
+ this.cteCollector = new CTECollector();
13
+ this.formatter = new Formatter();
14
+ }
15
+ /**
16
+ * Resolves name conflicts among CommonTables.
17
+ * If there are duplicate CTE names, they must have identical definitions.
18
+ * Also sorts the tables so that:
19
+ * 1. Recursive CTEs come first (CTEs that reference themselves)
20
+ * 2. Then remaining tables are sorted so inner (deeper) CTEs come before outer CTEs
21
+ *
22
+ * @param commonTables The list of CommonTables to check for name conflicts
23
+ * @returns An object containing:
24
+ * - needRecursive: boolean indicating if any recursive CTEs are present
25
+ * - commonTables: A new list of CommonTables with resolved name conflicts and proper order
26
+ * @throws Error if there are duplicate CTE names with different definitions
27
+ */
28
+ build(commonTables) {
29
+ // Early return for empty CTEs
30
+ // Note:
31
+ // Although it may seem reasonable to return early when there is only one element,
32
+ // the 'recursive' property is determined dynamically. Therefore, if there is at least one element,
33
+ // the CTEs must be rebuilt to ensure correct recursive detection.
34
+ if (commonTables.length === 0) {
35
+ return new WithClause(false, commonTables);
36
+ }
37
+ // Step 1: Resolve name conflicts
38
+ const resolvedTables = this.resolveDuplicateNames(commonTables);
39
+ // Step 2: Identify recursive CTEs and build dependency graph
40
+ const { tableMap, recursiveCTEs, dependencies } = this.buildDependencyGraph(resolvedTables);
41
+ // Step 3: Sort tables according to dependencies and recursiveness
42
+ const sortedTables = this.sortCommonTables(resolvedTables, tableMap, recursiveCTEs, dependencies);
43
+ return new WithClause(recursiveCTEs.size > 0, sortedTables);
44
+ }
45
+ /**
46
+ * Resolves duplicate CTE names by checking if they have identical definitions.
47
+ * If definitions differ, throws an error.
48
+ *
49
+ * @param commonTables The list of CTEs to check for duplicates
50
+ * @returns A list of CTEs with duplicates removed
51
+ * @throws Error if there are duplicate CTE names with different definitions
52
+ */
53
+ resolveDuplicateNames(commonTables) {
54
+ // Group CTEs by their names
55
+ const ctesByName = new Map();
56
+ for (const table of commonTables) {
57
+ const tableName = table.aliasExpression.table.name;
58
+ if (!ctesByName.has(tableName)) {
59
+ ctesByName.set(tableName, []);
60
+ }
61
+ ctesByName.get(tableName).push(table);
62
+ }
63
+ // Resolve name duplications
64
+ const resolvedTables = [];
65
+ for (const [name, tables] of ctesByName.entries()) {
66
+ if (tables.length === 1) {
67
+ // No duplication
68
+ resolvedTables.push(tables[0]);
69
+ continue;
70
+ }
71
+ // For duplicate names, check if definitions are identical
72
+ const definitions = tables.map(table => this.formatter.format(table.query));
73
+ const uniqueDefinitions = new Set(definitions);
74
+ if (uniqueDefinitions.size === 1) {
75
+ // If all definitions are identical, use only the first one
76
+ resolvedTables.push(tables[0]);
77
+ }
78
+ else {
79
+ // Error if definitions differ
80
+ throw new Error(`CTE name conflict detected: '${name}' has multiple different definitions`);
81
+ }
82
+ }
83
+ return resolvedTables;
84
+ }
85
+ /**
86
+ * Builds a dependency graph of CTEs and identifies recursive CTEs.
87
+ *
88
+ * @param tables The list of CTEs to analyze
89
+ * @returns Object containing the table map, set of recursive CTEs, and dependency map
90
+ */
91
+ buildDependencyGraph(tables) {
92
+ // Create a map of table names for quick lookup
93
+ const tableMap = new Map();
94
+ for (const table of tables) {
95
+ tableMap.set(table.aliasExpression.table.name, table);
96
+ }
97
+ // Identify recursive CTEs (those that reference themselves)
98
+ const recursiveCTEs = new Set();
99
+ // Build dependency graph: which tables reference which other tables
100
+ const dependencies = new Map();
101
+ const referencedBy = new Map();
102
+ for (const table of tables) {
103
+ const tableName = table.aliasExpression.table.name;
104
+ // Check for self-references (recursive CTEs)
105
+ const referencedTables = this.sourceCollector.collect(table.query);
106
+ // Check if this CTE references itself
107
+ for (const referencedTable of referencedTables) {
108
+ if (referencedTable.table.name === tableName) {
109
+ recursiveCTEs.add(tableName);
110
+ break;
111
+ }
112
+ }
113
+ // Setup dependencies
114
+ if (!dependencies.has(tableName)) {
115
+ dependencies.set(tableName, new Set());
116
+ }
117
+ // Find any references to other CTEs in this table's query
118
+ const referencedCTEs = this.cteCollector.collect(table.query);
119
+ for (const referencedCTE of referencedCTEs) {
120
+ const referencedName = referencedCTE.aliasExpression.table.name;
121
+ // Only consider references to tables in our collection
122
+ if (tableMap.has(referencedName)) {
123
+ dependencies.get(tableName).add(referencedName);
124
+ // Add the reverse relationship
125
+ if (!referencedBy.has(referencedName)) {
126
+ referencedBy.set(referencedName, new Set());
127
+ }
128
+ referencedBy.get(referencedName).add(tableName);
129
+ }
130
+ }
131
+ }
132
+ return { tableMap, recursiveCTEs, dependencies };
133
+ }
134
+ /**
135
+ * Sorts the CTEs using topological sort, with recursive CTEs coming first.
136
+ *
137
+ * @param tables The list of CTEs to sort
138
+ * @param tableMap Map of table names to their CommonTable objects
139
+ * @param recursiveCTEs Set of table names that are recursive (self-referential)
140
+ * @param dependencies Map of table dependencies
141
+ * @returns Sorted list of CTEs
142
+ * @throws Error if a circular reference is detected
143
+ */
144
+ sortCommonTables(tables, tableMap, recursiveCTEs, dependencies) {
145
+ const recursiveResult = [];
146
+ const nonRecursiveResult = [];
147
+ const visited = new Set();
148
+ const visiting = new Set();
149
+ // Topological sort function
150
+ const visit = (tableName) => {
151
+ if (visited.has(tableName))
152
+ return;
153
+ if (visiting.has(tableName)) {
154
+ throw new Error(`Circular reference detected in CTE: ${tableName}`);
155
+ }
156
+ visiting.add(tableName);
157
+ // Process dependencies first (inner CTEs)
158
+ const deps = dependencies.get(tableName) || new Set();
159
+ for (const dep of deps) {
160
+ visit(dep);
161
+ }
162
+ visiting.delete(tableName);
163
+ visited.add(tableName);
164
+ // Add this table after its dependencies
165
+ // Recursive CTEs go to recursiveResult, others to nonRecursiveResult
166
+ if (recursiveCTEs.has(tableName)) {
167
+ recursiveResult.push(tableMap.get(tableName));
168
+ }
169
+ else {
170
+ nonRecursiveResult.push(tableMap.get(tableName));
171
+ }
172
+ };
173
+ // Process all tables
174
+ for (const table of tables) {
175
+ const tableName = table.aliasExpression.table.name;
176
+ if (!visited.has(tableName)) {
177
+ visit(tableName);
178
+ }
179
+ }
180
+ // Combine the results: recursive CTEs first, then non-recursive CTEs
181
+ return [...recursiveResult, ...nonRecursiveResult];
182
+ }
183
+ }
184
+ //# sourceMappingURL=CTEBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CTEBuilder.js","sourceRoot":"","sources":["../../../src/transformers/CTEBuilder.ts"],"names":[],"mappings":"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"}