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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +199 -0
  3. package/bin/dotnet/Microsoft.SqlServer.TransactSql.ScriptDom.dll +0 -0
  4. package/bin/dotnet/SqlScriptDom.deps.json +41 -0
  5. package/bin/dotnet/SqlScriptDom.dll +0 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +21 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/language.d.ts +3 -0
  11. package/dist/language.d.ts.map +1 -0
  12. package/dist/language.js +9 -0
  13. package/dist/language.js.map +1 -0
  14. package/dist/options.d.ts +3 -0
  15. package/dist/options.d.ts.map +1 -0
  16. package/dist/options.js +35 -0
  17. package/dist/options.js.map +1 -0
  18. package/dist/parser/index.d.ts +5 -0
  19. package/dist/parser/index.d.ts.map +1 -0
  20. package/dist/parser/index.js +263 -0
  21. package/dist/parser/index.js.map +1 -0
  22. package/dist/parser/types.d.ts +21 -0
  23. package/dist/parser/types.d.ts.map +1 -0
  24. package/dist/parser/types.js +2 -0
  25. package/dist/parser/types.js.map +1 -0
  26. package/dist/printer/admin.d.ts +22 -0
  27. package/dist/printer/admin.d.ts.map +1 -0
  28. package/dist/printer/admin.js +250 -0
  29. package/dist/printer/admin.js.map +1 -0
  30. package/dist/printer/ddl.d.ts +36 -0
  31. package/dist/printer/ddl.d.ts.map +1 -0
  32. package/dist/printer/ddl.js +836 -0
  33. package/dist/printer/ddl.js.map +1 -0
  34. package/dist/printer/expressions.d.ts +11 -0
  35. package/dist/printer/expressions.d.ts.map +1 -0
  36. package/dist/printer/expressions.js +1475 -0
  37. package/dist/printer/expressions.js.map +1 -0
  38. package/dist/printer/helpers.d.ts +25 -0
  39. package/dist/printer/helpers.d.ts.map +1 -0
  40. package/dist/printer/helpers.js +61 -0
  41. package/dist/printer/helpers.js.map +1 -0
  42. package/dist/printer/index.d.ts +4 -0
  43. package/dist/printer/index.d.ts.map +1 -0
  44. package/dist/printer/index.js +30 -0
  45. package/dist/printer/index.js.map +1 -0
  46. package/dist/printer/procedural.d.ts +41 -0
  47. package/dist/printer/procedural.d.ts.map +1 -0
  48. package/dist/printer/procedural.js +364 -0
  49. package/dist/printer/procedural.js.map +1 -0
  50. package/dist/printer/security.d.ts +15 -0
  51. package/dist/printer/security.d.ts.map +1 -0
  52. package/dist/printer/security.js +309 -0
  53. package/dist/printer/security.js.map +1 -0
  54. package/dist/printer/statements.d.ts +18 -0
  55. package/dist/printer/statements.d.ts.map +1 -0
  56. package/dist/printer/statements.js +689 -0
  57. package/dist/printer/statements.js.map +1 -0
  58. package/dist/printer/utils.d.ts +34 -0
  59. package/dist/printer/utils.d.ts.map +1 -0
  60. package/dist/printer/utils.js +61 -0
  61. package/dist/printer/utils.js.map +1 -0
  62. 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