rawsql-ts 0.1.0-beta.11 → 0.1.0-beta.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -18
- package/dist/esm/index.js +17 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/models/BinarySelectQuery.js +137 -0
- package/dist/esm/models/BinarySelectQuery.js.map +1 -0
- package/dist/esm/models/Clause.js +289 -0
- package/dist/esm/models/Clause.js.map +1 -0
- package/dist/esm/models/KeywordTrie.js +48 -0
- package/dist/esm/models/KeywordTrie.js.map +1 -0
- package/dist/esm/models/Lexeme.js +18 -0
- package/dist/esm/models/Lexeme.js.map +1 -0
- package/dist/esm/models/SelectQuery.js +5 -0
- package/dist/esm/models/SelectQuery.js.map +1 -0
- package/dist/esm/models/SimpleSelectQuery.js +288 -0
- package/dist/esm/models/SimpleSelectQuery.js.map +1 -0
- package/dist/esm/models/SqlComponent.js +22 -0
- package/dist/esm/models/SqlComponent.js.map +1 -0
- package/dist/esm/models/ValueComponent.js +223 -0
- package/dist/esm/models/ValueComponent.js.map +1 -0
- package/dist/esm/models/ValuesQuery.js +12 -0
- package/dist/esm/models/ValuesQuery.js.map +1 -0
- package/dist/esm/parsers/CommandExpressionParser.js +120 -0
- package/dist/esm/parsers/CommandExpressionParser.js.map +1 -0
- package/dist/esm/parsers/CommonTableParser.js +58 -0
- package/dist/esm/parsers/CommonTableParser.js.map +1 -0
- package/dist/esm/parsers/ForClauseParser.js +54 -0
- package/dist/esm/parsers/ForClauseParser.js.map +1 -0
- package/dist/esm/parsers/FromClauseParser.js +43 -0
- package/dist/esm/parsers/FromClauseParser.js.map +1 -0
- package/dist/esm/parsers/FunctionExpressionParser.js +174 -0
- package/dist/esm/parsers/FunctionExpressionParser.js.map +1 -0
- package/dist/esm/parsers/GroupByParser.js +54 -0
- package/dist/esm/parsers/GroupByParser.js.map +1 -0
- package/dist/esm/parsers/HavingParser.js +32 -0
- package/dist/esm/parsers/HavingParser.js.map +1 -0
- package/dist/esm/parsers/IdentifierParser.js +35 -0
- package/dist/esm/parsers/IdentifierParser.js.map +1 -0
- package/dist/esm/parsers/JoinClauseParser.js +101 -0
- package/dist/esm/parsers/JoinClauseParser.js.map +1 -0
- package/dist/esm/parsers/KeywordParser.js +87 -0
- package/dist/esm/parsers/KeywordParser.js.map +1 -0
- package/dist/esm/parsers/LimitClauseParser.js +46 -0
- package/dist/esm/parsers/LimitClauseParser.js.map +1 -0
- package/dist/esm/parsers/LiteralParser.js +34 -0
- package/dist/esm/parsers/LiteralParser.js.map +1 -0
- package/dist/esm/parsers/OrderByClauseParser.js +73 -0
- package/dist/esm/parsers/OrderByClauseParser.js.map +1 -0
- package/dist/esm/parsers/OverExpressionParser.js +40 -0
- package/dist/esm/parsers/OverExpressionParser.js.map +1 -0
- package/dist/esm/parsers/ParameterExpressionParser.js +11 -0
- package/dist/esm/parsers/ParameterExpressionParser.js.map +1 -0
- package/dist/esm/parsers/ParenExpressionParser.js +29 -0
- package/dist/esm/parsers/ParenExpressionParser.js.map +1 -0
- package/dist/esm/parsers/PartitionByParser.js +49 -0
- package/dist/esm/parsers/PartitionByParser.js.map +1 -0
- package/dist/esm/parsers/SelectClauseParser.js +80 -0
- package/dist/esm/parsers/SelectClauseParser.js.map +1 -0
- package/dist/esm/parsers/SelectQueryParser.js +149 -0
- package/dist/esm/parsers/SelectQueryParser.js.map +1 -0
- package/dist/esm/parsers/SourceAliasExpressionParser.js +45 -0
- package/dist/esm/parsers/SourceAliasExpressionParser.js.map +1 -0
- package/dist/esm/parsers/SourceExpressionParser.js +31 -0
- package/dist/esm/parsers/SourceExpressionParser.js.map +1 -0
- package/dist/esm/parsers/SourceParser.js +115 -0
- package/dist/esm/parsers/SourceParser.js.map +1 -0
- package/dist/esm/parsers/SqlTokenizer.js +170 -0
- package/dist/esm/parsers/SqlTokenizer.js.map +1 -0
- package/dist/esm/parsers/StringSpecifierExpressionParser.js +18 -0
- package/dist/esm/parsers/StringSpecifierExpressionParser.js.map +1 -0
- package/dist/esm/parsers/UnaryExpressionParser.js +26 -0
- package/dist/esm/parsers/UnaryExpressionParser.js.map +1 -0
- package/dist/esm/parsers/ValueParser.js +132 -0
- package/dist/esm/parsers/ValueParser.js.map +1 -0
- package/dist/esm/parsers/ValuesQueryParser.js +82 -0
- package/dist/esm/parsers/ValuesQueryParser.js.map +1 -0
- package/dist/esm/parsers/WhereClauseParser.js +32 -0
- package/dist/esm/parsers/WhereClauseParser.js.map +1 -0
- package/dist/esm/parsers/WindowClauseParser.js +41 -0
- package/dist/esm/parsers/WindowClauseParser.js.map +1 -0
- package/dist/esm/parsers/WindowExpressionParser.js +159 -0
- package/dist/esm/parsers/WindowExpressionParser.js.map +1 -0
- package/dist/esm/parsers/WithClauseParser.js +53 -0
- package/dist/esm/parsers/WithClauseParser.js.map +1 -0
- package/dist/esm/tokenReaders/BaseTokenReader.js +78 -0
- package/dist/esm/tokenReaders/BaseTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/CommandTokenReader.js +141 -0
- package/dist/esm/tokenReaders/CommandTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/FunctionTokenReader.js +41 -0
- package/dist/esm/tokenReaders/FunctionTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/IdentifierTokenReader.js +66 -0
- package/dist/esm/tokenReaders/IdentifierTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/LiteralTokenReader.js +185 -0
- package/dist/esm/tokenReaders/LiteralTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/OperatorTokenReader.js +94 -0
- package/dist/esm/tokenReaders/OperatorTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/ParameterTokenReader.js +40 -0
- package/dist/esm/tokenReaders/ParameterTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/StringSpecifierTokenReader.js +27 -0
- package/dist/esm/tokenReaders/StringSpecifierTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/SymbolTokenReader.js +31 -0
- package/dist/esm/tokenReaders/SymbolTokenReader.js.map +1 -0
- package/dist/esm/tokenReaders/TokenReaderManager.js +106 -0
- package/dist/esm/tokenReaders/TokenReaderManager.js.map +1 -0
- package/dist/esm/tokenReaders/TypeTokenReader.js +55 -0
- package/dist/esm/tokenReaders/TypeTokenReader.js.map +1 -0
- package/dist/esm/transformers/CTEBuilder.js +184 -0
- package/dist/esm/transformers/CTEBuilder.js.map +1 -0
- package/dist/esm/transformers/CTECollector.js +380 -0
- package/dist/esm/transformers/CTECollector.js.map +1 -0
- package/dist/esm/transformers/CTEDisabler.js +321 -0
- package/dist/esm/transformers/CTEDisabler.js.map +1 -0
- package/dist/esm/transformers/CTEInjector.js +79 -0
- package/dist/esm/transformers/CTEInjector.js.map +1 -0
- package/dist/esm/transformers/CTENormalizer.js +42 -0
- package/dist/esm/transformers/CTENormalizer.js.map +1 -0
- package/dist/esm/transformers/Formatter.js +463 -0
- package/dist/esm/transformers/Formatter.js.map +1 -0
- package/dist/esm/transformers/QueryConverter.js +115 -0
- package/dist/esm/transformers/QueryConverter.js.map +1 -0
- package/dist/esm/transformers/SelectValueCollector.js +245 -0
- package/dist/esm/transformers/SelectValueCollector.js.map +1 -0
- package/dist/esm/transformers/SelectableColumnCollector.js +304 -0
- package/dist/esm/transformers/SelectableColumnCollector.js.map +1 -0
- package/dist/esm/transformers/TableColumnResolver.js +2 -0
- package/dist/esm/transformers/TableColumnResolver.js.map +1 -0
- package/dist/esm/transformers/TableSourceCollector.js +380 -0
- package/dist/esm/transformers/TableSourceCollector.js.map +1 -0
- package/dist/esm/transformers/UpstreamSelectQueryFinder.js +125 -0
- package/dist/esm/transformers/UpstreamSelectQueryFinder.js.map +1 -0
- package/dist/esm/types/index.d.ts +14 -0
- package/dist/esm/types/models/BinarySelectQuery.d.ts +91 -0
- package/dist/esm/types/models/Clause.d.ts +189 -0
- package/dist/esm/types/models/KeywordTrie.d.ts +11 -0
- package/dist/esm/types/models/Lexeme.d.ts +25 -0
- package/dist/esm/types/models/SelectQuery.d.ts +5 -0
- package/dist/esm/types/models/SimpleSelectQuery.d.ts +167 -0
- package/dist/esm/types/models/SqlComponent.d.ts +18 -0
- package/dist/esm/types/models/ValueComponent.d.ts +158 -0
- package/dist/esm/types/models/ValuesQuery.d.ts +10 -0
- package/dist/esm/types/parsers/CommandExpressionParser.d.ts +15 -0
- package/dist/esm/types/parsers/CommonTableParser.d.ts +9 -0
- package/dist/esm/types/parsers/ForClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/FromClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/FunctionExpressionParser.d.ts +22 -0
- package/dist/esm/types/parsers/GroupByParser.d.ts +10 -0
- package/dist/esm/types/parsers/HavingParser.d.ts +9 -0
- package/dist/esm/types/parsers/IdentifierParser.d.ts +8 -0
- package/dist/esm/types/parsers/JoinClauseParser.d.ts +14 -0
- package/dist/esm/types/parsers/KeywordParser.d.ts +17 -0
- package/dist/esm/types/parsers/LimitClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/LiteralParser.d.ts +8 -0
- package/dist/esm/types/parsers/OrderByClauseParser.d.ts +10 -0
- package/dist/esm/types/parsers/OverExpressionParser.d.ts +9 -0
- package/dist/esm/types/parsers/ParameterExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/ParenExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/PartitionByParser.d.ts +9 -0
- package/dist/esm/types/parsers/SelectClauseParser.d.ts +10 -0
- package/dist/esm/types/parsers/SelectQueryParser.d.ts +13 -0
- package/dist/esm/types/parsers/SourceAliasExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/SourceExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/SourceParser.d.ts +13 -0
- package/dist/esm/types/parsers/SqlTokenizer.d.ts +64 -0
- package/dist/esm/types/parsers/StringSpecifierExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/UnaryExpressionParser.d.ts +8 -0
- package/dist/esm/types/parsers/ValueParser.d.ts +14 -0
- package/dist/esm/types/parsers/ValuesQueryParser.d.ts +10 -0
- package/dist/esm/types/parsers/WhereClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/WindowClauseParser.d.ts +9 -0
- package/dist/esm/types/parsers/WindowExpressionParser.d.ts +12 -0
- package/dist/esm/types/parsers/WithClauseParser.d.ts +9 -0
- package/dist/esm/types/tokenReaders/BaseTokenReader.d.ts +43 -0
- package/dist/esm/types/tokenReaders/CommandTokenReader.d.ts +7 -0
- package/dist/esm/types/tokenReaders/FunctionTokenReader.d.ts +11 -0
- package/dist/esm/types/tokenReaders/IdentifierTokenReader.d.ts +15 -0
- package/dist/esm/types/tokenReaders/LiteralTokenReader.d.ts +23 -0
- package/dist/esm/types/tokenReaders/OperatorTokenReader.d.ts +5 -0
- package/dist/esm/types/tokenReaders/ParameterTokenReader.d.ts +11 -0
- package/dist/esm/types/tokenReaders/StringSpecifierTokenReader.d.ts +8 -0
- package/dist/esm/types/tokenReaders/SymbolTokenReader.d.ts +12 -0
- package/dist/esm/types/tokenReaders/TokenReaderManager.d.ts +53 -0
- package/dist/esm/types/tokenReaders/TypeTokenReader.d.ts +11 -0
- package/dist/esm/types/transformers/CTEBuilder.d.ts +52 -0
- package/dist/esm/types/transformers/CTECollector.d.ts +81 -0
- package/dist/esm/types/transformers/CTEDisabler.d.ts +77 -0
- package/dist/esm/types/transformers/CTEInjector.d.ts +40 -0
- package/dist/esm/types/transformers/CTENormalizer.d.ts +25 -0
- package/dist/esm/types/transformers/Formatter.d.ts +82 -0
- package/dist/esm/types/transformers/QueryConverter.d.ts +41 -0
- package/dist/esm/types/transformers/SelectValueCollector.d.ts +60 -0
- package/dist/esm/types/transformers/SelectableColumnCollector.d.ts +70 -0
- package/dist/esm/types/transformers/TableColumnResolver.d.ts +10 -0
- package/dist/esm/types/transformers/TableSourceCollector.d.ts +92 -0
- package/dist/esm/types/transformers/UpstreamSelectQueryFinder.d.ts +27 -0
- package/dist/esm/types/utils/charLookupTable.d.ts +11 -0
- package/dist/esm/types/utils/stringUtils.d.ts +43 -0
- package/dist/esm/utils/charLookupTable.js +69 -0
- package/dist/esm/utils/charLookupTable.js.map +1 -0
- package/dist/esm/utils/stringUtils.js +164 -0
- package/dist/esm/utils/stringUtils.js.map +1 -0
- package/package.json +4 -1
@@ -0,0 +1,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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"}
|