prettier-plugin-tsql 0.1.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/LICENSE +21 -0
- package/README.md +199 -0
- package/bin/dotnet/Microsoft.SqlServer.TransactSql.ScriptDom.dll +0 -0
- package/bin/dotnet/SqlScriptDom.deps.json +41 -0
- package/bin/dotnet/SqlScriptDom.dll +0 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/language.d.ts +3 -0
- package/dist/language.d.ts.map +1 -0
- package/dist/language.js +9 -0
- package/dist/language.js.map +1 -0
- package/dist/options.d.ts +3 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +35 -0
- package/dist/options.js.map +1 -0
- package/dist/parser/index.d.ts +5 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +263 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/types.d.ts +21 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +2 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/printer/admin.d.ts +22 -0
- package/dist/printer/admin.d.ts.map +1 -0
- package/dist/printer/admin.js +250 -0
- package/dist/printer/admin.js.map +1 -0
- package/dist/printer/ddl.d.ts +36 -0
- package/dist/printer/ddl.d.ts.map +1 -0
- package/dist/printer/ddl.js +836 -0
- package/dist/printer/ddl.js.map +1 -0
- package/dist/printer/expressions.d.ts +11 -0
- package/dist/printer/expressions.d.ts.map +1 -0
- package/dist/printer/expressions.js +1475 -0
- package/dist/printer/expressions.js.map +1 -0
- package/dist/printer/helpers.d.ts +25 -0
- package/dist/printer/helpers.d.ts.map +1 -0
- package/dist/printer/helpers.js +61 -0
- package/dist/printer/helpers.js.map +1 -0
- package/dist/printer/index.d.ts +4 -0
- package/dist/printer/index.d.ts.map +1 -0
- package/dist/printer/index.js +30 -0
- package/dist/printer/index.js.map +1 -0
- package/dist/printer/procedural.d.ts +41 -0
- package/dist/printer/procedural.d.ts.map +1 -0
- package/dist/printer/procedural.js +364 -0
- package/dist/printer/procedural.js.map +1 -0
- package/dist/printer/security.d.ts +15 -0
- package/dist/printer/security.d.ts.map +1 -0
- package/dist/printer/security.js +309 -0
- package/dist/printer/security.js.map +1 -0
- package/dist/printer/statements.d.ts +18 -0
- package/dist/printer/statements.d.ts.map +1 -0
- package/dist/printer/statements.js +689 -0
- package/dist/printer/statements.js.map +1 -0
- package/dist/printer/utils.d.ts +34 -0
- package/dist/printer/utils.d.ts.map +1 -0
- package/dist/printer/utils.js +61 -0
- package/dist/printer/utils.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,836 @@
|
|
|
1
|
+
import { keyword, hardline, join, indent, group, softline, line, ifExistsDoc } from './utils.js';
|
|
2
|
+
import { prop, propArr, propStr, propBool, schemaObjectName } from './helpers.js';
|
|
3
|
+
// printNode / printBool / qexpr / printStatementWithComments are imported from statements.ts
|
|
4
|
+
// — circular but safe in ESM (all imports are function references, never accessed during init)
|
|
5
|
+
import { printStatementWithComments, printNode, printBool, qexpr } from './statements.js';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// CREATE TABLE
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
export function printCreateTable(node, opts) {
|
|
10
|
+
const columns = propArr(node, 'columns');
|
|
11
|
+
const constraints = propArr(node, 'constraints');
|
|
12
|
+
const options = node.props?.['options'];
|
|
13
|
+
const allDefs = [
|
|
14
|
+
...columns.map((col) => printColumnDef(col, opts)),
|
|
15
|
+
...constraints.map((c) => printConstraintDef(c, opts)),
|
|
16
|
+
];
|
|
17
|
+
const withPart = options && options.length > 0
|
|
18
|
+
? [
|
|
19
|
+
hardline,
|
|
20
|
+
keyword('WITH', opts),
|
|
21
|
+
' ',
|
|
22
|
+
group(['(', indent([softline, join([',', line], options)]), softline, ')']),
|
|
23
|
+
]
|
|
24
|
+
: '';
|
|
25
|
+
return group([
|
|
26
|
+
keyword('CREATE TABLE', opts),
|
|
27
|
+
' ',
|
|
28
|
+
schemaObjectName(prop(node, 'name')),
|
|
29
|
+
' (',
|
|
30
|
+
indent([hardline, join([',', hardline], allDefs)]),
|
|
31
|
+
hardline,
|
|
32
|
+
')',
|
|
33
|
+
withPart,
|
|
34
|
+
';',
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
export function printColumnDef(node, opts) {
|
|
38
|
+
const name = propStr(node, 'name') ?? 'col';
|
|
39
|
+
// Computed column: Name AS expression [PERSISTED]
|
|
40
|
+
const computedExpr = prop(node, 'computedExpression');
|
|
41
|
+
if (computedExpr) {
|
|
42
|
+
const isPersisted = node.props?.['isPersisted'];
|
|
43
|
+
return [
|
|
44
|
+
name,
|
|
45
|
+
' ',
|
|
46
|
+
keyword('AS', opts),
|
|
47
|
+
' ',
|
|
48
|
+
printNode(computedExpr, opts),
|
|
49
|
+
isPersisted ? [' ', keyword('PERSISTED', opts)] : '',
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
const dataType = propStr(node, 'dataType') ?? 'INT';
|
|
53
|
+
const params = node.props?.['dataTypeParams'];
|
|
54
|
+
// Read nullable as a tristate (true/false/undefined) — propBool only returns true/false.
|
|
55
|
+
const isNullable = node.props?.['nullable'];
|
|
56
|
+
const isIdentity = propBool(node, 'identity');
|
|
57
|
+
const identitySeed = propStr(node, 'identitySeed');
|
|
58
|
+
const identityIncrement = propStr(node, 'identityIncrement');
|
|
59
|
+
const defaultValue = prop(node, 'defaultValue');
|
|
60
|
+
const typeStr = Array.isArray(params) && params.length > 0
|
|
61
|
+
? [keyword(dataType, opts), `(${params.join(', ')})`]
|
|
62
|
+
: keyword(dataType, opts);
|
|
63
|
+
const parts = [name, ' ', typeStr];
|
|
64
|
+
if (isIdentity) {
|
|
65
|
+
const seed = identitySeed ?? '1';
|
|
66
|
+
const inc = identityIncrement ?? '1';
|
|
67
|
+
parts.push(' ', keyword('IDENTITY', opts), `(${seed}, ${inc})`);
|
|
68
|
+
}
|
|
69
|
+
if (defaultValue)
|
|
70
|
+
parts.push(' ', keyword('DEFAULT', opts), ' ', printNode(defaultValue, opts));
|
|
71
|
+
if (isNullable === false)
|
|
72
|
+
parts.push(' ', keyword('NOT NULL', opts));
|
|
73
|
+
else if (isNullable === true)
|
|
74
|
+
parts.push(' ', keyword('NULL', opts));
|
|
75
|
+
return parts;
|
|
76
|
+
}
|
|
77
|
+
export function printConstraintDef(node, opts) {
|
|
78
|
+
const constraintName = propStr(node, 'constraintName');
|
|
79
|
+
const namePrefix = constraintName ? [keyword('CONSTRAINT', opts), ' ', constraintName, ' '] : '';
|
|
80
|
+
switch (node.type) {
|
|
81
|
+
case 'UniqueConstraint': {
|
|
82
|
+
const isPK = propBool(node, 'isPrimaryKey');
|
|
83
|
+
const cols = node.props?.['columns'];
|
|
84
|
+
const colList = Array.isArray(cols) ? cols.join(', ') : '';
|
|
85
|
+
const kw = isPK ? keyword('PRIMARY KEY', opts) : keyword('UNIQUE', opts);
|
|
86
|
+
return [namePrefix, kw, ' (', colList, ')'];
|
|
87
|
+
}
|
|
88
|
+
case 'CheckConstraint': {
|
|
89
|
+
const expr = prop(node, 'expression');
|
|
90
|
+
return [namePrefix, keyword('CHECK', opts), ' (', expr ? printBool(expr, opts) : '', ')'];
|
|
91
|
+
}
|
|
92
|
+
case 'ForeignKeyConstraint': {
|
|
93
|
+
const cols = node.props?.['columns'];
|
|
94
|
+
const refTable = prop(node, 'refTable');
|
|
95
|
+
const refCols = node.props?.['refColumns'];
|
|
96
|
+
const colList = Array.isArray(cols) ? cols.join(', ') : '';
|
|
97
|
+
const refColList = Array.isArray(refCols) ? refCols.join(', ') : '';
|
|
98
|
+
const refName = refTable ? schemaObjectName(refTable) : '';
|
|
99
|
+
return [
|
|
100
|
+
namePrefix,
|
|
101
|
+
keyword('FOREIGN KEY', opts),
|
|
102
|
+
' (',
|
|
103
|
+
colList,
|
|
104
|
+
') ',
|
|
105
|
+
keyword('REFERENCES', opts),
|
|
106
|
+
' ',
|
|
107
|
+
refName,
|
|
108
|
+
' (',
|
|
109
|
+
refColList,
|
|
110
|
+
')',
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
default:
|
|
114
|
+
return node.text ?? `/* constraint: ${node.type} */`;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// ALTER TABLE
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
export function printAlterTable(node, opts) {
|
|
121
|
+
const alterType = propStr(node, 'alterType') ?? '';
|
|
122
|
+
const name = schemaObjectName(prop(node, 'name'));
|
|
123
|
+
if (alterType === 'AlterTableAddTableElementStatement') {
|
|
124
|
+
const defs = [
|
|
125
|
+
...propArr(node, 'columns').map((c) => printColumnDef(c, opts)),
|
|
126
|
+
...propArr(node, 'constraints').map((c) => printConstraintDef(c, opts)),
|
|
127
|
+
];
|
|
128
|
+
const addPart = defs.length === 1 ? [' ', defs[0]] : indent([hardline, join([',', hardline], defs)]);
|
|
129
|
+
return [keyword('ALTER TABLE', opts), ' ', name, hardline, keyword('ADD', opts), addPart, ';'];
|
|
130
|
+
}
|
|
131
|
+
if (alterType === 'AlterTableDropTableElementStatement') {
|
|
132
|
+
const elements = node.props?.['elements'];
|
|
133
|
+
const elemList = Array.isArray(elements) ? elements.join(', ') : '';
|
|
134
|
+
return group([
|
|
135
|
+
keyword('ALTER TABLE', opts),
|
|
136
|
+
' ',
|
|
137
|
+
name,
|
|
138
|
+
hardline,
|
|
139
|
+
keyword('DROP COLUMN', opts),
|
|
140
|
+
' ',
|
|
141
|
+
elemList,
|
|
142
|
+
';',
|
|
143
|
+
]);
|
|
144
|
+
}
|
|
145
|
+
return [keyword('ALTER TABLE', opts), ' ', name, ' /* ', alterType, ' */;'];
|
|
146
|
+
}
|
|
147
|
+
// ---------------------------------------------------------------------------
|
|
148
|
+
// CREATE INDEX
|
|
149
|
+
// ---------------------------------------------------------------------------
|
|
150
|
+
export function printCreateIndex(node, opts) {
|
|
151
|
+
const indexName = propStr(node, 'indexName') ?? 'idx';
|
|
152
|
+
const isUnique = propBool(node, 'unique');
|
|
153
|
+
const isClustered = propBool(node, 'clustered');
|
|
154
|
+
const table = prop(node, 'table');
|
|
155
|
+
const columns = propArr(node, 'columns');
|
|
156
|
+
const includeColumns = node.props?.['includeColumns'];
|
|
157
|
+
const colDocs = columns.map((c) => {
|
|
158
|
+
const colName = propStr(c, 'name') ?? c.text ?? '';
|
|
159
|
+
const sort = propStr(c, 'sortOrder') ?? 'Ascending';
|
|
160
|
+
return sort === 'Descending'
|
|
161
|
+
? [colName, ' ', keyword('DESC', opts)]
|
|
162
|
+
: [colName, ' ', keyword('ASC', opts)];
|
|
163
|
+
});
|
|
164
|
+
const uniqueKw = isUnique ? keyword('UNIQUE ', opts) : '';
|
|
165
|
+
const clusteredKw = isClustered ? keyword('CLUSTERED ', opts) : keyword('NONCLUSTERED ', opts);
|
|
166
|
+
const onClause = [
|
|
167
|
+
keyword('ON', opts),
|
|
168
|
+
' ',
|
|
169
|
+
schemaObjectName(table),
|
|
170
|
+
' (',
|
|
171
|
+
indent([softline, join([',', line], colDocs)]),
|
|
172
|
+
softline,
|
|
173
|
+
')',
|
|
174
|
+
];
|
|
175
|
+
const includePart = Array.isArray(includeColumns) && includeColumns.length > 0
|
|
176
|
+
? [hardline, keyword('INCLUDE', opts), ' (', includeColumns.join(', '), ')']
|
|
177
|
+
: '';
|
|
178
|
+
return group([
|
|
179
|
+
keyword('CREATE ', opts),
|
|
180
|
+
uniqueKw,
|
|
181
|
+
clusteredKw,
|
|
182
|
+
keyword('INDEX', opts),
|
|
183
|
+
' ',
|
|
184
|
+
indexName,
|
|
185
|
+
indent([hardline, onClause, includePart]),
|
|
186
|
+
';',
|
|
187
|
+
]);
|
|
188
|
+
}
|
|
189
|
+
// ---------------------------------------------------------------------------
|
|
190
|
+
// ALTER INDEX
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
export function printAlterIndex(node, opts) {
|
|
193
|
+
const indexName = propStr(node, 'indexName');
|
|
194
|
+
const table = prop(node, 'table');
|
|
195
|
+
const alterType = propStr(node, 'alterType') ?? 'Rebuild';
|
|
196
|
+
const typeKwMap = {
|
|
197
|
+
Rebuild: 'REBUILD',
|
|
198
|
+
Reorganize: 'REORGANIZE',
|
|
199
|
+
Disable: 'DISABLE',
|
|
200
|
+
Set: 'SET',
|
|
201
|
+
};
|
|
202
|
+
const typeKw = keyword(typeKwMap[alterType] ?? alterType.toUpperCase(), opts);
|
|
203
|
+
return [
|
|
204
|
+
keyword('ALTER INDEX', opts),
|
|
205
|
+
' ',
|
|
206
|
+
indexName ? indexName : keyword('ALL', opts),
|
|
207
|
+
' ',
|
|
208
|
+
keyword('ON', opts),
|
|
209
|
+
' ',
|
|
210
|
+
schemaObjectName(table),
|
|
211
|
+
' ',
|
|
212
|
+
typeKw,
|
|
213
|
+
';',
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
// WITH options for procs and functions (RECOMPILE, ENCRYPTION, EXECUTE AS, ...)
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
function printExecuteAsClause(optNode, opts) {
|
|
221
|
+
// ExecuteAsOption node: kind = Caller|Self|Owner|Login|User|String
|
|
222
|
+
const kind = propStr(optNode, 'kind') ?? 'Caller';
|
|
223
|
+
const principal = propStr(optNode, 'principal');
|
|
224
|
+
// String kind = EXECUTE AS 'username' (no USER/LOGIN qualifier)
|
|
225
|
+
if (kind === 'String')
|
|
226
|
+
return [keyword('EXECUTE AS', opts), " '", principal ?? '', "'"];
|
|
227
|
+
const kindMap = {
|
|
228
|
+
Caller: 'CALLER',
|
|
229
|
+
Self: 'SELF',
|
|
230
|
+
Owner: 'OWNER',
|
|
231
|
+
Login: 'LOGIN',
|
|
232
|
+
User: 'USER',
|
|
233
|
+
};
|
|
234
|
+
const kindKw = keyword(kindMap[kind] ?? kind.toUpperCase(), opts);
|
|
235
|
+
if (principal)
|
|
236
|
+
return [keyword('EXECUTE AS', opts), ' ', kindKw, " = '", principal, "'"];
|
|
237
|
+
return [keyword('EXECUTE AS', opts), ' ', kindKw];
|
|
238
|
+
}
|
|
239
|
+
function printModuleOptions(node, opts) {
|
|
240
|
+
const options = propArr(node, 'options');
|
|
241
|
+
if (!options.length)
|
|
242
|
+
return '';
|
|
243
|
+
const optDocs = options.map((o) => {
|
|
244
|
+
if (o.type === 'ExecuteAsOption')
|
|
245
|
+
return printExecuteAsClause(o, opts);
|
|
246
|
+
return keyword(o.text ?? '', opts);
|
|
247
|
+
});
|
|
248
|
+
return [hardline, group([keyword('WITH', opts), indent([line, join([',', line], optDocs)])])];
|
|
249
|
+
}
|
|
250
|
+
// ---------------------------------------------------------------------------
|
|
251
|
+
// CREATE / ALTER / CREATE OR ALTER PROCEDURE
|
|
252
|
+
// ---------------------------------------------------------------------------
|
|
253
|
+
export function printCreateProcedure(node, opts) {
|
|
254
|
+
const parameters = propArr(node, 'parameters');
|
|
255
|
+
const body = propArr(node, 'body');
|
|
256
|
+
const paramDocs = parameters.map((p) => {
|
|
257
|
+
const pName = propStr(p, 'name') ?? '@p';
|
|
258
|
+
const dt = propStr(p, 'dataType') ?? 'INT';
|
|
259
|
+
const isOutput = propBool(p, 'output');
|
|
260
|
+
const isReadonly = propBool(p, 'readonly');
|
|
261
|
+
const defaultVal = prop(p, 'defaultValue');
|
|
262
|
+
const parts = [pName, ' ', keyword(dt, opts)];
|
|
263
|
+
if (defaultVal)
|
|
264
|
+
parts.push(' = ', printNode(defaultVal, opts));
|
|
265
|
+
if (isOutput)
|
|
266
|
+
parts.push(' ', keyword('OUTPUT', opts));
|
|
267
|
+
if (isReadonly)
|
|
268
|
+
parts.push(' ', keyword('READONLY', opts));
|
|
269
|
+
return parts;
|
|
270
|
+
});
|
|
271
|
+
const bodyDocs = body.map((s) => printStatementWithComments(s, opts));
|
|
272
|
+
const preBody = node.preBodyComments?.length
|
|
273
|
+
? node.preBodyComments.flatMap((c) => [hardline, c])
|
|
274
|
+
: '';
|
|
275
|
+
const postParam = node.postParamComments?.length
|
|
276
|
+
? node.postParamComments.flatMap((c) => [hardline, c])
|
|
277
|
+
: '';
|
|
278
|
+
const procKw = node.type === 'CreateOrAlterProcedureStatement'
|
|
279
|
+
? keyword('CREATE OR ALTER PROCEDURE', opts)
|
|
280
|
+
: node.type === 'AlterProcedureStatement'
|
|
281
|
+
? keyword('ALTER PROCEDURE', opts)
|
|
282
|
+
: keyword('CREATE PROCEDURE', opts);
|
|
283
|
+
return group([
|
|
284
|
+
procKw,
|
|
285
|
+
' ',
|
|
286
|
+
schemaObjectName(prop(node, 'name')),
|
|
287
|
+
preBody,
|
|
288
|
+
parameters.length > 0 ? indent([hardline, join([',', hardline], paramDocs)]) : '',
|
|
289
|
+
postParam,
|
|
290
|
+
printModuleOptions(node, opts),
|
|
291
|
+
hardline,
|
|
292
|
+
keyword('AS', opts),
|
|
293
|
+
hardline,
|
|
294
|
+
keyword('BEGIN', opts),
|
|
295
|
+
indent([hardline, join([hardline, hardline], bodyDocs)]),
|
|
296
|
+
hardline,
|
|
297
|
+
keyword('END', opts),
|
|
298
|
+
';',
|
|
299
|
+
]);
|
|
300
|
+
}
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
// CREATE / ALTER / CREATE OR ALTER FUNCTION
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
export function printCreateFunction(node, opts) {
|
|
305
|
+
const parameters = propArr(node, 'parameters');
|
|
306
|
+
const bodyType = propStr(node, 'bodyType') ?? 'scalar';
|
|
307
|
+
const returnType = propStr(node, 'returnType') ?? '';
|
|
308
|
+
const body = node.props?.['body'];
|
|
309
|
+
const paramDocs = parameters.map((p) => {
|
|
310
|
+
const pName = propStr(p, 'name') ?? '@p';
|
|
311
|
+
const dt = propStr(p, 'dataType') ?? 'INT';
|
|
312
|
+
return [pName, ' ', keyword(dt, opts)];
|
|
313
|
+
});
|
|
314
|
+
const preBody = node.preBodyComments?.length
|
|
315
|
+
? node.preBodyComments.flatMap((c) => [hardline, c])
|
|
316
|
+
: '';
|
|
317
|
+
const postParam = node.postParamComments?.length
|
|
318
|
+
? node.postParamComments.flatMap((c) => [hardline, c])
|
|
319
|
+
: '';
|
|
320
|
+
const fnKw = node.type === 'CreateOrAlterFunctionStatement'
|
|
321
|
+
? keyword('CREATE OR ALTER FUNCTION', opts)
|
|
322
|
+
: node.type === 'AlterFunctionStatement'
|
|
323
|
+
? keyword('ALTER FUNCTION', opts)
|
|
324
|
+
: keyword('CREATE FUNCTION', opts);
|
|
325
|
+
const nameAndParams = [
|
|
326
|
+
fnKw,
|
|
327
|
+
' ',
|
|
328
|
+
schemaObjectName(prop(node, 'name')),
|
|
329
|
+
preBody,
|
|
330
|
+
group(['(', parameters.length > 0 ? [indent([softline, join([',', line], paramDocs)]), softline] : '', ')']),
|
|
331
|
+
postParam,
|
|
332
|
+
printModuleOptions(node, opts),
|
|
333
|
+
];
|
|
334
|
+
if (bodyType === 'table') {
|
|
335
|
+
// Inline TVF: RETURNS TABLE AS RETURN (query) — no BEGIN/END
|
|
336
|
+
// returnType raw text contains the SELECT, not the word TABLE — hardcode TABLE
|
|
337
|
+
const queryDoc = body && !Array.isArray(body) ? qexpr(body, opts) : '/* query */';
|
|
338
|
+
return [
|
|
339
|
+
nameAndParams,
|
|
340
|
+
' ',
|
|
341
|
+
keyword('RETURNS', opts),
|
|
342
|
+
' ',
|
|
343
|
+
keyword('TABLE', opts),
|
|
344
|
+
hardline,
|
|
345
|
+
keyword('AS', opts),
|
|
346
|
+
hardline,
|
|
347
|
+
keyword('RETURN', opts),
|
|
348
|
+
' (',
|
|
349
|
+
indent([hardline, queryDoc]),
|
|
350
|
+
hardline,
|
|
351
|
+
')',
|
|
352
|
+
';',
|
|
353
|
+
];
|
|
354
|
+
}
|
|
355
|
+
// Scalar or multi-statement TVF — both use BEGIN...END
|
|
356
|
+
const stmts = Array.isArray(body) ? body.map((s) => printStatementWithComments(s, opts)) : [];
|
|
357
|
+
const bodyDoc = join([hardline, hardline], stmts);
|
|
358
|
+
let retTypePart;
|
|
359
|
+
if (bodyType === 'inline-table') {
|
|
360
|
+
const returnVar = propStr(node, 'returnVar') ?? '@t';
|
|
361
|
+
const returnColumns = propArr(node, 'returnColumns');
|
|
362
|
+
const colDocs = returnColumns.map((c) => printColumnDef(c, opts));
|
|
363
|
+
retTypePart = [
|
|
364
|
+
returnVar,
|
|
365
|
+
' ',
|
|
366
|
+
keyword('TABLE', opts),
|
|
367
|
+
' (',
|
|
368
|
+
indent([hardline, join([',', hardline], colDocs)]),
|
|
369
|
+
hardline,
|
|
370
|
+
')',
|
|
371
|
+
];
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
retTypePart = keyword(returnType, opts);
|
|
375
|
+
}
|
|
376
|
+
return [
|
|
377
|
+
nameAndParams,
|
|
378
|
+
' ',
|
|
379
|
+
keyword('RETURNS', opts),
|
|
380
|
+
' ',
|
|
381
|
+
retTypePart,
|
|
382
|
+
hardline,
|
|
383
|
+
keyword('AS', opts),
|
|
384
|
+
hardline,
|
|
385
|
+
keyword('BEGIN', opts),
|
|
386
|
+
indent([hardline, bodyDoc]),
|
|
387
|
+
hardline,
|
|
388
|
+
keyword('END', opts),
|
|
389
|
+
';',
|
|
390
|
+
];
|
|
391
|
+
}
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
// CREATE / ALTER / CREATE OR ALTER VIEW
|
|
394
|
+
// ---------------------------------------------------------------------------
|
|
395
|
+
export function printCreateView(node, opts) {
|
|
396
|
+
const columns = node.props?.['columns'];
|
|
397
|
+
const withOptions = node.props?.['withOptions'];
|
|
398
|
+
const body = prop(node, 'body');
|
|
399
|
+
const kw = node.type === 'CreateOrAlterViewStatement'
|
|
400
|
+
? keyword('CREATE OR ALTER VIEW', opts)
|
|
401
|
+
: node.type === 'AlterViewStatement'
|
|
402
|
+
? keyword('ALTER VIEW', opts)
|
|
403
|
+
: keyword('CREATE VIEW', opts);
|
|
404
|
+
const colsPart = columns?.length
|
|
405
|
+
? [' ', group(['(', indent([softline, join([',', line], columns)]), softline, ')'])]
|
|
406
|
+
: '';
|
|
407
|
+
const withPart = withOptions?.length
|
|
408
|
+
? [
|
|
409
|
+
hardline,
|
|
410
|
+
keyword('WITH', opts),
|
|
411
|
+
' ',
|
|
412
|
+
join(', ', withOptions.map((o) => keyword(o, opts))),
|
|
413
|
+
]
|
|
414
|
+
: '';
|
|
415
|
+
const preBodyPart = node.preBodyComments?.length
|
|
416
|
+
? node.preBodyComments.flatMap((c) => [hardline, c])
|
|
417
|
+
: '';
|
|
418
|
+
return group([
|
|
419
|
+
kw,
|
|
420
|
+
' ',
|
|
421
|
+
schemaObjectName(prop(node, 'name')),
|
|
422
|
+
colsPart,
|
|
423
|
+
withPart,
|
|
424
|
+
preBodyPart,
|
|
425
|
+
hardline,
|
|
426
|
+
keyword('AS', opts),
|
|
427
|
+
hardline,
|
|
428
|
+
body ? qexpr(body, opts) : '',
|
|
429
|
+
';',
|
|
430
|
+
]);
|
|
431
|
+
}
|
|
432
|
+
// ---------------------------------------------------------------------------
|
|
433
|
+
// CREATE / ALTER TRIGGER
|
|
434
|
+
// ---------------------------------------------------------------------------
|
|
435
|
+
export function printCreateTrigger(node, opts) {
|
|
436
|
+
const kw = node.type === 'AlterTriggerStatement' ? keyword('ALTER TRIGGER', opts) : keyword('CREATE TRIGGER', opts);
|
|
437
|
+
const triggerType = propStr(node, 'triggerType') ?? 'After';
|
|
438
|
+
const typeMap = {
|
|
439
|
+
For: 'FOR',
|
|
440
|
+
After: 'AFTER',
|
|
441
|
+
InsteadOf: 'INSTEAD OF',
|
|
442
|
+
};
|
|
443
|
+
const typeKw = keyword(typeMap[triggerType] ?? triggerType.toUpperCase(), opts);
|
|
444
|
+
const actions = node.props?.['actions'];
|
|
445
|
+
const actionList = Array.isArray(actions)
|
|
446
|
+
? join(', ', actions.map((a) => keyword(a.toUpperCase(), opts)))
|
|
447
|
+
: '';
|
|
448
|
+
const bodyDocs = propArr(node, 'body').map((s) => printStatementWithComments(s, opts));
|
|
449
|
+
return [
|
|
450
|
+
kw,
|
|
451
|
+
' ',
|
|
452
|
+
schemaObjectName(prop(node, 'name')),
|
|
453
|
+
hardline,
|
|
454
|
+
keyword('ON', opts),
|
|
455
|
+
' ',
|
|
456
|
+
schemaObjectName(prop(node, 'onName')),
|
|
457
|
+
hardline,
|
|
458
|
+
typeKw,
|
|
459
|
+
' ',
|
|
460
|
+
actionList,
|
|
461
|
+
hardline,
|
|
462
|
+
keyword('AS', opts),
|
|
463
|
+
hardline,
|
|
464
|
+
keyword('BEGIN', opts),
|
|
465
|
+
indent([hardline, join([hardline, hardline], bodyDocs)]),
|
|
466
|
+
hardline,
|
|
467
|
+
keyword('END', opts),
|
|
468
|
+
';',
|
|
469
|
+
];
|
|
470
|
+
}
|
|
471
|
+
// ---------------------------------------------------------------------------
|
|
472
|
+
// CREATE / ALTER SEQUENCE
|
|
473
|
+
// ---------------------------------------------------------------------------
|
|
474
|
+
function printSequenceOptions(node, opts) {
|
|
475
|
+
const parts = [];
|
|
476
|
+
const dataType = propStr(node, 'dataType'); // emitted inline on header line, not here
|
|
477
|
+
const startWith = propStr(node, 'startWith');
|
|
478
|
+
if (startWith != null)
|
|
479
|
+
parts.push(hardline, keyword('START WITH', opts), ' ', startWith);
|
|
480
|
+
const restartWith = propStr(node, 'restartWith');
|
|
481
|
+
if (restartWith != null)
|
|
482
|
+
parts.push(hardline, keyword('RESTART WITH', opts), ' ', restartWith);
|
|
483
|
+
const incrementBy = propStr(node, 'incrementBy');
|
|
484
|
+
if (incrementBy != null)
|
|
485
|
+
parts.push(hardline, keyword('INCREMENT BY', opts), ' ', incrementBy);
|
|
486
|
+
const minValue = propStr(node, 'minValue');
|
|
487
|
+
const noMinValue = node.props?.['noMinValue'];
|
|
488
|
+
if (minValue != null)
|
|
489
|
+
parts.push(hardline, keyword('MINVALUE', opts), ' ', minValue);
|
|
490
|
+
else if (noMinValue)
|
|
491
|
+
parts.push(hardline, keyword('NO MINVALUE', opts));
|
|
492
|
+
const maxValue = propStr(node, 'maxValue');
|
|
493
|
+
const noMaxValue = node.props?.['noMaxValue'];
|
|
494
|
+
if (maxValue != null)
|
|
495
|
+
parts.push(hardline, keyword('MAXVALUE', opts), ' ', maxValue);
|
|
496
|
+
else if (noMaxValue)
|
|
497
|
+
parts.push(hardline, keyword('NO MAXVALUE', opts));
|
|
498
|
+
const cycle = node.props?.['cycle'];
|
|
499
|
+
if (cycle === true)
|
|
500
|
+
parts.push(hardline, keyword('CYCLE', opts));
|
|
501
|
+
else if (cycle === false)
|
|
502
|
+
parts.push(hardline, keyword('NO CYCLE', opts));
|
|
503
|
+
const cache = propStr(node, 'cache');
|
|
504
|
+
const noCache = node.props?.['noCache'];
|
|
505
|
+
if (cache != null)
|
|
506
|
+
parts.push(hardline, keyword('CACHE', opts), ' ', cache);
|
|
507
|
+
else if (noCache)
|
|
508
|
+
parts.push(hardline, keyword('NO CACHE', opts));
|
|
509
|
+
return parts;
|
|
510
|
+
}
|
|
511
|
+
function sequenceHeader(kw, node, opts) {
|
|
512
|
+
const dataType = propStr(node, 'dataType');
|
|
513
|
+
const asPart = dataType ? [' ', keyword('AS', opts), ' ', keyword(dataType, opts)] : '';
|
|
514
|
+
return [kw, ' ', schemaObjectName(prop(node, 'name')), asPart];
|
|
515
|
+
}
|
|
516
|
+
export function printCreateSequence(node, opts) {
|
|
517
|
+
return group([
|
|
518
|
+
sequenceHeader(keyword('CREATE SEQUENCE', opts), node, opts),
|
|
519
|
+
indent(printSequenceOptions(node, opts)),
|
|
520
|
+
';',
|
|
521
|
+
]);
|
|
522
|
+
}
|
|
523
|
+
export function printAlterSequence(node, opts) {
|
|
524
|
+
return group([
|
|
525
|
+
sequenceHeader(keyword('ALTER SEQUENCE', opts), node, opts),
|
|
526
|
+
indent(printSequenceOptions(node, opts)),
|
|
527
|
+
';',
|
|
528
|
+
]);
|
|
529
|
+
}
|
|
530
|
+
// ---------------------------------------------------------------------------
|
|
531
|
+
// BULK INSERT
|
|
532
|
+
// ---------------------------------------------------------------------------
|
|
533
|
+
export function printBulkInsert(node, opts) {
|
|
534
|
+
const table = prop(node, 'table');
|
|
535
|
+
const from = propStr(node, 'from');
|
|
536
|
+
const options = node.props?.['options'];
|
|
537
|
+
const optDocs = Array.isArray(options) && options.length > 0
|
|
538
|
+
? [
|
|
539
|
+
hardline,
|
|
540
|
+
keyword('WITH', opts),
|
|
541
|
+
' (',
|
|
542
|
+
indent([hardline, join([',', hardline], options)]),
|
|
543
|
+
hardline,
|
|
544
|
+
')',
|
|
545
|
+
]
|
|
546
|
+
: '';
|
|
547
|
+
return group([
|
|
548
|
+
keyword('BULK INSERT', opts),
|
|
549
|
+
' ',
|
|
550
|
+
schemaObjectName(table),
|
|
551
|
+
hardline,
|
|
552
|
+
keyword('FROM', opts),
|
|
553
|
+
' ',
|
|
554
|
+
from ?? '',
|
|
555
|
+
optDocs,
|
|
556
|
+
';',
|
|
557
|
+
]);
|
|
558
|
+
}
|
|
559
|
+
// ---------------------------------------------------------------------------
|
|
560
|
+
// CREATE TYPE
|
|
561
|
+
// ---------------------------------------------------------------------------
|
|
562
|
+
export function printCreateTypeUddt(node, opts) {
|
|
563
|
+
const nullable = node.props?.['nullable'];
|
|
564
|
+
const nullablePart = nullable === false ? [' ', keyword('NOT NULL', opts)] : nullable === true ? [' ', keyword('NULL', opts)] : '';
|
|
565
|
+
return [
|
|
566
|
+
keyword('CREATE TYPE', opts),
|
|
567
|
+
' ',
|
|
568
|
+
schemaObjectName(prop(node, 'name')),
|
|
569
|
+
' ',
|
|
570
|
+
keyword('FROM', opts),
|
|
571
|
+
' ',
|
|
572
|
+
keyword(propStr(node, 'dataType') ?? '', opts),
|
|
573
|
+
nullablePart,
|
|
574
|
+
';',
|
|
575
|
+
];
|
|
576
|
+
}
|
|
577
|
+
export function printCreateTypeTable(node, opts) {
|
|
578
|
+
const allDefs = [
|
|
579
|
+
...propArr(node, 'columns').map((c) => printColumnDef(c, opts)),
|
|
580
|
+
...propArr(node, 'constraints').map((c) => printConstraintDef(c, opts)),
|
|
581
|
+
];
|
|
582
|
+
return group([
|
|
583
|
+
keyword('CREATE TYPE', opts),
|
|
584
|
+
' ',
|
|
585
|
+
schemaObjectName(prop(node, 'name')),
|
|
586
|
+
' ',
|
|
587
|
+
keyword('AS TABLE', opts),
|
|
588
|
+
' (',
|
|
589
|
+
indent([hardline, join([',', hardline], allDefs)]),
|
|
590
|
+
hardline,
|
|
591
|
+
');',
|
|
592
|
+
]);
|
|
593
|
+
}
|
|
594
|
+
// ---------------------------------------------------------------------------
|
|
595
|
+
// DROP helpers (shared across multiple statement types)
|
|
596
|
+
// ---------------------------------------------------------------------------
|
|
597
|
+
export function printDropObjects(objType, node, opts) {
|
|
598
|
+
const names = propArr(node, 'names');
|
|
599
|
+
const ifExists = propBool(node, 'ifExists');
|
|
600
|
+
return [
|
|
601
|
+
keyword('DROP', opts),
|
|
602
|
+
' ',
|
|
603
|
+
keyword(objType, opts),
|
|
604
|
+
ifExistsDoc(ifExists, opts),
|
|
605
|
+
' ',
|
|
606
|
+
join(', ', names.map((n) => schemaObjectName(n))),
|
|
607
|
+
';',
|
|
608
|
+
];
|
|
609
|
+
}
|
|
610
|
+
export function printDropIndex(node, opts) {
|
|
611
|
+
const indices = propArr(node, 'indices');
|
|
612
|
+
const indexDocs = indices.map((idx) => [propStr(idx, 'name') ?? '', ' ', keyword('ON', opts), ' ', schemaObjectName(prop(idx, 'table'))]);
|
|
613
|
+
return group([keyword('DROP INDEX', opts), ' ', join([',', hardline], indexDocs), ';']);
|
|
614
|
+
}
|
|
615
|
+
// ---------------------------------------------------------------------------
|
|
616
|
+
// CREATE / DROP SYNONYM
|
|
617
|
+
// ---------------------------------------------------------------------------
|
|
618
|
+
export function printCreateSynonym(node, opts) {
|
|
619
|
+
const name = schemaObjectName(prop(node, 'name'));
|
|
620
|
+
const forName = schemaObjectName(prop(node, 'forName'));
|
|
621
|
+
return [keyword('CREATE SYNONYM', opts), ' ', name, ' ', keyword('FOR', opts), ' ', forName, ';'];
|
|
622
|
+
}
|
|
623
|
+
// ---------------------------------------------------------------------------
|
|
624
|
+
// CREATE / ALTER / DROP SCHEMA
|
|
625
|
+
// ---------------------------------------------------------------------------
|
|
626
|
+
export function printCreateSchema(node, opts) {
|
|
627
|
+
const name = propStr(node, 'name') ?? '';
|
|
628
|
+
const owner = propStr(node, 'owner');
|
|
629
|
+
const ownerPart = owner ? [' ', keyword('AUTHORIZATION', opts), ' ', owner] : '';
|
|
630
|
+
return [keyword('CREATE SCHEMA', opts), ' ', name, ownerPart, ';'];
|
|
631
|
+
}
|
|
632
|
+
export function printAlterSchema(node, opts) {
|
|
633
|
+
const name = propStr(node, 'name') ?? '';
|
|
634
|
+
const objectKind = propStr(node, 'objectKind') ?? '';
|
|
635
|
+
const objectName = schemaObjectName(prop(node, 'objectName'));
|
|
636
|
+
// Emit the securable-type qualifier only when ScriptDom gives a non-default kind.
|
|
637
|
+
// ScriptDom uses "Object" for a plain table/view/proc (no explicit qualifier needed).
|
|
638
|
+
const kindMap = {
|
|
639
|
+
Type: 'TYPE',
|
|
640
|
+
XmlSchemaCollection: 'XML SCHEMA COLLECTION',
|
|
641
|
+
};
|
|
642
|
+
const qualifier = kindMap[objectKind];
|
|
643
|
+
const transferTarget = qualifier ? [keyword(qualifier, opts), '::', objectName] : objectName;
|
|
644
|
+
return [keyword('ALTER SCHEMA', opts), ' ', name, ' ', keyword('TRANSFER', opts), ' ', transferTarget, ';'];
|
|
645
|
+
}
|
|
646
|
+
export function printDropSchema(node, opts) {
|
|
647
|
+
const name = schemaObjectName(prop(node, 'name'));
|
|
648
|
+
const ifExists = propBool(node, 'ifExists');
|
|
649
|
+
return [keyword('DROP SCHEMA', opts), ifExistsDoc(ifExists, opts), ' ', name, ';'];
|
|
650
|
+
}
|
|
651
|
+
// ---------------------------------------------------------------------------
|
|
652
|
+
// CREATE / ALTER / DROP PARTITION FUNCTION
|
|
653
|
+
// ---------------------------------------------------------------------------
|
|
654
|
+
export function printCreatePartitionFunction(node, opts) {
|
|
655
|
+
const name = propStr(node, 'name') ?? '';
|
|
656
|
+
const paramType = propStr(node, 'paramType') ?? '';
|
|
657
|
+
const collation = propStr(node, 'collation');
|
|
658
|
+
const range = propStr(node, 'range');
|
|
659
|
+
const boundaryValues = propArr(node, 'boundaryValues');
|
|
660
|
+
const rangeKw = range === 'Right'
|
|
661
|
+
? keyword('RANGE RIGHT', opts)
|
|
662
|
+
: range === 'Left'
|
|
663
|
+
? keyword('RANGE LEFT', opts)
|
|
664
|
+
: keyword('RANGE', opts);
|
|
665
|
+
const collationPart = collation ? [' ', keyword('COLLATE', opts), ' ', collation] : '';
|
|
666
|
+
const valsDocs = boundaryValues.map((v) => printNode(v, opts));
|
|
667
|
+
const forValues = group([
|
|
668
|
+
keyword('FOR VALUES', opts),
|
|
669
|
+
' (',
|
|
670
|
+
indent([softline, join([',', line], valsDocs)]),
|
|
671
|
+
softline,
|
|
672
|
+
')',
|
|
673
|
+
]);
|
|
674
|
+
return [
|
|
675
|
+
keyword('CREATE PARTITION FUNCTION', opts),
|
|
676
|
+
' ',
|
|
677
|
+
name,
|
|
678
|
+
' (',
|
|
679
|
+
keyword(paramType, opts),
|
|
680
|
+
collationPart,
|
|
681
|
+
') ',
|
|
682
|
+
keyword('AS', opts),
|
|
683
|
+
' ',
|
|
684
|
+
rangeKw,
|
|
685
|
+
indent([hardline, forValues]),
|
|
686
|
+
';',
|
|
687
|
+
];
|
|
688
|
+
}
|
|
689
|
+
export function printAlterPartitionFunction(node, opts) {
|
|
690
|
+
const name = propStr(node, 'name') ?? '';
|
|
691
|
+
const isSplit = propBool(node, 'isSplit');
|
|
692
|
+
const boundary = prop(node, 'boundary');
|
|
693
|
+
const action = isSplit ? keyword('SPLIT RANGE', opts) : keyword('MERGE RANGE', opts);
|
|
694
|
+
return [
|
|
695
|
+
keyword('ALTER PARTITION FUNCTION', opts),
|
|
696
|
+
' ',
|
|
697
|
+
name,
|
|
698
|
+
'()',
|
|
699
|
+
indent([hardline, action, ' (', boundary ? printNode(boundary, opts) : '', ')']),
|
|
700
|
+
';',
|
|
701
|
+
];
|
|
702
|
+
}
|
|
703
|
+
export function printDropPartitionFunction(node, opts) {
|
|
704
|
+
const name = propStr(node, 'name') ?? '';
|
|
705
|
+
const ifExists = propBool(node, 'ifExists');
|
|
706
|
+
return [keyword('DROP PARTITION FUNCTION', opts), ifExistsDoc(ifExists, opts), ' ', name, ';'];
|
|
707
|
+
}
|
|
708
|
+
// ---------------------------------------------------------------------------
|
|
709
|
+
// CREATE / ALTER / DROP PARTITION SCHEME
|
|
710
|
+
// ---------------------------------------------------------------------------
|
|
711
|
+
export function printCreatePartitionScheme(node, opts) {
|
|
712
|
+
const name = propStr(node, 'name') ?? '';
|
|
713
|
+
const pf = propStr(node, 'partitionFunction') ?? '';
|
|
714
|
+
const isAll = propBool(node, 'isAll');
|
|
715
|
+
const fileGroups = propArr(node, 'fileGroups');
|
|
716
|
+
const fgDocs = fileGroups.map((fg) => String(fg));
|
|
717
|
+
const toClause = isAll
|
|
718
|
+
? [keyword('ALL TO', opts), ' (', join(', ', fgDocs), ')']
|
|
719
|
+
: [keyword('TO', opts), ' (', join(', ', fgDocs), ')'];
|
|
720
|
+
return [
|
|
721
|
+
keyword('CREATE PARTITION SCHEME', opts),
|
|
722
|
+
' ',
|
|
723
|
+
name,
|
|
724
|
+
indent([hardline, keyword('AS PARTITION', opts), ' ', pf, hardline, toClause]),
|
|
725
|
+
';',
|
|
726
|
+
];
|
|
727
|
+
}
|
|
728
|
+
export function printAlterPartitionScheme(node, opts) {
|
|
729
|
+
const name = propStr(node, 'name') ?? '';
|
|
730
|
+
const fileGroup = propStr(node, 'fileGroup');
|
|
731
|
+
const nextUsed = fileGroup ? [keyword('NEXT USED', opts), ' ', fileGroup] : keyword('NEXT USED', opts);
|
|
732
|
+
return [keyword('ALTER PARTITION SCHEME', opts), ' ', name, indent([hardline, nextUsed]), ';'];
|
|
733
|
+
}
|
|
734
|
+
export function printDropPartitionScheme(node, opts) {
|
|
735
|
+
const name = propStr(node, 'name') ?? '';
|
|
736
|
+
const ifExists = propBool(node, 'ifExists');
|
|
737
|
+
return [keyword('DROP PARTITION SCHEME', opts), ifExistsDoc(ifExists, opts), ' ', name, ';'];
|
|
738
|
+
}
|
|
739
|
+
// ---------------------------------------------------------------------------
|
|
740
|
+
// CREATE COLUMNSTORE INDEX
|
|
741
|
+
// ---------------------------------------------------------------------------
|
|
742
|
+
export function printCreateColumnStoreIndex(node, opts) {
|
|
743
|
+
const name = propStr(node, 'name') ?? '';
|
|
744
|
+
const clustered = node.props?.['clustered'];
|
|
745
|
+
const onName = prop(node, 'onName');
|
|
746
|
+
const columns = node.props?.['columns'];
|
|
747
|
+
const filterPredicate = propStr(node, 'filterPredicate');
|
|
748
|
+
const options = node.props?.['options'];
|
|
749
|
+
const clusterKw = clustered === true
|
|
750
|
+
? [keyword('CLUSTERED', opts), ' ']
|
|
751
|
+
: clustered === false
|
|
752
|
+
? [keyword('NONCLUSTERED', opts), ' ']
|
|
753
|
+
: '';
|
|
754
|
+
const parts = [keyword('CREATE', opts), ' ', clusterKw, keyword('COLUMNSTORE INDEX', opts), ' ', name];
|
|
755
|
+
parts.push([hardline, keyword('ON', opts), ' ', onName ? schemaObjectName(onName) : '']);
|
|
756
|
+
if (columns?.length) {
|
|
757
|
+
parts.push([' ', group(['(', indent([softline, join([',', line], columns)]), softline, ')'])]);
|
|
758
|
+
}
|
|
759
|
+
if (filterPredicate)
|
|
760
|
+
parts.push([hardline, keyword('WHERE', opts), ' ', filterPredicate]);
|
|
761
|
+
if (options?.length) {
|
|
762
|
+
parts.push([
|
|
763
|
+
hardline,
|
|
764
|
+
group([keyword('WITH', opts), ' (', indent([softline, join([',', line], options.map((o) => keyword(o, opts)))]), softline, ')']),
|
|
765
|
+
]);
|
|
766
|
+
}
|
|
767
|
+
parts.push(';');
|
|
768
|
+
return parts;
|
|
769
|
+
}
|
|
770
|
+
// ---------------------------------------------------------------------------
|
|
771
|
+
// ENABLE / DISABLE TRIGGER
|
|
772
|
+
// ---------------------------------------------------------------------------
|
|
773
|
+
export function printEnableDisableTrigger(node, opts) {
|
|
774
|
+
const enforcement = propStr(node, 'enforcement') ?? 'Enable';
|
|
775
|
+
const all = propBool(node, 'all');
|
|
776
|
+
const triggerNames = node.props?.['triggerNames'];
|
|
777
|
+
const targetScope = propStr(node, 'targetScope') ?? 'Normal';
|
|
778
|
+
const targetName = prop(node, 'targetName');
|
|
779
|
+
const verb = enforcement === 'Disable' ? 'DISABLE TRIGGER' : 'ENABLE TRIGGER';
|
|
780
|
+
const triggersDoc = all ? keyword('ALL', opts) : join(', ', (triggerNames ?? []).map((n) => n));
|
|
781
|
+
let onTarget;
|
|
782
|
+
if (targetScope === 'Database')
|
|
783
|
+
onTarget = keyword('DATABASE', opts);
|
|
784
|
+
else if (targetScope === 'AllServer')
|
|
785
|
+
onTarget = keyword('ALL SERVER', opts);
|
|
786
|
+
else
|
|
787
|
+
onTarget = targetName ? schemaObjectName(targetName) : '';
|
|
788
|
+
return [keyword(verb, opts), ' ', triggersDoc, hardline, keyword('ON', opts), ' ', onTarget, ';'];
|
|
789
|
+
}
|
|
790
|
+
// ---------------------------------------------------------------------------
|
|
791
|
+
// CREATE / UPDATE / DROP STATISTICS
|
|
792
|
+
// ---------------------------------------------------------------------------
|
|
793
|
+
export function printCreateStatistics(node, opts) {
|
|
794
|
+
const name = propStr(node, 'name') ?? '';
|
|
795
|
+
const onName = prop(node, 'onName');
|
|
796
|
+
const columns = node.props?.['columns'];
|
|
797
|
+
const filterPredicate = propStr(node, 'filterPredicate');
|
|
798
|
+
const options = node.props?.['options'];
|
|
799
|
+
const parts = [keyword('CREATE STATISTICS', opts), ' ', name];
|
|
800
|
+
parts.push([hardline, keyword('ON', opts), ' ', onName ? schemaObjectName(onName) : '']);
|
|
801
|
+
if (columns?.length) {
|
|
802
|
+
parts.push([' ', group(['(', indent([softline, join([',', line], columns)]), softline, ')'])]);
|
|
803
|
+
}
|
|
804
|
+
if (filterPredicate)
|
|
805
|
+
parts.push([hardline, keyword('WHERE', opts), ' ', filterPredicate]);
|
|
806
|
+
if (options?.length) {
|
|
807
|
+
parts.push([
|
|
808
|
+
hardline,
|
|
809
|
+
group([keyword('WITH', opts), indent([line, join([',', line], options.map((o) => keyword(o, opts)))])]),
|
|
810
|
+
]);
|
|
811
|
+
}
|
|
812
|
+
parts.push(';');
|
|
813
|
+
return parts;
|
|
814
|
+
}
|
|
815
|
+
export function printUpdateStatistics(node, opts) {
|
|
816
|
+
const table = prop(node, 'table');
|
|
817
|
+
const subElements = node.props?.['subElements'];
|
|
818
|
+
const options = node.props?.['options'];
|
|
819
|
+
const parts = [keyword('UPDATE STATISTICS', opts), ' ', table ? schemaObjectName(table) : ''];
|
|
820
|
+
if (subElements?.length) {
|
|
821
|
+
parts.push([' ', group(['(', indent([softline, join([',', line], subElements)]), softline, ')'])]);
|
|
822
|
+
}
|
|
823
|
+
if (options?.length) {
|
|
824
|
+
parts.push([
|
|
825
|
+
hardline,
|
|
826
|
+
group([keyword('WITH', opts), indent([line, join([',', line], options.map((o) => keyword(o, opts)))])]),
|
|
827
|
+
]);
|
|
828
|
+
}
|
|
829
|
+
parts.push(';');
|
|
830
|
+
return parts;
|
|
831
|
+
}
|
|
832
|
+
export function printDropStatistics(node, opts) {
|
|
833
|
+
const objects = node.props?.['objects'];
|
|
834
|
+
return [keyword('DROP STATISTICS', opts), ' ', join([',', hardline], (objects ?? []).map((o) => o)), ';'];
|
|
835
|
+
}
|
|
836
|
+
//# sourceMappingURL=ddl.js.map
|