rawsql-ts 0.24.2 → 0.24.4
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 +10 -1
- package/dist/esm/index.min.js +9 -9
- package/dist/esm/index.min.js.map +2 -2
- package/dist/esm/models/ValueComponent.d.ts +2 -1
- package/dist/esm/models/ValueComponent.js +2 -1
- package/dist/esm/models/ValueComponent.js.map +1 -1
- package/dist/esm/parsers/CommandExpressionParser.d.ts +2 -0
- package/dist/esm/parsers/CommandExpressionParser.js +49 -4
- package/dist/esm/parsers/CommandExpressionParser.js.map +1 -1
- package/dist/esm/parsers/HavingParser.js +6 -0
- package/dist/esm/parsers/HavingParser.js.map +1 -1
- package/dist/esm/parsers/JoinOnClauseParser.js +6 -0
- package/dist/esm/parsers/JoinOnClauseParser.js.map +1 -1
- package/dist/esm/parsers/LimitClauseParser.js +6 -0
- package/dist/esm/parsers/LimitClauseParser.js.map +1 -1
- package/dist/esm/parsers/OffsetClauseParser.js +6 -0
- package/dist/esm/parsers/OffsetClauseParser.js.map +1 -1
- package/dist/esm/parsers/OrderByClauseParser.d.ts +2 -0
- package/dist/esm/parsers/OrderByClauseParser.js +42 -29
- package/dist/esm/parsers/OrderByClauseParser.js.map +1 -1
- package/dist/esm/parsers/ParameterDecorator.d.ts +2 -2
- package/dist/esm/parsers/ParameterDecorator.js +1 -1
- package/dist/esm/parsers/ParameterDecorator.js.map +1 -1
- package/dist/esm/parsers/ParameterExpressionParser.js +2 -1
- package/dist/esm/parsers/ParameterExpressionParser.js.map +1 -1
- package/dist/esm/parsers/SqlPrintTokenParser.d.ts +18 -4
- package/dist/esm/parsers/SqlPrintTokenParser.js +135 -18
- package/dist/esm/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/esm/parsers/ValueParser.js +5 -3
- package/dist/esm/parsers/ValueParser.js.map +1 -1
- package/dist/esm/transformers/FormatOptionResolver.js +1 -0
- package/dist/esm/transformers/FormatOptionResolver.js.map +1 -1
- package/dist/esm/transformers/LinePrinter.d.ts +1 -1
- package/dist/esm/transformers/OnelineFormattingHelper.d.ts +1 -0
- package/dist/esm/transformers/OnelineFormattingHelper.js.map +1 -1
- package/dist/esm/transformers/SqlFormatter.d.ts +9 -5
- package/dist/esm/transformers/SqlFormatter.js +4 -4
- package/dist/esm/transformers/SqlFormatter.js.map +1 -1
- package/dist/esm/transformers/SqlPrinter.d.ts +26 -2
- package/dist/esm/transformers/SqlPrinter.js +325 -26
- package/dist/esm/transformers/SqlPrinter.js.map +1 -1
- package/dist/index.min.js +9 -9
- package/dist/index.min.js.map +2 -2
- package/dist/models/ValueComponent.js +2 -1
- package/dist/models/ValueComponent.js.map +1 -1
- package/dist/parsers/CommandExpressionParser.js +49 -4
- package/dist/parsers/CommandExpressionParser.js.map +1 -1
- package/dist/parsers/HavingParser.js +6 -0
- package/dist/parsers/HavingParser.js.map +1 -1
- package/dist/parsers/JoinOnClauseParser.js +6 -0
- package/dist/parsers/JoinOnClauseParser.js.map +1 -1
- package/dist/parsers/LimitClauseParser.js +6 -0
- package/dist/parsers/LimitClauseParser.js.map +1 -1
- package/dist/parsers/OffsetClauseParser.js +6 -0
- package/dist/parsers/OffsetClauseParser.js.map +1 -1
- package/dist/parsers/OrderByClauseParser.js +42 -29
- package/dist/parsers/OrderByClauseParser.js.map +1 -1
- package/dist/parsers/ParameterDecorator.js +1 -1
- package/dist/parsers/ParameterDecorator.js.map +1 -1
- package/dist/parsers/ParameterExpressionParser.js +2 -1
- package/dist/parsers/ParameterExpressionParser.js.map +1 -1
- package/dist/parsers/SqlPrintTokenParser.js +136 -18
- package/dist/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/parsers/ValueParser.js +5 -3
- package/dist/parsers/ValueParser.js.map +1 -1
- package/dist/src/models/ValueComponent.d.ts +2 -1
- package/dist/src/parsers/CommandExpressionParser.d.ts +2 -0
- package/dist/src/parsers/OrderByClauseParser.d.ts +2 -0
- package/dist/src/parsers/ParameterDecorator.d.ts +2 -2
- package/dist/src/parsers/SqlPrintTokenParser.d.ts +18 -4
- package/dist/src/transformers/LinePrinter.d.ts +1 -1
- package/dist/src/transformers/OnelineFormattingHelper.d.ts +1 -0
- package/dist/src/transformers/SqlFormatter.d.ts +9 -5
- package/dist/src/transformers/SqlPrinter.d.ts +26 -2
- package/dist/transformers/FormatOptionResolver.js +1 -0
- package/dist/transformers/FormatOptionResolver.js.map +1 -1
- package/dist/transformers/OnelineFormattingHelper.js.map +1 -1
- package/dist/transformers/SqlFormatter.js +5 -3
- package/dist/transformers/SqlFormatter.js.map +1 -1
- package/dist/transformers/SqlPrinter.js +325 -26
- package/dist/transformers/SqlPrinter.js.map +1 -1
- package/dist/tsconfig.browser.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -9,11 +9,14 @@ import { CreateTableQuery } from "../models/CreateTableQuery";
|
|
|
9
9
|
export declare enum ParameterStyle {
|
|
10
10
|
Anonymous = "anonymous",
|
|
11
11
|
Indexed = "indexed",
|
|
12
|
-
Named = "named"
|
|
12
|
+
Named = "named",
|
|
13
|
+
Original = "original"
|
|
13
14
|
}
|
|
14
15
|
export type CastStyle = 'postgres' | 'standard';
|
|
15
16
|
export type ConstraintStyle = 'postgres' | 'mysql';
|
|
16
|
-
export type
|
|
17
|
+
export type AliasKeywordStyle = 'explicit' | 'omit' | 'as' | 'implicit';
|
|
18
|
+
export type SourceAliasStyle = AliasKeywordStyle;
|
|
19
|
+
export type ColumnAliasStyle = AliasKeywordStyle;
|
|
17
20
|
export type OrderByDefaultDirectionStyle = 'omit' | 'explicit';
|
|
18
21
|
export interface FormatterConfig {
|
|
19
22
|
identifierEscape?: {
|
|
@@ -26,7 +29,7 @@ export interface FormatterConfig {
|
|
|
26
29
|
end: string;
|
|
27
30
|
};
|
|
28
31
|
/**
|
|
29
|
-
* Parameter style: anonymous (?), indexed ($1),
|
|
32
|
+
* Parameter style: anonymous (?), indexed ($1), named (:name), or original parsed spelling.
|
|
30
33
|
*/
|
|
31
34
|
parameterStyle?: ParameterStyle;
|
|
32
35
|
/** Controls how CAST expressions are rendered */
|
|
@@ -35,6 +38,8 @@ export interface FormatterConfig {
|
|
|
35
38
|
constraintStyle?: ConstraintStyle;
|
|
36
39
|
/** Controls whether source aliases are rendered with an explicit AS keyword */
|
|
37
40
|
sourceAliasStyle?: SourceAliasStyle;
|
|
41
|
+
/** Controls whether column aliases are rendered with an explicit AS keyword */
|
|
42
|
+
columnAliasStyle?: ColumnAliasStyle;
|
|
38
43
|
/** Controls whether the default ASC direction is omitted or rendered explicitly */
|
|
39
44
|
orderByDefaultDirectionStyle?: OrderByDefaultDirectionStyle;
|
|
40
45
|
}
|
|
@@ -55,8 +60,10 @@ export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrint
|
|
|
55
60
|
private castStyle;
|
|
56
61
|
private constraintStyle;
|
|
57
62
|
private sourceAliasStyle;
|
|
63
|
+
private columnAliasStyle;
|
|
58
64
|
private orderByDefaultDirectionStyle;
|
|
59
65
|
private readonly normalizeJoinConditionOrder;
|
|
66
|
+
private readonly listContinuationCommentComponents;
|
|
60
67
|
private joinConditionContexts;
|
|
61
68
|
constructor(options?: {
|
|
62
69
|
preset?: FormatterConfig;
|
|
@@ -69,10 +76,11 @@ export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrint
|
|
|
69
76
|
start: string;
|
|
70
77
|
end: string;
|
|
71
78
|
};
|
|
72
|
-
parameterStyle?: 'anonymous' | 'indexed' | 'named';
|
|
79
|
+
parameterStyle?: 'anonymous' | 'indexed' | 'named' | 'original';
|
|
73
80
|
castStyle?: CastStyle;
|
|
74
81
|
constraintStyle?: ConstraintStyle;
|
|
75
82
|
sourceAliasStyle?: SourceAliasStyle;
|
|
83
|
+
columnAliasStyle?: ColumnAliasStyle;
|
|
76
84
|
orderByDefaultDirectionStyle?: OrderByDefaultDirectionStyle;
|
|
77
85
|
joinConditionOrderByDeclaration?: boolean;
|
|
78
86
|
});
|
|
@@ -218,6 +226,8 @@ export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrint
|
|
|
218
226
|
private visitParenExpression;
|
|
219
227
|
private visitCastExpression;
|
|
220
228
|
private visitCaseExpression;
|
|
229
|
+
private removeCaseAfterCommentsDuplicatedOnFirstWhen;
|
|
230
|
+
private normalizeCommentSignature;
|
|
221
231
|
private extractSwitchAfterComments;
|
|
222
232
|
private collectCaseLeadingCommentsFromSwitch;
|
|
223
233
|
private findCaseKeyToken;
|
|
@@ -249,6 +259,8 @@ export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrint
|
|
|
249
259
|
*/
|
|
250
260
|
private visitWindowFrameBoundStatic;
|
|
251
261
|
private visitSelectItem;
|
|
262
|
+
private collectCaseSelectItemDuplicateAfterComments;
|
|
263
|
+
private filterCaseSelectItemDuplicateAfterComments;
|
|
252
264
|
private visitSelectClause;
|
|
253
265
|
private flattenTokenText;
|
|
254
266
|
private visitHintClause;
|
|
@@ -257,6 +269,8 @@ export declare class SqlPrintTokenParser implements SqlComponentVisitor<SqlPrint
|
|
|
257
269
|
private visitTableSource;
|
|
258
270
|
private visitSourceExpression;
|
|
259
271
|
private appendSourceAliasKeyword;
|
|
272
|
+
private shouldPrintColumnAliasKeyword;
|
|
273
|
+
private normalizeAliasKeywordStyle;
|
|
260
274
|
visitFromClause(arg: FromClause): SqlPrintToken;
|
|
261
275
|
visitJoinClause(arg: JoinClause): SqlPrintToken;
|
|
262
276
|
visitJoinOnClause(arg: JoinOnClause): SqlPrintToken;
|
|
@@ -18,6 +18,7 @@ export var ParameterStyle;
|
|
|
18
18
|
ParameterStyle["Anonymous"] = "anonymous";
|
|
19
19
|
ParameterStyle["Indexed"] = "indexed";
|
|
20
20
|
ParameterStyle["Named"] = "named";
|
|
21
|
+
ParameterStyle["Original"] = "original";
|
|
21
22
|
})(ParameterStyle || (ParameterStyle = {}));
|
|
22
23
|
export const PRESETS = {
|
|
23
24
|
mysql: {
|
|
@@ -138,6 +139,7 @@ export class SqlPrintTokenParser {
|
|
|
138
139
|
this._selfHandlingComponentTypes = new Set([
|
|
139
140
|
SimpleSelectQuery.kind,
|
|
140
141
|
SelectItem.kind,
|
|
142
|
+
OrderByItem.kind,
|
|
141
143
|
CaseKeyValuePair.kind,
|
|
142
144
|
SwitchCaseArgument.kind,
|
|
143
145
|
ColumnReference.kind,
|
|
@@ -154,9 +156,10 @@ export class SqlPrintTokenParser {
|
|
|
154
156
|
return this._selfHandlingComponentTypes;
|
|
155
157
|
}
|
|
156
158
|
constructor(options) {
|
|
157
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m
|
|
159
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
158
160
|
this.handlers = new Map();
|
|
159
161
|
this.index = 1;
|
|
162
|
+
this.listContinuationCommentComponents = new WeakSet();
|
|
160
163
|
this.joinConditionContexts = [];
|
|
161
164
|
if (options === null || options === void 0 ? void 0 : options.preset) {
|
|
162
165
|
const preset = options.preset;
|
|
@@ -174,9 +177,10 @@ export class SqlPrintTokenParser {
|
|
|
174
177
|
});
|
|
175
178
|
this.castStyle = (_j = options === null || options === void 0 ? void 0 : options.castStyle) !== null && _j !== void 0 ? _j : 'standard';
|
|
176
179
|
this.constraintStyle = (_k = options === null || options === void 0 ? void 0 : options.constraintStyle) !== null && _k !== void 0 ? _k : 'postgres';
|
|
177
|
-
this.sourceAliasStyle = (
|
|
178
|
-
this.
|
|
179
|
-
this.
|
|
180
|
+
this.sourceAliasStyle = this.normalizeAliasKeywordStyle(options === null || options === void 0 ? void 0 : options.sourceAliasStyle);
|
|
181
|
+
this.columnAliasStyle = this.normalizeAliasKeywordStyle(options === null || options === void 0 ? void 0 : options.columnAliasStyle);
|
|
182
|
+
this.orderByDefaultDirectionStyle = (_l = options === null || options === void 0 ? void 0 : options.orderByDefaultDirectionStyle) !== null && _l !== void 0 ? _l : 'omit';
|
|
183
|
+
this.normalizeJoinConditionOrder = (_m = options === null || options === void 0 ? void 0 : options.joinConditionOrderByDeclaration) !== null && _m !== void 0 ? _m : false;
|
|
180
184
|
this.handlers.set(ValueList.kind, (expr) => this.visitValueList(expr));
|
|
181
185
|
this.handlers.set(ColumnReference.kind, (expr) => this.visitColumnReference(expr));
|
|
182
186
|
this.handlers.set(QualifiedName.kind, (expr) => this.visitQualifiedName(expr));
|
|
@@ -346,6 +350,7 @@ export class SqlPrintTokenParser {
|
|
|
346
350
|
}
|
|
347
351
|
visitQualifiedName(arg) {
|
|
348
352
|
const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.QualifiedName);
|
|
353
|
+
const hasOwnComments = this.hasPositionedComments(arg) || this.hasLegacyComments(arg);
|
|
349
354
|
if (arg.namespaces) {
|
|
350
355
|
for (let i = 0; i < arg.namespaces.length; i++) {
|
|
351
356
|
token.innerTokens.push(arg.namespaces[i].accept(this));
|
|
@@ -366,7 +371,7 @@ export class SqlPrintTokenParser {
|
|
|
366
371
|
arg.name.positionedComments = originalNameComments;
|
|
367
372
|
arg.name.comments = originalNameLegacyComments;
|
|
368
373
|
// Apply the name's comments to the qualified name token
|
|
369
|
-
if (this.hasPositionedComments(arg.name) || this.hasLegacyComments(arg.name)) {
|
|
374
|
+
if (!hasOwnComments && (this.hasPositionedComments(arg.name) || this.hasLegacyComments(arg.name))) {
|
|
370
375
|
this.addComponentComments(token, arg.name);
|
|
371
376
|
}
|
|
372
377
|
// Also handle any comments directly on the QualifiedName itself
|
|
@@ -387,7 +392,13 @@ export class SqlPrintTokenParser {
|
|
|
387
392
|
for (let i = 0; i < arg.order.length; i++) {
|
|
388
393
|
if (i > 0)
|
|
389
394
|
token.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
|
|
390
|
-
|
|
395
|
+
const item = arg.order[i];
|
|
396
|
+
token.innerTokens.push(this.visit(item));
|
|
397
|
+
if (!(item instanceof OrderByItem) &&
|
|
398
|
+
this.orderByDefaultDirectionStyle === 'explicit') {
|
|
399
|
+
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
400
|
+
token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'asc'));
|
|
401
|
+
}
|
|
391
402
|
}
|
|
392
403
|
return token;
|
|
393
404
|
}
|
|
@@ -416,6 +427,10 @@ export class SqlPrintTokenParser {
|
|
|
416
427
|
token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'nulls last'));
|
|
417
428
|
}
|
|
418
429
|
}
|
|
430
|
+
if (arg.comments && arg.comments.length > 0) {
|
|
431
|
+
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
432
|
+
token.innerTokens.push(...this.createInlineCommentSequence(arg.comments));
|
|
433
|
+
}
|
|
419
434
|
return token;
|
|
420
435
|
}
|
|
421
436
|
parse(arg) {
|
|
@@ -424,7 +439,7 @@ export class SqlPrintTokenParser {
|
|
|
424
439
|
const token = this.visit(arg);
|
|
425
440
|
const paramsRaw = ParameterCollector.collect(arg).sort((a, b) => { var _a, _b; return ((_a = a.index) !== null && _a !== void 0 ? _a : 0) - ((_b = b.index) !== null && _b !== void 0 ? _b : 0); });
|
|
426
441
|
const style = this.parameterDecorator.style;
|
|
427
|
-
if (style === ParameterStyle.Named) {
|
|
442
|
+
if (style === ParameterStyle.Named || style === ParameterStyle.Original) {
|
|
428
443
|
// Named: { name: value, ... }
|
|
429
444
|
const paramsObj = {};
|
|
430
445
|
for (const p of paramsRaw) {
|
|
@@ -894,7 +909,18 @@ export class SqlPrintTokenParser {
|
|
|
894
909
|
}
|
|
895
910
|
visitColumnReference(arg) {
|
|
896
911
|
const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ColumnReference);
|
|
912
|
+
const hasOwnComments = this.hasPositionedComments(arg) || this.hasLegacyComments(arg);
|
|
913
|
+
const originalNamePositionedComments = arg.qualifiedName.name.positionedComments;
|
|
914
|
+
const originalNameComments = arg.qualifiedName.name.comments;
|
|
915
|
+
if (hasOwnComments) {
|
|
916
|
+
arg.qualifiedName.name.positionedComments = null;
|
|
917
|
+
arg.qualifiedName.name.comments = null;
|
|
918
|
+
}
|
|
897
919
|
token.innerTokens.push(arg.qualifiedName.accept(this));
|
|
920
|
+
if (hasOwnComments) {
|
|
921
|
+
arg.qualifiedName.name.positionedComments = originalNamePositionedComments;
|
|
922
|
+
arg.qualifiedName.name.comments = originalNameComments;
|
|
923
|
+
}
|
|
898
924
|
this.addComponentComments(token, arg);
|
|
899
925
|
return token;
|
|
900
926
|
}
|
|
@@ -1060,7 +1086,9 @@ export class SqlPrintTokenParser {
|
|
|
1060
1086
|
visitParameterExpression(arg) {
|
|
1061
1087
|
// Create a parameter token and decorate it using the parameterDecorator
|
|
1062
1088
|
arg.index = this.index;
|
|
1063
|
-
const text = this.parameterDecorator.
|
|
1089
|
+
const text = this.parameterDecorator.style === ParameterStyle.Original && arg.sourceText
|
|
1090
|
+
? arg.sourceText
|
|
1091
|
+
: this.parameterDecorator.decorate(arg.name.value, arg.index);
|
|
1064
1092
|
const token = new SqlPrintToken(SqlPrintTokenType.parameter, text);
|
|
1065
1093
|
this.addComponentComments(token, arg);
|
|
1066
1094
|
this.index++;
|
|
@@ -1166,6 +1194,7 @@ export class SqlPrintTokenParser {
|
|
|
1166
1194
|
return token;
|
|
1167
1195
|
}
|
|
1168
1196
|
visitParenExpression(arg) {
|
|
1197
|
+
var _a, _b;
|
|
1169
1198
|
const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.ParenExpression);
|
|
1170
1199
|
// Handle positioned comments for ParenExpression - check both self and inner expression
|
|
1171
1200
|
const hasOwnComments = arg.positionedComments && arg.positionedComments.length > 0;
|
|
@@ -1178,6 +1207,11 @@ export class SqlPrintTokenParser {
|
|
|
1178
1207
|
innerAfterComments = arg.expression.getPositionedComments('after');
|
|
1179
1208
|
arg.expression.positionedComments = null;
|
|
1180
1209
|
}
|
|
1210
|
+
if (hasOwnComments && innerBeforeComments.length > 0) {
|
|
1211
|
+
const innerBeforeSet = new Set(innerBeforeComments);
|
|
1212
|
+
arg.positionedComments = (_b = (_a = arg.positionedComments) === null || _a === void 0 ? void 0 : _a.map(comment => comment.position === 'after'
|
|
1213
|
+
? Object.assign(Object.assign({}, comment), { comments: comment.comments.filter(value => !innerBeforeSet.has(value)) }) : comment).filter(comment => comment.comments.length > 0)) !== null && _b !== void 0 ? _b : null;
|
|
1214
|
+
}
|
|
1181
1215
|
// Build basic structure first
|
|
1182
1216
|
token.innerTokens.push(SqlPrintTokenParser.PAREN_OPEN_TOKEN);
|
|
1183
1217
|
token.innerTokens.push(this.visit(arg.expression));
|
|
@@ -1231,6 +1265,7 @@ export class SqlPrintTokenParser {
|
|
|
1231
1265
|
const token = new SqlPrintToken(SqlPrintTokenType.container, '', SqlPrintTokenContainerType.CaseExpression);
|
|
1232
1266
|
// Handle positioned comments for CaseExpression (unified spec: positioned comments only)
|
|
1233
1267
|
if (arg.positionedComments && arg.positionedComments.length > 0) {
|
|
1268
|
+
this.removeCaseAfterCommentsDuplicatedOnFirstWhen(arg);
|
|
1234
1269
|
this.addPositionedCommentsToToken(token, arg);
|
|
1235
1270
|
// Clear positioned comments to prevent duplicate processing
|
|
1236
1271
|
arg.positionedComments = null;
|
|
@@ -1243,7 +1278,6 @@ export class SqlPrintTokenParser {
|
|
|
1243
1278
|
promotedComments.push(...this.collectCaseLeadingCommentBlocks(conditionToken));
|
|
1244
1279
|
}
|
|
1245
1280
|
const switchToken = this.visit(arg.switchCase);
|
|
1246
|
-
promotedComments.push(...this.collectCaseLeadingCommentsFromSwitch(switchToken));
|
|
1247
1281
|
if (promotedComments.length > 0) {
|
|
1248
1282
|
token.innerTokens.push(...promotedComments);
|
|
1249
1283
|
}
|
|
@@ -1266,6 +1300,32 @@ export class SqlPrintTokenParser {
|
|
|
1266
1300
|
}
|
|
1267
1301
|
return token;
|
|
1268
1302
|
}
|
|
1303
|
+
removeCaseAfterCommentsDuplicatedOnFirstWhen(arg) {
|
|
1304
|
+
var _a, _b;
|
|
1305
|
+
if (!arg.positionedComments || arg.positionedComments.length === 0) {
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
const firstWhenComments = new Set(((_b = (_a = arg.switchCase.cases[0]) === null || _a === void 0 ? void 0 : _a.getPositionedComments('before')) !== null && _b !== void 0 ? _b : [])
|
|
1309
|
+
.map(comment => this.normalizeCommentSignature(comment)));
|
|
1310
|
+
if (firstWhenComments.size === 0) {
|
|
1311
|
+
return;
|
|
1312
|
+
}
|
|
1313
|
+
const retained = [];
|
|
1314
|
+
for (const entry of arg.positionedComments) {
|
|
1315
|
+
if (entry.position !== 'after') {
|
|
1316
|
+
retained.push(entry);
|
|
1317
|
+
continue;
|
|
1318
|
+
}
|
|
1319
|
+
const comments = entry.comments.filter(comment => !firstWhenComments.has(this.normalizeCommentSignature(comment)));
|
|
1320
|
+
if (comments.length > 0) {
|
|
1321
|
+
retained.push(Object.assign(Object.assign({}, entry), { comments }));
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
arg.positionedComments = retained.length > 0 ? retained : null;
|
|
1325
|
+
}
|
|
1326
|
+
normalizeCommentSignature(comment) {
|
|
1327
|
+
return comment.replace(/\s+/g, ' ').trim();
|
|
1328
|
+
}
|
|
1269
1329
|
extractSwitchAfterComments(arg) {
|
|
1270
1330
|
if (!arg.positionedComments || arg.positionedComments.length === 0) {
|
|
1271
1331
|
return [];
|
|
@@ -1587,11 +1647,13 @@ export class SqlPrintTokenParser {
|
|
|
1587
1647
|
// Add positioned comments in recorded order
|
|
1588
1648
|
const beforeComments = arg.getPositionedComments('before');
|
|
1589
1649
|
const afterComments = arg.getPositionedComments('after');
|
|
1650
|
+
const duplicateCaseAfterComments = arg.value instanceof CaseExpression
|
|
1651
|
+
? this.collectCaseSelectItemDuplicateAfterComments(arg.value)
|
|
1652
|
+
: new Set();
|
|
1590
1653
|
if (beforeComments.length > 0) {
|
|
1591
|
-
if (arg.value instanceof CaseExpression) {
|
|
1654
|
+
if (arg.value instanceof CaseExpression || this.listContinuationCommentComponents.has(arg)) {
|
|
1592
1655
|
const commentBlocks = this.createCommentBlocks(beforeComments);
|
|
1593
1656
|
token.innerTokens.push(...commentBlocks);
|
|
1594
|
-
token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.commentNewline, ''));
|
|
1595
1657
|
}
|
|
1596
1658
|
else {
|
|
1597
1659
|
const commentTokens = this.createInlineCommentSequence(beforeComments);
|
|
@@ -1600,9 +1662,12 @@ export class SqlPrintTokenParser {
|
|
|
1600
1662
|
}
|
|
1601
1663
|
}
|
|
1602
1664
|
token.innerTokens.push(this.visit(arg.value));
|
|
1603
|
-
|
|
1665
|
+
const visibleAfterComments = arg.value instanceof CaseExpression
|
|
1666
|
+
? this.filterCaseSelectItemDuplicateAfterComments(afterComments, duplicateCaseAfterComments)
|
|
1667
|
+
: afterComments;
|
|
1668
|
+
if (visibleAfterComments.length > 0 && !isParenExpression) {
|
|
1604
1669
|
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
1605
|
-
const commentTokens = this.createInlineCommentSequence(
|
|
1670
|
+
const commentTokens = this.createInlineCommentSequence(visibleAfterComments);
|
|
1606
1671
|
token.innerTokens.push(...commentTokens);
|
|
1607
1672
|
}
|
|
1608
1673
|
// Restore original positioned comments to avoid side effects
|
|
@@ -1622,6 +1687,8 @@ export class SqlPrintTokenParser {
|
|
|
1622
1687
|
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
1623
1688
|
// Handle AS keyword positioned comments (before AS)
|
|
1624
1689
|
const asKeywordPositionedComments = 'asKeywordPositionedComments' in arg ? arg.asKeywordPositionedComments : null;
|
|
1690
|
+
const asKeywordComments = 'asKeywordComments' in arg ? arg.asKeywordComments : null;
|
|
1691
|
+
const shouldPrintAsKeyword = this.shouldPrintColumnAliasKeyword(asKeywordPositionedComments, asKeywordComments);
|
|
1625
1692
|
if (asKeywordPositionedComments) {
|
|
1626
1693
|
const beforeComments = asKeywordPositionedComments.filter((pc) => pc.position === 'before');
|
|
1627
1694
|
if (beforeComments.length > 0) {
|
|
@@ -1632,9 +1699,11 @@ export class SqlPrintTokenParser {
|
|
|
1632
1699
|
}
|
|
1633
1700
|
}
|
|
1634
1701
|
}
|
|
1635
|
-
|
|
1702
|
+
if (shouldPrintAsKeyword) {
|
|
1703
|
+
token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'as'));
|
|
1704
|
+
}
|
|
1636
1705
|
// Handle AS keyword positioned comments (after AS)
|
|
1637
|
-
if (asKeywordPositionedComments) {
|
|
1706
|
+
if (shouldPrintAsKeyword && asKeywordPositionedComments) {
|
|
1638
1707
|
const afterComments = asKeywordPositionedComments.filter((pc) => pc.position === 'after');
|
|
1639
1708
|
if (afterComments.length > 0) {
|
|
1640
1709
|
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
@@ -1645,13 +1714,14 @@ export class SqlPrintTokenParser {
|
|
|
1645
1714
|
}
|
|
1646
1715
|
}
|
|
1647
1716
|
// Fallback: Add AS keyword legacy comments if present
|
|
1648
|
-
const asKeywordComments = 'asKeywordComments' in arg ? arg.asKeywordComments : null;
|
|
1649
1717
|
if (asKeywordComments && asKeywordComments.length > 0) {
|
|
1650
1718
|
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
1651
1719
|
const commentTokens = this.createInlineCommentSequence(asKeywordComments);
|
|
1652
1720
|
token.innerTokens.push(...commentTokens);
|
|
1653
1721
|
}
|
|
1654
|
-
|
|
1722
|
+
if (shouldPrintAsKeyword) {
|
|
1723
|
+
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
1724
|
+
}
|
|
1655
1725
|
// Visit identifier to get alias with proper spacing
|
|
1656
1726
|
const identifierToken = this.visit(arg.identifier);
|
|
1657
1727
|
token.innerTokens.push(identifierToken);
|
|
@@ -1676,6 +1746,34 @@ export class SqlPrintTokenParser {
|
|
|
1676
1746
|
}
|
|
1677
1747
|
return token;
|
|
1678
1748
|
}
|
|
1749
|
+
collectCaseSelectItemDuplicateAfterComments(value) {
|
|
1750
|
+
const promoted = new Set();
|
|
1751
|
+
if (value.comments) {
|
|
1752
|
+
for (const comment of value.comments) {
|
|
1753
|
+
promoted.add(comment);
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
const firstCase = value.switchCase.cases[0];
|
|
1757
|
+
if (firstCase === null || firstCase === void 0 ? void 0 : firstCase.positionedComments) {
|
|
1758
|
+
for (const positionedComment of firstCase.positionedComments) {
|
|
1759
|
+
if (positionedComment.position === 'before') {
|
|
1760
|
+
for (const comment of positionedComment.comments) {
|
|
1761
|
+
promoted.add(comment);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
return promoted;
|
|
1767
|
+
}
|
|
1768
|
+
filterCaseSelectItemDuplicateAfterComments(afterComments, promoted) {
|
|
1769
|
+
if (afterComments.length === 0) {
|
|
1770
|
+
return afterComments;
|
|
1771
|
+
}
|
|
1772
|
+
if (promoted.size === 0) {
|
|
1773
|
+
return afterComments;
|
|
1774
|
+
}
|
|
1775
|
+
return afterComments.filter(comment => !promoted.has(comment));
|
|
1776
|
+
}
|
|
1679
1777
|
visitSelectClause(arg) {
|
|
1680
1778
|
const token = new SqlPrintToken(SqlPrintTokenType.keyword, 'select', SqlPrintTokenContainerType.SelectClause);
|
|
1681
1779
|
// Handle positioned comments for SelectClause (unified spec)
|
|
@@ -1711,6 +1809,14 @@ export class SqlPrintTokenParser {
|
|
|
1711
1809
|
for (let i = 0; i < arg.items.length; i++) {
|
|
1712
1810
|
if (i > 0) {
|
|
1713
1811
|
token.innerTokens.push(...SqlPrintTokenParser.commaSpaceTokens());
|
|
1812
|
+
this.listContinuationCommentComponents.add(arg.items[i]);
|
|
1813
|
+
try {
|
|
1814
|
+
token.innerTokens.push(this.visit(arg.items[i]));
|
|
1815
|
+
}
|
|
1816
|
+
finally {
|
|
1817
|
+
this.listContinuationCommentComponents.delete(arg.items[i]);
|
|
1818
|
+
}
|
|
1819
|
+
continue;
|
|
1714
1820
|
}
|
|
1715
1821
|
token.innerTokens.push(this.visit(arg.items[i]));
|
|
1716
1822
|
}
|
|
@@ -1790,12 +1896,23 @@ export class SqlPrintTokenParser {
|
|
|
1790
1896
|
}
|
|
1791
1897
|
}
|
|
1792
1898
|
appendSourceAliasKeyword(token) {
|
|
1793
|
-
if (this.sourceAliasStyle === '
|
|
1899
|
+
if (this.sourceAliasStyle === 'omit') {
|
|
1794
1900
|
return;
|
|
1795
1901
|
}
|
|
1796
1902
|
token.innerTokens.push(new SqlPrintToken(SqlPrintTokenType.keyword, 'as'));
|
|
1797
1903
|
token.innerTokens.push(SqlPrintTokenParser.SPACE_TOKEN);
|
|
1798
1904
|
}
|
|
1905
|
+
shouldPrintColumnAliasKeyword(asKeywordPositionedComments, asKeywordComments) {
|
|
1906
|
+
if (this.columnAliasStyle === 'explicit') {
|
|
1907
|
+
return true;
|
|
1908
|
+
}
|
|
1909
|
+
const hasPositionedComments = Array.isArray(asKeywordPositionedComments) && asKeywordPositionedComments.length > 0;
|
|
1910
|
+
const hasLegacyComments = Array.isArray(asKeywordComments) && asKeywordComments.length > 0;
|
|
1911
|
+
return hasPositionedComments || hasLegacyComments;
|
|
1912
|
+
}
|
|
1913
|
+
normalizeAliasKeywordStyle(style) {
|
|
1914
|
+
return style === 'implicit' || style === 'omit' ? 'omit' : 'explicit';
|
|
1915
|
+
}
|
|
1799
1916
|
visitFromClause(arg) {
|
|
1800
1917
|
// Build a declaration order map so JOIN ON operands can be normalized later.
|
|
1801
1918
|
let contextPushed = false;
|