rawsql-ts 0.11.43-beta → 0.12.0
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 +12 -12
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.min.js +15 -19
- package/dist/esm/index.min.js.map +4 -4
- package/dist/esm/src/index.d.ts +18 -0
- package/dist/esm/src/index.js +18 -0
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/models/BinarySelectQuery.d.ts +25 -1
- package/dist/esm/src/models/BinarySelectQuery.js +28 -0
- package/dist/esm/src/models/BinarySelectQuery.js.map +1 -1
- package/dist/esm/src/models/Clause.d.ts +14 -2
- package/dist/esm/src/models/Clause.js +26 -1
- package/dist/esm/src/models/Clause.js.map +1 -1
- package/dist/esm/src/models/CreateTableQuery.d.ts +99 -5
- package/dist/esm/src/models/CreateTableQuery.js +85 -10
- package/dist/esm/src/models/CreateTableQuery.js.map +1 -1
- package/dist/esm/src/models/DDLStatements.d.ts +195 -0
- package/dist/esm/src/models/DDLStatements.js +201 -0
- package/dist/esm/src/models/DDLStatements.js.map +1 -0
- package/dist/esm/src/models/DeleteQuery.d.ts +17 -0
- package/dist/esm/src/models/DeleteQuery.js +16 -0
- package/dist/esm/src/models/DeleteQuery.js.map +1 -0
- package/dist/esm/src/models/InsertQuery.d.ts +7 -1
- package/dist/esm/src/models/InsertQuery.js +6 -2
- package/dist/esm/src/models/InsertQuery.js.map +1 -1
- package/dist/esm/src/models/MergeQuery.d.ts +63 -0
- package/dist/esm/src/models/MergeQuery.js +94 -0
- package/dist/esm/src/models/MergeQuery.js.map +1 -0
- package/dist/esm/src/models/SelectQuery.d.ts +37 -1
- package/dist/esm/src/models/SelectQuery.js +4 -1
- package/dist/esm/src/models/SelectQuery.js.map +1 -1
- package/dist/esm/src/models/SimpleSelectQuery.d.ts +29 -1
- package/dist/esm/src/models/SimpleSelectQuery.js +32 -0
- package/dist/esm/src/models/SimpleSelectQuery.js.map +1 -1
- package/dist/esm/src/models/SqlComponent.d.ts +2 -1
- package/dist/esm/src/models/SqlComponent.js +1 -1
- package/dist/esm/src/models/SqlComponent.js.map +1 -1
- package/dist/esm/src/models/SqlPrintToken.d.ts +36 -0
- package/dist/esm/src/models/SqlPrintToken.js +35 -0
- package/dist/esm/src/models/SqlPrintToken.js.map +1 -1
- package/dist/esm/src/models/ValuesQuery.d.ts +25 -1
- package/dist/esm/src/models/ValuesQuery.js +28 -0
- package/dist/esm/src/models/ValuesQuery.js.map +1 -1
- package/dist/esm/src/parsers/AlterTableParser.d.ts +25 -0
- package/dist/esm/src/parsers/AlterTableParser.js +428 -0
- package/dist/esm/src/parsers/AlterTableParser.js.map +1 -0
- package/dist/esm/src/parsers/AnalyzeStatementParser.d.ts +13 -0
- package/dist/esm/src/parsers/AnalyzeStatementParser.js +90 -0
- package/dist/esm/src/parsers/AnalyzeStatementParser.js.map +1 -0
- package/dist/esm/src/parsers/CreateIndexParser.d.ts +16 -0
- package/dist/esm/src/parsers/CreateIndexParser.js +237 -0
- package/dist/esm/src/parsers/CreateIndexParser.js.map +1 -0
- package/dist/esm/src/parsers/CreateTableParser.d.ts +41 -0
- package/dist/esm/src/parsers/CreateTableParser.js +734 -0
- package/dist/esm/src/parsers/CreateTableParser.js.map +1 -0
- package/dist/esm/src/parsers/DeleteClauseParser.d.ts +11 -0
- package/dist/esm/src/parsers/DeleteClauseParser.js +33 -0
- package/dist/esm/src/parsers/DeleteClauseParser.js.map +1 -0
- package/dist/esm/src/parsers/DeleteQueryParser.d.ts +16 -0
- package/dist/esm/src/parsers/DeleteQueryParser.js +73 -0
- package/dist/esm/src/parsers/DeleteQueryParser.js.map +1 -0
- package/dist/esm/src/parsers/DropConstraintParser.d.ts +12 -0
- package/dist/esm/src/parsers/DropConstraintParser.js +47 -0
- package/dist/esm/src/parsers/DropConstraintParser.js.map +1 -0
- package/dist/esm/src/parsers/DropIndexParser.d.ts +12 -0
- package/dist/esm/src/parsers/DropIndexParser.js +69 -0
- package/dist/esm/src/parsers/DropIndexParser.js.map +1 -0
- package/dist/esm/src/parsers/DropTableParser.d.ts +12 -0
- package/dist/esm/src/parsers/DropTableParser.js +59 -0
- package/dist/esm/src/parsers/DropTableParser.js.map +1 -0
- package/dist/esm/src/parsers/ExplainStatementParser.d.ts +23 -0
- package/dist/esm/src/parsers/ExplainStatementParser.js +185 -0
- package/dist/esm/src/parsers/ExplainStatementParser.js.map +1 -0
- package/dist/esm/src/parsers/FunctionExpressionParser.d.ts +4 -0
- package/dist/esm/src/parsers/FunctionExpressionParser.js +25 -8
- package/dist/esm/src/parsers/FunctionExpressionParser.js.map +1 -1
- package/dist/esm/src/parsers/InsertQueryParser.js +103 -31
- package/dist/esm/src/parsers/InsertQueryParser.js.map +1 -1
- package/dist/esm/src/parsers/MergeQueryParser.d.ts +26 -0
- package/dist/esm/src/parsers/MergeQueryParser.js +479 -0
- package/dist/esm/src/parsers/MergeQueryParser.js.map +1 -0
- package/dist/esm/src/parsers/ParenExpressionParser.js +25 -0
- package/dist/esm/src/parsers/ParenExpressionParser.js.map +1 -1
- package/dist/esm/src/parsers/ReturningClauseParser.js +50 -7
- package/dist/esm/src/parsers/ReturningClauseParser.js.map +1 -1
- package/dist/esm/src/parsers/SelectClauseParser.js +3 -3
- package/dist/esm/src/parsers/SelectClauseParser.js.map +1 -1
- package/dist/esm/src/parsers/SelectQueryParser.d.ts +4 -0
- package/dist/esm/src/parsers/SelectQueryParser.js +4 -0
- package/dist/esm/src/parsers/SelectQueryParser.js.map +1 -1
- package/dist/esm/src/parsers/SetClauseParser.js +97 -15
- package/dist/esm/src/parsers/SetClauseParser.js.map +1 -1
- package/dist/esm/src/parsers/SqlParser.d.ts +40 -0
- package/dist/esm/src/parsers/SqlParser.js +400 -0
- package/dist/esm/src/parsers/SqlParser.js.map +1 -0
- package/dist/esm/src/parsers/SqlPrintTokenParser.d.ts +65 -3
- package/dist/esm/src/parsers/SqlPrintTokenParser.js +1145 -38
- package/dist/esm/src/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/esm/src/parsers/SqlTokenizer.d.ts +24 -2
- package/dist/esm/src/parsers/SqlTokenizer.js +135 -74
- package/dist/esm/src/parsers/SqlTokenizer.js.map +1 -1
- package/dist/esm/src/parsers/UpdateQueryParser.js +11 -1
- package/dist/esm/src/parsers/UpdateQueryParser.js.map +1 -1
- package/dist/esm/src/parsers/UsingClauseParser.d.ts +11 -0
- package/dist/esm/src/parsers/UsingClauseParser.js +29 -0
- package/dist/esm/src/parsers/UsingClauseParser.js.map +1 -0
- package/dist/esm/src/parsers/ValueParser.js +5 -1
- package/dist/esm/src/parsers/ValueParser.js.map +1 -1
- package/dist/esm/src/parsers/ValuesQueryParser.d.ts +0 -2
- package/dist/esm/src/parsers/ValuesQueryParser.js +5 -45
- package/dist/esm/src/parsers/ValuesQueryParser.js.map +1 -1
- package/dist/esm/src/parsers/utils/LexemeCommentUtils.d.ts +6 -0
- package/dist/esm/src/parsers/utils/LexemeCommentUtils.js +26 -0
- package/dist/esm/src/parsers/utils/LexemeCommentUtils.js.map +1 -0
- package/dist/esm/src/tokenReaders/CommandTokenReader.js +50 -2
- package/dist/esm/src/tokenReaders/CommandTokenReader.js.map +1 -1
- package/dist/esm/src/tokenReaders/LiteralTokenReader.js +8 -5
- package/dist/esm/src/tokenReaders/LiteralTokenReader.js.map +1 -1
- package/dist/esm/src/tokenReaders/OperatorTokenReader.js +10 -1
- package/dist/esm/src/tokenReaders/OperatorTokenReader.js.map +1 -1
- package/dist/esm/src/tokenReaders/TypeTokenReader.js +11 -1
- package/dist/esm/src/tokenReaders/TypeTokenReader.js.map +1 -1
- package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.d.ts +18 -0
- package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js +118 -0
- package/dist/esm/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
- package/dist/esm/src/transformers/LinePrinter.d.ts +1 -0
- package/dist/esm/src/transformers/LinePrinter.js +12 -0
- package/dist/esm/src/transformers/LinePrinter.js.map +1 -1
- package/dist/esm/src/transformers/OnelineFormattingHelper.d.ts +29 -0
- package/dist/esm/src/transformers/OnelineFormattingHelper.js +95 -0
- package/dist/esm/src/transformers/OnelineFormattingHelper.js.map +1 -0
- package/dist/esm/src/transformers/QueryBuilder.d.ts +47 -13
- package/dist/esm/src/transformers/QueryBuilder.js +424 -62
- package/dist/esm/src/transformers/QueryBuilder.js.map +1 -1
- package/dist/esm/src/transformers/SqlFormatter.d.ts +13 -1
- package/dist/esm/src/transformers/SqlFormatter.js +13 -4
- package/dist/esm/src/transformers/SqlFormatter.js.map +1 -1
- package/dist/esm/src/transformers/SqlPrinter.d.ts +47 -8
- package/dist/esm/src/transformers/SqlPrinter.js +625 -72
- package/dist/esm/src/transformers/SqlPrinter.js.map +1 -1
- package/dist/esm/src/types/Formatting.d.ts +8 -0
- package/dist/esm/src/types/Formatting.js +2 -0
- package/dist/esm/src/types/Formatting.js.map +1 -0
- package/dist/esm/src/utils/ParserStringUtils.d.ts +6 -0
- package/dist/esm/src/utils/ParserStringUtils.js +28 -0
- package/dist/esm/src/utils/ParserStringUtils.js.map +1 -0
- package/dist/esm/tsconfig.browser.tsbuildinfo +1 -1
- package/dist/index.min.js +14 -18
- package/dist/index.min.js.map +4 -4
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/models/BinarySelectQuery.d.ts +25 -1
- package/dist/src/models/BinarySelectQuery.js +28 -0
- package/dist/src/models/BinarySelectQuery.js.map +1 -1
- package/dist/src/models/Clause.d.ts +14 -2
- package/dist/src/models/Clause.js +29 -2
- package/dist/src/models/Clause.js.map +1 -1
- package/dist/src/models/CreateTableQuery.d.ts +99 -5
- package/dist/src/models/CreateTableQuery.js +90 -11
- package/dist/src/models/CreateTableQuery.js.map +1 -1
- package/dist/src/models/DDLStatements.d.ts +195 -0
- package/dist/src/models/DDLStatements.js +216 -0
- package/dist/src/models/DDLStatements.js.map +1 -0
- package/dist/src/models/DeleteQuery.d.ts +17 -0
- package/dist/src/models/DeleteQuery.js +20 -0
- package/dist/src/models/DeleteQuery.js.map +1 -0
- package/dist/src/models/InsertQuery.d.ts +7 -1
- package/dist/src/models/InsertQuery.js +6 -2
- package/dist/src/models/InsertQuery.js.map +1 -1
- package/dist/src/models/MergeQuery.d.ts +63 -0
- package/dist/src/models/MergeQuery.js +104 -0
- package/dist/src/models/MergeQuery.js.map +1 -0
- package/dist/src/models/SelectQuery.d.ts +37 -1
- package/dist/src/models/SelectQuery.js +7 -1
- package/dist/src/models/SelectQuery.js.map +1 -1
- package/dist/src/models/SimpleSelectQuery.d.ts +29 -1
- package/dist/src/models/SimpleSelectQuery.js +32 -0
- package/dist/src/models/SimpleSelectQuery.js.map +1 -1
- package/dist/src/models/SqlComponent.d.ts +2 -1
- package/dist/src/models/SqlComponent.js +1 -1
- package/dist/src/models/SqlComponent.js.map +1 -1
- package/dist/src/models/SqlPrintToken.d.ts +36 -0
- package/dist/src/models/SqlPrintToken.js +35 -0
- package/dist/src/models/SqlPrintToken.js.map +1 -1
- package/dist/src/models/ValuesQuery.d.ts +25 -1
- package/dist/src/models/ValuesQuery.js +28 -0
- package/dist/src/models/ValuesQuery.js.map +1 -1
- package/dist/src/parsers/AlterTableParser.d.ts +25 -0
- package/dist/src/parsers/AlterTableParser.js +432 -0
- package/dist/src/parsers/AlterTableParser.js.map +1 -0
- package/dist/src/parsers/AnalyzeStatementParser.d.ts +13 -0
- package/dist/src/parsers/AnalyzeStatementParser.js +94 -0
- package/dist/src/parsers/AnalyzeStatementParser.js.map +1 -0
- package/dist/src/parsers/CreateIndexParser.d.ts +16 -0
- package/dist/src/parsers/CreateIndexParser.js +241 -0
- package/dist/src/parsers/CreateIndexParser.js.map +1 -0
- package/dist/src/parsers/CreateTableParser.d.ts +41 -0
- package/dist/src/parsers/CreateTableParser.js +738 -0
- package/dist/src/parsers/CreateTableParser.js.map +1 -0
- package/dist/src/parsers/DeleteClauseParser.d.ts +11 -0
- package/dist/src/parsers/DeleteClauseParser.js +37 -0
- package/dist/src/parsers/DeleteClauseParser.js.map +1 -0
- package/dist/src/parsers/DeleteQueryParser.d.ts +16 -0
- package/dist/src/parsers/DeleteQueryParser.js +77 -0
- package/dist/src/parsers/DeleteQueryParser.js.map +1 -0
- package/dist/src/parsers/DropConstraintParser.d.ts +12 -0
- package/dist/src/parsers/DropConstraintParser.js +51 -0
- package/dist/src/parsers/DropConstraintParser.js.map +1 -0
- package/dist/src/parsers/DropIndexParser.d.ts +12 -0
- package/dist/src/parsers/DropIndexParser.js +73 -0
- package/dist/src/parsers/DropIndexParser.js.map +1 -0
- package/dist/src/parsers/DropTableParser.d.ts +12 -0
- package/dist/src/parsers/DropTableParser.js +63 -0
- package/dist/src/parsers/DropTableParser.js.map +1 -0
- package/dist/src/parsers/ExplainStatementParser.d.ts +23 -0
- package/dist/src/parsers/ExplainStatementParser.js +189 -0
- package/dist/src/parsers/ExplainStatementParser.js.map +1 -0
- package/dist/src/parsers/FunctionExpressionParser.d.ts +4 -0
- package/dist/src/parsers/FunctionExpressionParser.js +25 -8
- package/dist/src/parsers/FunctionExpressionParser.js.map +1 -1
- package/dist/src/parsers/InsertQueryParser.js +103 -31
- package/dist/src/parsers/InsertQueryParser.js.map +1 -1
- package/dist/src/parsers/MergeQueryParser.d.ts +26 -0
- package/dist/src/parsers/MergeQueryParser.js +483 -0
- package/dist/src/parsers/MergeQueryParser.js.map +1 -0
- package/dist/src/parsers/ParenExpressionParser.js +25 -0
- package/dist/src/parsers/ParenExpressionParser.js.map +1 -1
- package/dist/src/parsers/ReturningClauseParser.js +50 -7
- package/dist/src/parsers/ReturningClauseParser.js.map +1 -1
- package/dist/src/parsers/SelectClauseParser.js +2 -2
- package/dist/src/parsers/SelectClauseParser.js.map +1 -1
- package/dist/src/parsers/SelectQueryParser.d.ts +4 -0
- package/dist/src/parsers/SelectQueryParser.js +4 -0
- package/dist/src/parsers/SelectQueryParser.js.map +1 -1
- package/dist/src/parsers/SetClauseParser.js +97 -15
- package/dist/src/parsers/SetClauseParser.js.map +1 -1
- package/dist/src/parsers/SqlParser.d.ts +40 -0
- package/dist/src/parsers/SqlParser.js +409 -0
- package/dist/src/parsers/SqlParser.js.map +1 -0
- package/dist/src/parsers/SqlPrintTokenParser.d.ts +65 -3
- package/dist/src/parsers/SqlPrintTokenParser.js +1143 -36
- package/dist/src/parsers/SqlPrintTokenParser.js.map +1 -1
- package/dist/src/parsers/SqlTokenizer.d.ts +24 -2
- package/dist/src/parsers/SqlTokenizer.js +139 -74
- package/dist/src/parsers/SqlTokenizer.js.map +1 -1
- package/dist/src/parsers/UpdateQueryParser.js +11 -1
- package/dist/src/parsers/UpdateQueryParser.js.map +1 -1
- package/dist/src/parsers/UsingClauseParser.d.ts +11 -0
- package/dist/src/parsers/UsingClauseParser.js +33 -0
- package/dist/src/parsers/UsingClauseParser.js.map +1 -0
- package/dist/src/parsers/ValueParser.js +5 -1
- package/dist/src/parsers/ValueParser.js.map +1 -1
- package/dist/src/parsers/ValuesQueryParser.d.ts +0 -2
- package/dist/src/parsers/ValuesQueryParser.js +5 -45
- package/dist/src/parsers/ValuesQueryParser.js.map +1 -1
- package/dist/src/parsers/utils/LexemeCommentUtils.d.ts +6 -0
- package/dist/src/parsers/utils/LexemeCommentUtils.js +29 -0
- package/dist/src/parsers/utils/LexemeCommentUtils.js.map +1 -0
- package/dist/src/tokenReaders/CommandTokenReader.js +50 -2
- package/dist/src/tokenReaders/CommandTokenReader.js.map +1 -1
- package/dist/src/tokenReaders/LiteralTokenReader.js +8 -5
- package/dist/src/tokenReaders/LiteralTokenReader.js.map +1 -1
- package/dist/src/tokenReaders/OperatorTokenReader.js +10 -1
- package/dist/src/tokenReaders/OperatorTokenReader.js.map +1 -1
- package/dist/src/tokenReaders/TypeTokenReader.js +11 -1
- package/dist/src/tokenReaders/TypeTokenReader.js.map +1 -1
- package/dist/src/transformers/InsertQuerySelectValuesConverter.d.ts +18 -0
- package/dist/src/transformers/InsertQuerySelectValuesConverter.js +122 -0
- package/dist/src/transformers/InsertQuerySelectValuesConverter.js.map +1 -0
- package/dist/src/transformers/LinePrinter.d.ts +1 -0
- package/dist/src/transformers/LinePrinter.js +12 -0
- package/dist/src/transformers/LinePrinter.js.map +1 -1
- package/dist/src/transformers/OnelineFormattingHelper.d.ts +29 -0
- package/dist/src/transformers/OnelineFormattingHelper.js +99 -0
- package/dist/src/transformers/OnelineFormattingHelper.js.map +1 -0
- package/dist/src/transformers/QueryBuilder.d.ts +47 -13
- package/dist/src/transformers/QueryBuilder.js +433 -60
- package/dist/src/transformers/QueryBuilder.js.map +1 -1
- package/dist/src/transformers/SqlFormatter.d.ts +13 -1
- package/dist/src/transformers/SqlFormatter.js +20 -5
- package/dist/src/transformers/SqlFormatter.js.map +1 -1
- package/dist/src/transformers/SqlPrinter.d.ts +47 -8
- package/dist/src/transformers/SqlPrinter.js +625 -72
- package/dist/src/transformers/SqlPrinter.js.map +1 -1
- package/dist/src/types/Formatting.d.ts +8 -0
- package/dist/src/types/Formatting.js +3 -0
- package/dist/src/types/Formatting.js.map +1 -0
- package/dist/src/utils/ParserStringUtils.d.ts +6 -0
- package/dist/src/utils/ParserStringUtils.js +31 -0
- package/dist/src/utils/ParserStringUtils.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { SqlPrintTokenType, SqlPrintTokenContainerType } from "../models/SqlPrintToken";
|
|
2
2
|
import { LinePrinter } from "./LinePrinter";
|
|
3
3
|
import { resolveIndentCharOption, resolveNewlineOption } from "./FormatOptionResolver";
|
|
4
|
+
import { OnelineFormattingHelper, } from "./OnelineFormattingHelper";
|
|
5
|
+
const CREATE_TABLE_SINGLE_PAREN_KEYWORDS = new Set(['unique', 'check', 'key', 'index']);
|
|
6
|
+
const CREATE_TABLE_MULTI_PAREN_KEYWORDS = new Set(['primary key', 'foreign key', 'unique key']);
|
|
7
|
+
const CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER = new Set(['references']);
|
|
4
8
|
/**
|
|
5
9
|
* SqlPrinter formats a SqlPrintToken tree into a SQL string with flexible style options.
|
|
6
10
|
*
|
|
@@ -26,9 +30,11 @@ export class SqlPrinter {
|
|
|
26
30
|
* @param options Optional style settings for pretty printing
|
|
27
31
|
*/
|
|
28
32
|
constructor(options) {
|
|
29
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
33
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
30
34
|
/** Track whether we are currently inside a WITH clause for full-oneline formatting */
|
|
31
35
|
this.insideWithClause = false;
|
|
36
|
+
/** Tracks nesting depth while formatting MERGE WHEN predicate segments */
|
|
37
|
+
this.mergeWhenPredicateDepth = 0;
|
|
32
38
|
/** Pending line comment that needs a forced newline before next token */
|
|
33
39
|
this.pendingLineCommentBreak = null;
|
|
34
40
|
/** Accumulates lines when reconstructing multi-line block comments inside CommentBlocks */
|
|
@@ -47,19 +53,32 @@ export class SqlPrinter {
|
|
|
47
53
|
this.andBreak = (_e = options === null || options === void 0 ? void 0 : options.andBreak) !== null && _e !== void 0 ? _e : 'none';
|
|
48
54
|
this.orBreak = (_f = options === null || options === void 0 ? void 0 : options.orBreak) !== null && _f !== void 0 ? _f : 'none';
|
|
49
55
|
this.keywordCase = (_g = options === null || options === void 0 ? void 0 : options.keywordCase) !== null && _g !== void 0 ? _g : 'none';
|
|
50
|
-
this.
|
|
51
|
-
this.withClauseStyle = (
|
|
52
|
-
this.commentStyle = (
|
|
53
|
-
this.parenthesesOneLine = (
|
|
54
|
-
this.betweenOneLine = (
|
|
55
|
-
this.valuesOneLine = (
|
|
56
|
-
this.joinOneLine = (
|
|
57
|
-
this.caseOneLine = (
|
|
58
|
-
this.subqueryOneLine = (
|
|
59
|
-
this.indentNestedParentheses = (
|
|
56
|
+
this.commentExportMode = this.resolveCommentExportMode(options === null || options === void 0 ? void 0 : options.exportComment);
|
|
57
|
+
this.withClauseStyle = (_h = options === null || options === void 0 ? void 0 : options.withClauseStyle) !== null && _h !== void 0 ? _h : 'standard';
|
|
58
|
+
this.commentStyle = (_j = options === null || options === void 0 ? void 0 : options.commentStyle) !== null && _j !== void 0 ? _j : 'block';
|
|
59
|
+
this.parenthesesOneLine = (_k = options === null || options === void 0 ? void 0 : options.parenthesesOneLine) !== null && _k !== void 0 ? _k : false;
|
|
60
|
+
this.betweenOneLine = (_l = options === null || options === void 0 ? void 0 : options.betweenOneLine) !== null && _l !== void 0 ? _l : false;
|
|
61
|
+
this.valuesOneLine = (_m = options === null || options === void 0 ? void 0 : options.valuesOneLine) !== null && _m !== void 0 ? _m : false;
|
|
62
|
+
this.joinOneLine = (_o = options === null || options === void 0 ? void 0 : options.joinOneLine) !== null && _o !== void 0 ? _o : false;
|
|
63
|
+
this.caseOneLine = (_p = options === null || options === void 0 ? void 0 : options.caseOneLine) !== null && _p !== void 0 ? _p : false;
|
|
64
|
+
this.subqueryOneLine = (_q = options === null || options === void 0 ? void 0 : options.subqueryOneLine) !== null && _q !== void 0 ? _q : false;
|
|
65
|
+
this.indentNestedParentheses = (_r = options === null || options === void 0 ? void 0 : options.indentNestedParentheses) !== null && _r !== void 0 ? _r : false;
|
|
66
|
+
this.insertColumnsOneLine = (_s = options === null || options === void 0 ? void 0 : options.insertColumnsOneLine) !== null && _s !== void 0 ? _s : false;
|
|
67
|
+
this.whenOneLine = (_t = options === null || options === void 0 ? void 0 : options.whenOneLine) !== null && _t !== void 0 ? _t : false;
|
|
68
|
+
const onelineOptions = {
|
|
69
|
+
parenthesesOneLine: this.parenthesesOneLine,
|
|
70
|
+
betweenOneLine: this.betweenOneLine,
|
|
71
|
+
valuesOneLine: this.valuesOneLine,
|
|
72
|
+
joinOneLine: this.joinOneLine,
|
|
73
|
+
caseOneLine: this.caseOneLine,
|
|
74
|
+
subqueryOneLine: this.subqueryOneLine,
|
|
75
|
+
insertColumnsOneLine: this.insertColumnsOneLine,
|
|
76
|
+
withClauseStyle: this.withClauseStyle,
|
|
77
|
+
};
|
|
78
|
+
this.onelineHelper = new OnelineFormattingHelper(onelineOptions);
|
|
60
79
|
this.linePrinter = new LinePrinter(this.indentChar, this.indentSize, this.newline, this.commaBreak);
|
|
61
80
|
// Initialize
|
|
62
|
-
this.indentIncrementContainers = new Set((
|
|
81
|
+
this.indentIncrementContainers = new Set((_u = options === null || options === void 0 ? void 0 : options.indentIncrementContainerTypes) !== null && _u !== void 0 ? _u : [
|
|
63
82
|
SqlPrintTokenContainerType.SelectClause,
|
|
64
83
|
SqlPrintTokenContainerType.FromClause,
|
|
65
84
|
SqlPrintTokenContainerType.WhereClause,
|
|
@@ -79,7 +98,11 @@ export class SqlPrinter {
|
|
|
79
98
|
SqlPrintTokenContainerType.CaseThenValue,
|
|
80
99
|
SqlPrintTokenContainerType.ElseClause,
|
|
81
100
|
SqlPrintTokenContainerType.CaseElseValue,
|
|
82
|
-
SqlPrintTokenContainerType.SimpleSelectQuery
|
|
101
|
+
SqlPrintTokenContainerType.SimpleSelectQuery,
|
|
102
|
+
SqlPrintTokenContainerType.CreateTableDefinition,
|
|
103
|
+
SqlPrintTokenContainerType.AlterTableStatement,
|
|
104
|
+
SqlPrintTokenContainerType.IndexColumnList,
|
|
105
|
+
SqlPrintTokenContainerType.SetClause
|
|
83
106
|
// Note: CommentBlock is intentionally excluded from indentIncrementContainers
|
|
84
107
|
// because it serves as a grouping mechanism without affecting indentation.
|
|
85
108
|
// CaseExpression, SwitchCaseArgument, CaseKeyValuePair, and ElseClause
|
|
@@ -108,7 +131,42 @@ export class SqlPrinter {
|
|
|
108
131
|
this.appendToken(token, level, undefined, 0, false);
|
|
109
132
|
return this.linePrinter.print();
|
|
110
133
|
}
|
|
111
|
-
|
|
134
|
+
// Resolve legacy boolean values into explicit comment export modes.
|
|
135
|
+
resolveCommentExportMode(option) {
|
|
136
|
+
if (option === undefined) {
|
|
137
|
+
return 'none';
|
|
138
|
+
}
|
|
139
|
+
if (option === true) {
|
|
140
|
+
return 'full';
|
|
141
|
+
}
|
|
142
|
+
if (option === false) {
|
|
143
|
+
return 'none';
|
|
144
|
+
}
|
|
145
|
+
return option;
|
|
146
|
+
}
|
|
147
|
+
// Determine whether the current mode allows emitting inline comments.
|
|
148
|
+
rendersInlineComments() {
|
|
149
|
+
return this.commentExportMode === 'full';
|
|
150
|
+
}
|
|
151
|
+
// Decide if a comment block or token should be rendered given its context.
|
|
152
|
+
shouldRenderComment(token, context) {
|
|
153
|
+
if (context === null || context === void 0 ? void 0 : context.forceRender) {
|
|
154
|
+
return this.commentExportMode !== 'none';
|
|
155
|
+
}
|
|
156
|
+
switch (this.commentExportMode) {
|
|
157
|
+
case 'full':
|
|
158
|
+
return true;
|
|
159
|
+
case 'none':
|
|
160
|
+
return false;
|
|
161
|
+
case 'header-only':
|
|
162
|
+
return token.isHeaderComment === true;
|
|
163
|
+
case 'top-header-only':
|
|
164
|
+
return token.isHeaderComment === true && Boolean(context === null || context === void 0 ? void 0 : context.isTopLevelContainer);
|
|
165
|
+
default:
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
appendToken(token, level, parentContainerType, caseContextDepth = 0, indentParentActive = false, commentContext) {
|
|
112
170
|
// Track WITH clause context for full-oneline formatting
|
|
113
171
|
const wasInsideWithClause = this.insideWithClause;
|
|
114
172
|
if (token.containerType === SqlPrintTokenContainerType.WithClause && this.withClauseStyle === 'full-oneline') {
|
|
@@ -117,6 +175,45 @@ export class SqlPrinter {
|
|
|
117
175
|
if (this.shouldSkipToken(token)) {
|
|
118
176
|
return;
|
|
119
177
|
}
|
|
178
|
+
const containerIsTopLevel = parentContainerType === undefined;
|
|
179
|
+
let leadingCommentCount = 0;
|
|
180
|
+
// Collect leading comment blocks with context so we can respect the export mode.
|
|
181
|
+
const leadingCommentContexts = [];
|
|
182
|
+
if (token.innerTokens && token.innerTokens.length > 0) {
|
|
183
|
+
while (leadingCommentCount < token.innerTokens.length) {
|
|
184
|
+
const leadingCandidate = token.innerTokens[leadingCommentCount];
|
|
185
|
+
if (leadingCandidate.containerType !== SqlPrintTokenContainerType.CommentBlock) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
const context = {
|
|
189
|
+
position: 'leading',
|
|
190
|
+
isTopLevelContainer: containerIsTopLevel,
|
|
191
|
+
};
|
|
192
|
+
const shouldRender = this.shouldRenderComment(leadingCandidate, context);
|
|
193
|
+
leadingCommentContexts.push({ token: leadingCandidate, context, shouldRender });
|
|
194
|
+
leadingCommentCount++;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
const hasRenderableLeadingComment = leadingCommentContexts.some(item => item.shouldRender);
|
|
198
|
+
const leadingCommentIndentLevel = hasRenderableLeadingComment
|
|
199
|
+
? this.getLeadingCommentIndentLevel(parentContainerType, level)
|
|
200
|
+
: null;
|
|
201
|
+
if (hasRenderableLeadingComment
|
|
202
|
+
&& !this.isOnelineMode()
|
|
203
|
+
&& this.shouldAddNewlineBeforeLeadingComments(parentContainerType)) {
|
|
204
|
+
const currentLine = this.linePrinter.getCurrentLine();
|
|
205
|
+
if (currentLine.text.trim().length > 0) {
|
|
206
|
+
// Align the newline before leading comments with the intended comment indentation.
|
|
207
|
+
this.linePrinter.appendNewline(leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
for (const leading of leadingCommentContexts) {
|
|
211
|
+
if (!leading.shouldRender) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
// Keep leading comment processing aligned with its computed indentation level.
|
|
215
|
+
this.appendToken(leading.token, leadingCommentIndentLevel !== null && leadingCommentIndentLevel !== void 0 ? leadingCommentIndentLevel : level, token.containerType, caseContextDepth, indentParentActive, leading.context);
|
|
216
|
+
}
|
|
120
217
|
if (this.smartCommentBlockBuilder && token.containerType !== SqlPrintTokenContainerType.CommentBlock && token.type !== SqlPrintTokenType.commentNewline) {
|
|
121
218
|
this.flushSmartCommentBlockBuilder();
|
|
122
219
|
}
|
|
@@ -130,8 +227,17 @@ export class SqlPrinter {
|
|
|
130
227
|
return;
|
|
131
228
|
}
|
|
132
229
|
}
|
|
230
|
+
// Fallback context applies when the caller did not provide comment metadata.
|
|
231
|
+
const effectiveCommentContext = commentContext !== null && commentContext !== void 0 ? commentContext : {
|
|
232
|
+
position: 'inline',
|
|
233
|
+
isTopLevelContainer: containerIsTopLevel,
|
|
234
|
+
};
|
|
133
235
|
if (token.containerType === SqlPrintTokenContainerType.CommentBlock) {
|
|
134
|
-
this.
|
|
236
|
+
if (!this.shouldRenderComment(token, effectiveCommentContext)) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
|
|
240
|
+
this.handleCommentBlockContainer(token, commentLevel, effectiveCommentContext);
|
|
135
241
|
return;
|
|
136
242
|
}
|
|
137
243
|
const current = this.linePrinter.getCurrentLine();
|
|
@@ -146,7 +252,7 @@ export class SqlPrinter {
|
|
|
146
252
|
this.handleCommaToken(token, level, parentContainerType);
|
|
147
253
|
}
|
|
148
254
|
else if (token.type === SqlPrintTokenType.parenthesis) {
|
|
149
|
-
this.handleParenthesisToken(token, level, indentParentActive);
|
|
255
|
+
this.handleParenthesisToken(token, level, indentParentActive, parentContainerType);
|
|
150
256
|
}
|
|
151
257
|
else if (token.type === SqlPrintTokenType.operator && token.text.toLowerCase() === 'and') {
|
|
152
258
|
this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
|
|
@@ -154,34 +260,34 @@ export class SqlPrinter {
|
|
|
154
260
|
else if (token.type === SqlPrintTokenType.operator && token.text.toLowerCase() === 'or') {
|
|
155
261
|
this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
|
|
156
262
|
}
|
|
157
|
-
else if (token.containerType ===
|
|
263
|
+
else if (token.containerType === SqlPrintTokenContainerType.JoinClause) {
|
|
158
264
|
this.handleJoinClauseToken(token, level);
|
|
159
265
|
}
|
|
160
266
|
else if (token.type === SqlPrintTokenType.comment) {
|
|
161
|
-
if (this.
|
|
162
|
-
this.
|
|
267
|
+
if (this.shouldRenderComment(token, effectiveCommentContext)) {
|
|
268
|
+
const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
|
|
269
|
+
this.printCommentToken(token.text, commentLevel, parentContainerType);
|
|
163
270
|
}
|
|
164
271
|
}
|
|
165
272
|
else if (token.type === SqlPrintTokenType.space) {
|
|
166
273
|
this.handleSpaceToken(token, parentContainerType);
|
|
167
274
|
}
|
|
168
275
|
else if (token.type === SqlPrintTokenType.commentNewline) {
|
|
169
|
-
this.
|
|
276
|
+
if (this.whenOneLine && parentContainerType === SqlPrintTokenContainerType.MergeWhenClause) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const commentLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
|
|
280
|
+
this.handleCommentNewlineToken(token, commentLevel);
|
|
170
281
|
}
|
|
171
282
|
else if (token.containerType === SqlPrintTokenContainerType.CommonTable && this.withClauseStyle === 'cte-oneline') {
|
|
172
283
|
this.handleCteOnelineToken(token, level);
|
|
173
284
|
return; // Return early to avoid processing innerTokens
|
|
174
285
|
}
|
|
175
|
-
else if ((token
|
|
176
|
-
(token.containerType === SqlPrintTokenContainerType.BetweenExpression && this.betweenOneLine) ||
|
|
177
|
-
(token.containerType === SqlPrintTokenContainerType.Values && this.valuesOneLine) ||
|
|
178
|
-
(token.containerType === SqlPrintTokenContainerType.JoinOnClause && this.joinOneLine) ||
|
|
179
|
-
(token.containerType === SqlPrintTokenContainerType.CaseExpression && this.caseOneLine) ||
|
|
180
|
-
(token.containerType === SqlPrintTokenContainerType.InlineQuery && this.subqueryOneLine)) {
|
|
286
|
+
else if (this.shouldFormatContainerAsOneline(token, shouldIndentNested)) {
|
|
181
287
|
this.handleOnelineToken(token, level);
|
|
182
288
|
return; // Return early to avoid processing innerTokens
|
|
183
289
|
}
|
|
184
|
-
else {
|
|
290
|
+
else if (!this.tryAppendInsertClauseTokenText(token.text, parentContainerType)) {
|
|
185
291
|
this.linePrinter.appendText(token.text);
|
|
186
292
|
}
|
|
187
293
|
// append keyword tokens(not indented)
|
|
@@ -195,7 +301,18 @@ export class SqlPrinter {
|
|
|
195
301
|
let increasedIndent = false;
|
|
196
302
|
const shouldIncreaseIndent = this.indentIncrementContainers.has(token.containerType) || shouldIndentNested;
|
|
197
303
|
const delayIndentNewline = shouldIndentNested && token.containerType === SqlPrintTokenContainerType.ParenExpression;
|
|
198
|
-
|
|
304
|
+
const isAlterTableStatement = token.containerType === SqlPrintTokenContainerType.AlterTableStatement;
|
|
305
|
+
let deferAlterTableIndent = false;
|
|
306
|
+
const alignExplainChild = this.shouldAlignExplainStatementChild(parentContainerType, token.containerType);
|
|
307
|
+
if (alignExplainChild) {
|
|
308
|
+
// Keep EXPLAIN target statements flush left so they render like standalone statements.
|
|
309
|
+
if (!this.isOnelineMode() && current.text !== '') {
|
|
310
|
+
this.linePrinter.appendNewline(level);
|
|
311
|
+
}
|
|
312
|
+
innerLevel = level;
|
|
313
|
+
increasedIndent = false;
|
|
314
|
+
}
|
|
315
|
+
else if (!this.isOnelineMode() && shouldIncreaseIndent) {
|
|
199
316
|
if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
|
|
200
317
|
// Keep everything on one line for full-oneline WITH clauses.
|
|
201
318
|
}
|
|
@@ -204,15 +321,96 @@ export class SqlPrinter {
|
|
|
204
321
|
increasedIndent = true;
|
|
205
322
|
}
|
|
206
323
|
else if (current.text !== '') {
|
|
207
|
-
|
|
324
|
+
if (isAlterTableStatement) {
|
|
325
|
+
// Delay the first line break so ALTER TABLE keeps the table name on the opening line.
|
|
326
|
+
innerLevel = level + 1;
|
|
327
|
+
increasedIndent = true;
|
|
328
|
+
deferAlterTableIndent = true;
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
let targetIndentLevel = level + 1;
|
|
332
|
+
if (token.containerType === SqlPrintTokenContainerType.SetClause &&
|
|
333
|
+
parentContainerType === SqlPrintTokenContainerType.MergeUpdateAction) {
|
|
334
|
+
targetIndentLevel = level + 2;
|
|
335
|
+
}
|
|
336
|
+
if (this.shouldAlignCreateTableSelect(token.containerType, parentContainerType)) {
|
|
337
|
+
innerLevel = level;
|
|
338
|
+
increasedIndent = false;
|
|
339
|
+
this.linePrinter.appendNewline(level);
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
innerLevel = targetIndentLevel;
|
|
343
|
+
increasedIndent = true;
|
|
344
|
+
this.linePrinter.appendNewline(innerLevel);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
else if (token.containerType === SqlPrintTokenContainerType.SetClause) {
|
|
349
|
+
innerLevel = parentContainerType === SqlPrintTokenContainerType.MergeUpdateAction ? level + 2 : level + 1;
|
|
208
350
|
increasedIndent = true;
|
|
209
|
-
|
|
351
|
+
current.level = innerLevel;
|
|
210
352
|
}
|
|
211
353
|
}
|
|
212
|
-
|
|
354
|
+
const isMergeWhenClause = this.whenOneLine && token.containerType === SqlPrintTokenContainerType.MergeWhenClause;
|
|
355
|
+
let mergePredicateActive = isMergeWhenClause;
|
|
356
|
+
let alterTableTableRendered = false;
|
|
357
|
+
let alterTableIndentInserted = false;
|
|
358
|
+
for (let i = leadingCommentCount; i < token.innerTokens.length; i++) {
|
|
213
359
|
const child = token.innerTokens[i];
|
|
360
|
+
const nextChild = token.innerTokens[i + 1];
|
|
361
|
+
const previousEntry = this.findPreviousSignificantToken(token.innerTokens, i);
|
|
362
|
+
const previousChild = previousEntry === null || previousEntry === void 0 ? void 0 : previousEntry.token;
|
|
363
|
+
const priorEntry = previousEntry ? this.findPreviousSignificantToken(token.innerTokens, previousEntry.index) : undefined;
|
|
364
|
+
const priorChild = priorEntry === null || priorEntry === void 0 ? void 0 : priorEntry.token;
|
|
365
|
+
const childIsAction = this.isMergeActionContainer(child);
|
|
366
|
+
const nextIsAction = this.isMergeActionContainer(nextChild);
|
|
367
|
+
const inMergePredicate = mergePredicateActive && !childIsAction;
|
|
368
|
+
if (isAlterTableStatement) {
|
|
369
|
+
if (child.containerType === SqlPrintTokenContainerType.QualifiedName) {
|
|
370
|
+
// Track when the table name has been printed so we can defer indentation until after it.
|
|
371
|
+
alterTableTableRendered = true;
|
|
372
|
+
}
|
|
373
|
+
else if (deferAlterTableIndent && alterTableTableRendered && !alterTableIndentInserted) {
|
|
374
|
+
if (!this.isOnelineMode()) {
|
|
375
|
+
this.linePrinter.appendNewline(innerLevel);
|
|
376
|
+
}
|
|
377
|
+
alterTableIndentInserted = true;
|
|
378
|
+
deferAlterTableIndent = false;
|
|
379
|
+
if (!this.isOnelineMode() && child.type === SqlPrintTokenType.space) {
|
|
380
|
+
// Drop the space token because we already emitted a newline.
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (child.type === SqlPrintTokenType.space) {
|
|
386
|
+
if (this.shouldConvertSpaceToClauseBreak(token.containerType, nextChild)) {
|
|
387
|
+
if (!this.isOnelineMode()) {
|
|
388
|
+
// Use a dedicated indent resolver so clause breaks can shift indentation for nested blocks.
|
|
389
|
+
const clauseBreakIndent = this.getClauseBreakIndentLevel(token.containerType, innerLevel);
|
|
390
|
+
this.linePrinter.appendNewline(clauseBreakIndent);
|
|
391
|
+
}
|
|
392
|
+
if (isMergeWhenClause && nextIsAction) {
|
|
393
|
+
mergePredicateActive = false;
|
|
394
|
+
}
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
this.handleSpaceToken(child, token.containerType, nextChild, previousChild, priorChild);
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
214
400
|
const childIndentParentActive = token.containerType === SqlPrintTokenContainerType.ParenExpression ? shouldIndentNested : indentParentActive;
|
|
215
|
-
|
|
401
|
+
if (inMergePredicate) {
|
|
402
|
+
this.mergeWhenPredicateDepth++;
|
|
403
|
+
}
|
|
404
|
+
const childCommentContext = child.containerType === SqlPrintTokenContainerType.CommentBlock
|
|
405
|
+
? { position: 'inline', isTopLevelContainer: containerIsTopLevel }
|
|
406
|
+
: undefined;
|
|
407
|
+
this.appendToken(child, innerLevel, token.containerType, nextCaseContextDepth, childIndentParentActive, childCommentContext);
|
|
408
|
+
if (inMergePredicate) {
|
|
409
|
+
this.mergeWhenPredicateDepth--;
|
|
410
|
+
}
|
|
411
|
+
if (childIsAction && isMergeWhenClause) {
|
|
412
|
+
mergePredicateActive = false;
|
|
413
|
+
}
|
|
216
414
|
}
|
|
217
415
|
if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
|
|
218
416
|
this.flushSmartCommentBlockBuilder();
|
|
@@ -229,6 +427,21 @@ export class SqlPrinter {
|
|
|
229
427
|
this.linePrinter.appendNewline(level);
|
|
230
428
|
}
|
|
231
429
|
}
|
|
430
|
+
shouldAlignExplainStatementChild(parentType, childType) {
|
|
431
|
+
if (parentType !== SqlPrintTokenContainerType.ExplainStatement) {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
switch (childType) {
|
|
435
|
+
case SqlPrintTokenContainerType.SimpleSelectQuery:
|
|
436
|
+
case SqlPrintTokenContainerType.InsertQuery:
|
|
437
|
+
case SqlPrintTokenContainerType.UpdateQuery:
|
|
438
|
+
case SqlPrintTokenContainerType.DeleteQuery:
|
|
439
|
+
case SqlPrintTokenContainerType.MergeQuery:
|
|
440
|
+
return true;
|
|
441
|
+
default:
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
232
445
|
isCaseContext(containerType) {
|
|
233
446
|
switch (containerType) {
|
|
234
447
|
case SqlPrintTokenContainerType.CaseExpression:
|
|
@@ -265,11 +478,13 @@ export class SqlPrinter {
|
|
|
265
478
|
}
|
|
266
479
|
handleKeywordToken(token, level, parentContainerType, caseContextDepth = 0) {
|
|
267
480
|
const lower = token.text.toLowerCase();
|
|
268
|
-
if (lower === 'and' &&
|
|
481
|
+
if (lower === 'and' &&
|
|
482
|
+
(this.andBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintTokenContainerType.MergeWhenClause))) {
|
|
269
483
|
this.handleAndOperatorToken(token, level, parentContainerType, caseContextDepth);
|
|
270
484
|
return;
|
|
271
485
|
}
|
|
272
|
-
else if (lower === 'or' &&
|
|
486
|
+
else if (lower === 'or' &&
|
|
487
|
+
(this.orBreak !== 'none' || (this.whenOneLine && parentContainerType === SqlPrintTokenContainerType.MergeWhenClause))) {
|
|
273
488
|
this.handleOrOperatorToken(token, level, parentContainerType, caseContextDepth);
|
|
274
489
|
return;
|
|
275
490
|
}
|
|
@@ -278,18 +493,50 @@ export class SqlPrinter {
|
|
|
278
493
|
this.linePrinter.appendText(text);
|
|
279
494
|
return;
|
|
280
495
|
}
|
|
496
|
+
this.ensureSpaceBeforeKeyword();
|
|
281
497
|
this.linePrinter.appendText(text);
|
|
282
498
|
}
|
|
499
|
+
ensureSpaceBeforeKeyword() {
|
|
500
|
+
const currentLine = this.linePrinter.getCurrentLine();
|
|
501
|
+
if (currentLine.text === '') {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
const lastChar = currentLine.text[currentLine.text.length - 1];
|
|
505
|
+
if (lastChar === '(') {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
this.ensureTrailingSpace();
|
|
509
|
+
}
|
|
510
|
+
ensureTrailingSpace() {
|
|
511
|
+
const currentLine = this.linePrinter.getCurrentLine();
|
|
512
|
+
if (currentLine.text === '') {
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (!currentLine.text.endsWith(' ')) {
|
|
516
|
+
currentLine.text += ' ';
|
|
517
|
+
}
|
|
518
|
+
currentLine.text = currentLine.text.replace(/\s+$/, ' ');
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Normalizes INSERT column list token text when one-line formatting is active.
|
|
522
|
+
*/
|
|
523
|
+
tryAppendInsertClauseTokenText(text, parentContainerType) {
|
|
524
|
+
const currentLineText = this.linePrinter.getCurrentLine().text;
|
|
525
|
+
const result = this.onelineHelper.formatInsertClauseToken(text, parentContainerType, currentLineText, () => this.ensureTrailingSpace());
|
|
526
|
+
if (!result.handled) {
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
if (result.text) {
|
|
530
|
+
this.linePrinter.appendText(result.text);
|
|
531
|
+
}
|
|
532
|
+
return true;
|
|
533
|
+
}
|
|
283
534
|
handleCommaToken(token, level, parentContainerType) {
|
|
284
535
|
const text = token.text;
|
|
285
536
|
const isWithinWithClause = parentContainerType === SqlPrintTokenContainerType.WithClause;
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
effectiveCommaBreak = this.cteCommaBreak;
|
|
290
|
-
}
|
|
291
|
-
else if (isWithinValuesClause) {
|
|
292
|
-
effectiveCommaBreak = this.valuesCommaBreak;
|
|
537
|
+
let effectiveCommaBreak = this.onelineHelper.resolveCommaBreak(parentContainerType, this.commaBreak, this.cteCommaBreak, this.valuesCommaBreak);
|
|
538
|
+
if (parentContainerType === SqlPrintTokenContainerType.SetClause) {
|
|
539
|
+
effectiveCommaBreak = 'before';
|
|
293
540
|
}
|
|
294
541
|
// Skip comma newlines when inside WITH clause with full-oneline style
|
|
295
542
|
if (this.insideWithClause && this.withClauseStyle === 'full-oneline') {
|
|
@@ -307,6 +554,14 @@ export class SqlPrinter {
|
|
|
307
554
|
}
|
|
308
555
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
309
556
|
this.linePrinter.appendNewline(level);
|
|
557
|
+
if (this.newline === ' ') {
|
|
558
|
+
// Remove the spacer introduced by space newlines so commas attach directly to the preceding token.
|
|
559
|
+
this.linePrinter.trimTrailingWhitespaceFromPreviousLine();
|
|
560
|
+
}
|
|
561
|
+
if (parentContainerType === SqlPrintTokenContainerType.InsertClause) {
|
|
562
|
+
// Align comma-prefixed column entries under the INSERT column indentation.
|
|
563
|
+
this.linePrinter.getCurrentLine().level = level + 1;
|
|
564
|
+
}
|
|
310
565
|
}
|
|
311
566
|
this.linePrinter.appendText(text);
|
|
312
567
|
if (previousCommaBreak !== 'before') {
|
|
@@ -335,6 +590,9 @@ export class SqlPrinter {
|
|
|
335
590
|
this.linePrinter.commaBreak = 'none';
|
|
336
591
|
}
|
|
337
592
|
this.linePrinter.appendText(text);
|
|
593
|
+
if (this.onelineHelper.isInsertClauseOneline(parentContainerType)) {
|
|
594
|
+
this.ensureTrailingSpace();
|
|
595
|
+
}
|
|
338
596
|
if (previousCommaBreak !== 'none') {
|
|
339
597
|
this.linePrinter.commaBreak = previousCommaBreak;
|
|
340
598
|
}
|
|
@@ -349,6 +607,11 @@ export class SqlPrinter {
|
|
|
349
607
|
this.linePrinter.appendText(text);
|
|
350
608
|
return;
|
|
351
609
|
}
|
|
610
|
+
if (this.whenOneLine &&
|
|
611
|
+
(parentContainerType === SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
|
|
612
|
+
this.linePrinter.appendText(text);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
352
615
|
if (this.andBreak === 'before') {
|
|
353
616
|
// Skip newline when inside WITH clause with full-oneline style
|
|
354
617
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
@@ -367,20 +630,32 @@ export class SqlPrinter {
|
|
|
367
630
|
this.linePrinter.appendText(text);
|
|
368
631
|
}
|
|
369
632
|
}
|
|
370
|
-
handleParenthesisToken(token, level, indentParentActive) {
|
|
633
|
+
handleParenthesisToken(token, level, indentParentActive, parentContainerType) {
|
|
371
634
|
if (token.text === '(') {
|
|
372
635
|
this.linePrinter.appendText(token.text);
|
|
373
|
-
if (
|
|
374
|
-
|
|
636
|
+
if ((parentContainerType === SqlPrintTokenContainerType.InsertClause ||
|
|
637
|
+
parentContainerType === SqlPrintTokenContainerType.MergeInsertAction) &&
|
|
638
|
+
this.insertColumnsOneLine) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
if (!this.isOnelineMode()) {
|
|
642
|
+
if (this.shouldBreakAfterOpeningParen(parentContainerType)) {
|
|
643
|
+
this.linePrinter.appendNewline(level + 1);
|
|
644
|
+
}
|
|
645
|
+
else if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
375
646
|
this.linePrinter.appendNewline(level);
|
|
376
647
|
}
|
|
377
648
|
}
|
|
378
649
|
return;
|
|
379
650
|
}
|
|
380
|
-
if (token.text === ')' &&
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
651
|
+
if (token.text === ')' && !this.isOnelineMode()) {
|
|
652
|
+
if (this.shouldBreakBeforeClosingParen(parentContainerType)) {
|
|
653
|
+
this.linePrinter.appendNewline(Math.max(level, 0));
|
|
654
|
+
this.linePrinter.appendText(token.text);
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
if (indentParentActive && !(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
658
|
+
const closingLevel = Math.max(level - 1, 0);
|
|
384
659
|
this.linePrinter.appendNewline(closingLevel);
|
|
385
660
|
}
|
|
386
661
|
}
|
|
@@ -393,6 +668,11 @@ export class SqlPrinter {
|
|
|
393
668
|
this.linePrinter.appendText(text);
|
|
394
669
|
return;
|
|
395
670
|
}
|
|
671
|
+
if (this.whenOneLine &&
|
|
672
|
+
(parentContainerType === SqlPrintTokenContainerType.MergeWhenClause || this.mergeWhenPredicateDepth > 0)) {
|
|
673
|
+
this.linePrinter.appendText(text);
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
396
676
|
if (this.orBreak === 'before') {
|
|
397
677
|
// Insert a newline before OR unless WITH full-oneline mode suppresses breaks.
|
|
398
678
|
if (!(this.insideWithClause && this.withClauseStyle === 'full-oneline')) {
|
|
@@ -442,37 +722,140 @@ export class SqlPrinter {
|
|
|
442
722
|
}
|
|
443
723
|
handleJoinClauseToken(token, level) {
|
|
444
724
|
const text = this.applyKeywordCase(token.text);
|
|
445
|
-
// before join clause, add newline
|
|
446
|
-
if (
|
|
725
|
+
// before join clause, add newline when multiline formatting is allowed
|
|
726
|
+
if (this.onelineHelper.shouldInsertJoinNewline(this.insideWithClause)) {
|
|
447
727
|
this.linePrinter.appendNewline(level);
|
|
448
728
|
}
|
|
449
729
|
this.linePrinter.appendText(text);
|
|
450
730
|
}
|
|
731
|
+
/**
|
|
732
|
+
* Decides whether the current container should collapse into a single line.
|
|
733
|
+
*/
|
|
734
|
+
shouldFormatContainerAsOneline(token, shouldIndentNested) {
|
|
735
|
+
return this.onelineHelper.shouldFormatContainer(token, shouldIndentNested);
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Detects an INSERT column list that must stay on a single line.
|
|
739
|
+
*/
|
|
740
|
+
isInsertClauseOneline(parentContainerType) {
|
|
741
|
+
return this.onelineHelper.isInsertClauseOneline(parentContainerType);
|
|
742
|
+
}
|
|
451
743
|
/**
|
|
452
744
|
* Handles space tokens with context-aware filtering.
|
|
453
745
|
* Skips spaces in CommentBlocks when in specific CTE modes to prevent duplication.
|
|
454
746
|
*/
|
|
455
|
-
handleSpaceToken(token, parentContainerType) {
|
|
747
|
+
handleSpaceToken(token, parentContainerType, nextToken, previousToken, priorToken) {
|
|
456
748
|
if (this.smartCommentBlockBuilder && this.smartCommentBlockBuilder.mode === 'line') {
|
|
457
749
|
this.flushSmartCommentBlockBuilder();
|
|
458
750
|
}
|
|
459
|
-
|
|
751
|
+
const currentLineText = this.linePrinter.getCurrentLine().text;
|
|
752
|
+
if (this.onelineHelper.shouldSkipInsertClauseSpace(parentContainerType, nextToken, currentLineText)) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (this.onelineHelper.shouldSkipCommentBlockSpace(parentContainerType, this.insideWithClause)) {
|
|
460
756
|
const currentLine = this.linePrinter.getCurrentLine();
|
|
461
757
|
if (currentLine.text !== '' && !currentLine.text.endsWith(' ')) {
|
|
462
758
|
this.linePrinter.appendText(' ');
|
|
463
759
|
}
|
|
464
760
|
return;
|
|
465
761
|
}
|
|
762
|
+
// Skip redundant spaces before structural parentheses in CREATE TABLE DDL.
|
|
763
|
+
if (this.shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken)) {
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
466
766
|
this.linePrinter.appendText(token.text);
|
|
467
767
|
}
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
this.
|
|
475
|
-
|
|
768
|
+
findPreviousSignificantToken(tokens, index) {
|
|
769
|
+
for (let i = index - 1; i >= 0; i--) {
|
|
770
|
+
const candidate = tokens[i];
|
|
771
|
+
if (candidate.type === SqlPrintTokenType.space || candidate.type === SqlPrintTokenType.commentNewline) {
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
if (candidate.type === SqlPrintTokenType.comment && !this.rendersInlineComments()) {
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
return { token: candidate, index: i };
|
|
778
|
+
}
|
|
779
|
+
return undefined;
|
|
780
|
+
}
|
|
781
|
+
shouldSkipSpaceBeforeParenthesis(parentContainerType, nextToken, previousToken, priorToken) {
|
|
782
|
+
if (!nextToken || nextToken.type !== SqlPrintTokenType.parenthesis || nextToken.text !== '(') {
|
|
783
|
+
return false;
|
|
784
|
+
}
|
|
785
|
+
if (!parentContainerType || !this.isCreateTableSpacingContext(parentContainerType)) {
|
|
786
|
+
return false;
|
|
787
|
+
}
|
|
788
|
+
if (!previousToken) {
|
|
789
|
+
return false;
|
|
790
|
+
}
|
|
791
|
+
if (this.isCreateTableNameToken(previousToken, parentContainerType)) {
|
|
792
|
+
return true;
|
|
793
|
+
}
|
|
794
|
+
if (this.isCreateTableConstraintKeyword(previousToken, parentContainerType)) {
|
|
795
|
+
return true;
|
|
796
|
+
}
|
|
797
|
+
if (priorToken && this.isCreateTableConstraintKeyword(priorToken, parentContainerType)) {
|
|
798
|
+
if (this.isIdentifierAttachedToConstraint(previousToken, priorToken, parentContainerType)) {
|
|
799
|
+
return true;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
return false;
|
|
803
|
+
}
|
|
804
|
+
shouldAlignCreateTableSelect(containerType, parentContainerType) {
|
|
805
|
+
return containerType === SqlPrintTokenContainerType.SimpleSelectQuery &&
|
|
806
|
+
parentContainerType === SqlPrintTokenContainerType.CreateTableQuery;
|
|
807
|
+
}
|
|
808
|
+
isCreateTableSpacingContext(parentContainerType) {
|
|
809
|
+
switch (parentContainerType) {
|
|
810
|
+
case SqlPrintTokenContainerType.CreateTableQuery:
|
|
811
|
+
case SqlPrintTokenContainerType.CreateTableDefinition:
|
|
812
|
+
case SqlPrintTokenContainerType.TableConstraintDefinition:
|
|
813
|
+
case SqlPrintTokenContainerType.ColumnConstraintDefinition:
|
|
814
|
+
case SqlPrintTokenContainerType.ReferenceDefinition:
|
|
815
|
+
return true;
|
|
816
|
+
default:
|
|
817
|
+
return false;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
isCreateTableNameToken(previousToken, parentContainerType) {
|
|
821
|
+
if (parentContainerType !== SqlPrintTokenContainerType.CreateTableQuery) {
|
|
822
|
+
return false;
|
|
823
|
+
}
|
|
824
|
+
return previousToken.containerType === SqlPrintTokenContainerType.QualifiedName;
|
|
825
|
+
}
|
|
826
|
+
isCreateTableConstraintKeyword(token, parentContainerType) {
|
|
827
|
+
if (token.type !== SqlPrintTokenType.keyword) {
|
|
828
|
+
return false;
|
|
829
|
+
}
|
|
830
|
+
const text = token.text.toLowerCase();
|
|
831
|
+
if (parentContainerType === SqlPrintTokenContainerType.ReferenceDefinition) {
|
|
832
|
+
return CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(text);
|
|
833
|
+
}
|
|
834
|
+
if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(text)) {
|
|
835
|
+
return true;
|
|
836
|
+
}
|
|
837
|
+
if (CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(text)) {
|
|
838
|
+
return true;
|
|
839
|
+
}
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
842
|
+
isIdentifierAttachedToConstraint(token, keywordToken, parentContainerType) {
|
|
843
|
+
if (!token) {
|
|
844
|
+
return false;
|
|
845
|
+
}
|
|
846
|
+
if (parentContainerType === SqlPrintTokenContainerType.ReferenceDefinition) {
|
|
847
|
+
return token.containerType === SqlPrintTokenContainerType.QualifiedName &&
|
|
848
|
+
CREATE_TABLE_PAREN_KEYWORDS_WITH_IDENTIFIER.has(keywordToken.text.toLowerCase());
|
|
849
|
+
}
|
|
850
|
+
if (parentContainerType === SqlPrintTokenContainerType.TableConstraintDefinition ||
|
|
851
|
+
parentContainerType === SqlPrintTokenContainerType.ColumnConstraintDefinition) {
|
|
852
|
+
const normalized = keywordToken.text.toLowerCase();
|
|
853
|
+
if (CREATE_TABLE_SINGLE_PAREN_KEYWORDS.has(normalized) ||
|
|
854
|
+
CREATE_TABLE_MULTI_PAREN_KEYWORDS.has(normalized)) {
|
|
855
|
+
return token.containerType === SqlPrintTokenContainerType.IdentifierString;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return false;
|
|
476
859
|
}
|
|
477
860
|
printCommentToken(text, level, parentContainerType) {
|
|
478
861
|
const trimmed = text.trim();
|
|
@@ -495,11 +878,12 @@ export class SqlPrinter {
|
|
|
495
878
|
const lineText = content ? `-- ${content}` : '--';
|
|
496
879
|
if (parentContainerType === SqlPrintTokenContainerType.CommentBlock) {
|
|
497
880
|
this.linePrinter.appendText(lineText);
|
|
498
|
-
this.pendingLineCommentBreak = level;
|
|
881
|
+
this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
|
|
499
882
|
}
|
|
500
883
|
else {
|
|
501
884
|
this.linePrinter.appendText(lineText);
|
|
502
|
-
this.
|
|
885
|
+
const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
|
|
886
|
+
this.linePrinter.appendNewline(effectiveLevel);
|
|
503
887
|
}
|
|
504
888
|
}
|
|
505
889
|
}
|
|
@@ -520,10 +904,11 @@ export class SqlPrinter {
|
|
|
520
904
|
}
|
|
521
905
|
if (trimmed.startsWith('--')) {
|
|
522
906
|
if (parentContainerType === SqlPrintTokenContainerType.CommentBlock) {
|
|
523
|
-
this.pendingLineCommentBreak = level;
|
|
907
|
+
this.pendingLineCommentBreak = this.resolveCommentIndentLevel(level, parentContainerType);
|
|
524
908
|
}
|
|
525
909
|
else {
|
|
526
|
-
this.
|
|
910
|
+
const effectiveLevel = this.resolveCommentIndentLevel(level, parentContainerType);
|
|
911
|
+
this.linePrinter.appendNewline(effectiveLevel);
|
|
527
912
|
}
|
|
528
913
|
}
|
|
529
914
|
}
|
|
@@ -566,11 +951,8 @@ export class SqlPrinter {
|
|
|
566
951
|
this.flushSmartCommentBlockBuilder();
|
|
567
952
|
return false;
|
|
568
953
|
}
|
|
569
|
-
handleCommentBlockContainer(token, level) {
|
|
954
|
+
handleCommentBlockContainer(token, level, context) {
|
|
570
955
|
var _a;
|
|
571
|
-
if (!this.exportComment) {
|
|
572
|
-
return;
|
|
573
|
-
}
|
|
574
956
|
if (this.commentStyle !== 'smart') {
|
|
575
957
|
const rawLines = this.extractRawCommentBlockLines(token);
|
|
576
958
|
if (rawLines.length > 0) {
|
|
@@ -580,7 +962,13 @@ export class SqlPrinter {
|
|
|
580
962
|
return;
|
|
581
963
|
}
|
|
582
964
|
for (const child of token.innerTokens) {
|
|
583
|
-
|
|
965
|
+
// Force inner comment tokens to render once the block is approved.
|
|
966
|
+
const childContext = {
|
|
967
|
+
position: context.position,
|
|
968
|
+
isTopLevelContainer: context.isTopLevelContainer,
|
|
969
|
+
forceRender: true,
|
|
970
|
+
};
|
|
971
|
+
this.appendToken(child, level, token.containerType, 0, false, childContext);
|
|
584
972
|
}
|
|
585
973
|
return;
|
|
586
974
|
}
|
|
@@ -642,7 +1030,8 @@ export class SqlPrinter {
|
|
|
642
1030
|
}
|
|
643
1031
|
const { lines, level, mode } = this.smartCommentBlockBuilder;
|
|
644
1032
|
if (mode === 'line') {
|
|
645
|
-
|
|
1033
|
+
const meaningfulLineCount = lines.filter(line => line.trim() !== '').length;
|
|
1034
|
+
if (meaningfulLineCount > 1) {
|
|
646
1035
|
const blockText = this.buildBlockComment(lines, level);
|
|
647
1036
|
this.linePrinter.appendText(blockText);
|
|
648
1037
|
}
|
|
@@ -805,6 +1194,19 @@ export class SqlPrinter {
|
|
|
805
1194
|
.replace(/\/\*/g, '\\/\\*')
|
|
806
1195
|
.replace(/\*\//g, '*\\/');
|
|
807
1196
|
}
|
|
1197
|
+
getCommentBaseIndentLevel(level, parentContainerType) {
|
|
1198
|
+
if (!parentContainerType) {
|
|
1199
|
+
return level;
|
|
1200
|
+
}
|
|
1201
|
+
const clauseAlignedLevel = this.getClauseBreakIndentLevel(parentContainerType, level);
|
|
1202
|
+
return Math.max(level, clauseAlignedLevel);
|
|
1203
|
+
}
|
|
1204
|
+
resolveCommentIndentLevel(level, parentContainerType) {
|
|
1205
|
+
var _a;
|
|
1206
|
+
const baseLevel = this.getCommentBaseIndentLevel(level, parentContainerType);
|
|
1207
|
+
const currentLevel = (_a = this.linePrinter.getCurrentLine().level) !== null && _a !== void 0 ? _a : baseLevel;
|
|
1208
|
+
return Math.max(baseLevel, currentLevel);
|
|
1209
|
+
}
|
|
808
1210
|
/**
|
|
809
1211
|
* Handles commentNewline tokens with conditional newline behavior.
|
|
810
1212
|
* In multiline mode (newline !== ' '), adds a newline after comments.
|
|
@@ -835,6 +1237,43 @@ export class SqlPrinter {
|
|
|
835
1237
|
return (this.insideWithClause && this.withClauseStyle === 'full-oneline') ||
|
|
836
1238
|
this.withClauseStyle === 'cte-oneline';
|
|
837
1239
|
}
|
|
1240
|
+
shouldAddNewlineBeforeLeadingComments(parentType) {
|
|
1241
|
+
if (!parentType) {
|
|
1242
|
+
return false;
|
|
1243
|
+
}
|
|
1244
|
+
if (parentType === SqlPrintTokenContainerType.TupleExpression) {
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
if (parentType === SqlPrintTokenContainerType.InsertClause ||
|
|
1248
|
+
parentType === SqlPrintTokenContainerType.MergeInsertAction) {
|
|
1249
|
+
return !this.insertColumnsOneLine;
|
|
1250
|
+
}
|
|
1251
|
+
if (parentType === SqlPrintTokenContainerType.SetClause) {
|
|
1252
|
+
return true;
|
|
1253
|
+
}
|
|
1254
|
+
if (parentType === SqlPrintTokenContainerType.SelectClause) {
|
|
1255
|
+
return true;
|
|
1256
|
+
}
|
|
1257
|
+
if (parentType === SqlPrintTokenContainerType.ExplainStatement) {
|
|
1258
|
+
// Ensure EXPLAIN targets print header comments on a dedicated line.
|
|
1259
|
+
return true;
|
|
1260
|
+
}
|
|
1261
|
+
return false;
|
|
1262
|
+
}
|
|
1263
|
+
getLeadingCommentIndentLevel(parentType, currentLevel) {
|
|
1264
|
+
if (parentType === SqlPrintTokenContainerType.TupleExpression) {
|
|
1265
|
+
return currentLevel + 1;
|
|
1266
|
+
}
|
|
1267
|
+
if (parentType === SqlPrintTokenContainerType.InsertClause ||
|
|
1268
|
+
parentType === SqlPrintTokenContainerType.MergeInsertAction ||
|
|
1269
|
+
parentType === SqlPrintTokenContainerType.SelectClause) {
|
|
1270
|
+
return currentLevel + 1;
|
|
1271
|
+
}
|
|
1272
|
+
if (parentType === SqlPrintTokenContainerType.SetClause) {
|
|
1273
|
+
return currentLevel + 1;
|
|
1274
|
+
}
|
|
1275
|
+
return currentLevel;
|
|
1276
|
+
}
|
|
838
1277
|
/**
|
|
839
1278
|
* Determines if the printer is in oneliner mode.
|
|
840
1279
|
* Oneliner mode uses single spaces instead of actual newlines.
|
|
@@ -867,9 +1306,10 @@ export class SqlPrinter {
|
|
|
867
1306
|
andBreak: this.andBreak,
|
|
868
1307
|
orBreak: this.orBreak,
|
|
869
1308
|
keywordCase: this.keywordCase,
|
|
870
|
-
exportComment:
|
|
1309
|
+
exportComment: 'none',
|
|
871
1310
|
withClauseStyle: 'standard', // Prevent recursive processing
|
|
872
1311
|
indentNestedParentheses: false,
|
|
1312
|
+
insertColumnsOneLine: this.insertColumnsOneLine,
|
|
873
1313
|
});
|
|
874
1314
|
}
|
|
875
1315
|
/**
|
|
@@ -882,6 +1322,117 @@ export class SqlPrinter {
|
|
|
882
1322
|
const cleanedResult = this.cleanDuplicateSpaces(onelineResult);
|
|
883
1323
|
this.linePrinter.appendText(cleanedResult);
|
|
884
1324
|
}
|
|
1325
|
+
getClauseBreakIndentLevel(parentType, level) {
|
|
1326
|
+
if (!parentType) {
|
|
1327
|
+
return level;
|
|
1328
|
+
}
|
|
1329
|
+
switch (parentType) {
|
|
1330
|
+
case SqlPrintTokenContainerType.MergeWhenClause:
|
|
1331
|
+
// Actions under WHEN clauses should be indented one level deeper than the WHEN line.
|
|
1332
|
+
return level + 1;
|
|
1333
|
+
case SqlPrintTokenContainerType.MergeUpdateAction:
|
|
1334
|
+
case SqlPrintTokenContainerType.MergeDeleteAction:
|
|
1335
|
+
case SqlPrintTokenContainerType.MergeInsertAction:
|
|
1336
|
+
// Keep MERGE actions and their follow-up keywords (e.g., VALUES, WHERE) aligned with the action keyword.
|
|
1337
|
+
return level + 1;
|
|
1338
|
+
default:
|
|
1339
|
+
return level;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
isMergeActionContainer(token) {
|
|
1343
|
+
if (!token) {
|
|
1344
|
+
return false;
|
|
1345
|
+
}
|
|
1346
|
+
switch (token.containerType) {
|
|
1347
|
+
case SqlPrintTokenContainerType.MergeUpdateAction:
|
|
1348
|
+
case SqlPrintTokenContainerType.MergeDeleteAction:
|
|
1349
|
+
case SqlPrintTokenContainerType.MergeInsertAction:
|
|
1350
|
+
case SqlPrintTokenContainerType.MergeDoNothingAction:
|
|
1351
|
+
return true;
|
|
1352
|
+
default:
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
shouldBreakAfterOpeningParen(parentType) {
|
|
1357
|
+
if (!parentType) {
|
|
1358
|
+
return false;
|
|
1359
|
+
}
|
|
1360
|
+
if (parentType === SqlPrintTokenContainerType.InsertClause ||
|
|
1361
|
+
parentType === SqlPrintTokenContainerType.MergeInsertAction) {
|
|
1362
|
+
return !this.isInsertClauseOneline(parentType);
|
|
1363
|
+
}
|
|
1364
|
+
return false;
|
|
1365
|
+
}
|
|
1366
|
+
shouldBreakBeforeClosingParen(parentType) {
|
|
1367
|
+
if (!parentType) {
|
|
1368
|
+
return false;
|
|
1369
|
+
}
|
|
1370
|
+
if (parentType === SqlPrintTokenContainerType.InsertClause ||
|
|
1371
|
+
parentType === SqlPrintTokenContainerType.MergeInsertAction) {
|
|
1372
|
+
return !this.isInsertClauseOneline(parentType);
|
|
1373
|
+
}
|
|
1374
|
+
return false;
|
|
1375
|
+
}
|
|
1376
|
+
shouldConvertSpaceToClauseBreak(parentType, nextToken) {
|
|
1377
|
+
if (!parentType || !nextToken) {
|
|
1378
|
+
return false;
|
|
1379
|
+
}
|
|
1380
|
+
const nextKeyword = nextToken.type === SqlPrintTokenType.keyword ? nextToken.text.toLowerCase() : null;
|
|
1381
|
+
const nextContainer = nextToken.containerType;
|
|
1382
|
+
if (parentType === SqlPrintTokenContainerType.MergeQuery) {
|
|
1383
|
+
// Break before USING blocks and before each WHEN clause to mirror statement structure.
|
|
1384
|
+
if (nextKeyword === 'using') {
|
|
1385
|
+
return true;
|
|
1386
|
+
}
|
|
1387
|
+
if (nextContainer === SqlPrintTokenContainerType.MergeWhenClause) {
|
|
1388
|
+
return true;
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
if (parentType === SqlPrintTokenContainerType.MergeWhenClause) {
|
|
1392
|
+
// Force the action to start on the next line with additional indentation.
|
|
1393
|
+
if (nextContainer === SqlPrintTokenContainerType.MergeUpdateAction ||
|
|
1394
|
+
nextContainer === SqlPrintTokenContainerType.MergeDeleteAction ||
|
|
1395
|
+
nextContainer === SqlPrintTokenContainerType.MergeInsertAction ||
|
|
1396
|
+
nextContainer === SqlPrintTokenContainerType.MergeDoNothingAction) {
|
|
1397
|
+
return true;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
if (parentType === SqlPrintTokenContainerType.UpdateQuery) {
|
|
1401
|
+
if (nextKeyword === 'set' || nextKeyword === 'from' || nextKeyword === 'where' || nextKeyword === 'returning') {
|
|
1402
|
+
return true;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
if (parentType === SqlPrintTokenContainerType.InsertQuery) {
|
|
1406
|
+
if (nextKeyword === 'returning') {
|
|
1407
|
+
return true;
|
|
1408
|
+
}
|
|
1409
|
+
if (nextKeyword && (nextKeyword.startsWith('select') || nextKeyword.startsWith('values'))) {
|
|
1410
|
+
return true;
|
|
1411
|
+
}
|
|
1412
|
+
if (nextContainer === SqlPrintTokenContainerType.ValuesQuery || nextContainer === SqlPrintTokenContainerType.SimpleSelectQuery) {
|
|
1413
|
+
return true;
|
|
1414
|
+
}
|
|
1415
|
+
if (nextContainer === SqlPrintTokenContainerType.InsertClause) {
|
|
1416
|
+
return true;
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
if (parentType === SqlPrintTokenContainerType.DeleteQuery) {
|
|
1420
|
+
if (nextKeyword === 'using' || nextKeyword === 'where' || nextKeyword === 'returning') {
|
|
1421
|
+
return true;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
if (parentType === SqlPrintTokenContainerType.MergeUpdateAction || parentType === SqlPrintTokenContainerType.MergeDeleteAction) {
|
|
1425
|
+
if (nextKeyword === 'where') {
|
|
1426
|
+
return true;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
if (parentType === SqlPrintTokenContainerType.MergeInsertAction) {
|
|
1430
|
+
if (nextKeyword && (nextKeyword.startsWith('values') || nextKeyword === 'default values')) {
|
|
1431
|
+
return true;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return false;
|
|
1435
|
+
}
|
|
885
1436
|
/**
|
|
886
1437
|
* Creates a unified SqlPrinter instance configured for oneline formatting.
|
|
887
1438
|
* Works for all oneline options: parentheses, BETWEEN, VALUES, JOIN, CASE, subqueries.
|
|
@@ -898,7 +1449,8 @@ export class SqlPrinter {
|
|
|
898
1449
|
andBreak: 'none', // Disable AND-based line breaks
|
|
899
1450
|
orBreak: 'none', // Disable OR-based line breaks
|
|
900
1451
|
keywordCase: this.keywordCase,
|
|
901
|
-
exportComment: this.
|
|
1452
|
+
exportComment: this.commentExportMode,
|
|
1453
|
+
commentStyle: this.commentStyle,
|
|
902
1454
|
withClauseStyle: 'standard',
|
|
903
1455
|
parenthesesOneLine: false, // Prevent recursive processing (avoid infinite loops)
|
|
904
1456
|
betweenOneLine: false, // Prevent recursive processing (avoid infinite loops)
|
|
@@ -907,6 +1459,7 @@ export class SqlPrinter {
|
|
|
907
1459
|
caseOneLine: false, // Prevent recursive processing (avoid infinite loops)
|
|
908
1460
|
subqueryOneLine: false, // Prevent recursive processing (avoid infinite loops)
|
|
909
1461
|
indentNestedParentheses: false,
|
|
1462
|
+
insertColumnsOneLine: this.insertColumnsOneLine,
|
|
910
1463
|
});
|
|
911
1464
|
}
|
|
912
1465
|
/**
|