@sap/cds-compiler 5.9.4 → 6.0.12
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/CHANGELOG.md +117 -319
- package/README.md +1 -1
- package/bin/cds_update_identifiers.js +3 -5
- package/bin/cdsc.js +24 -9
- package/bin/cdshi.js +1 -1
- package/bin/cdsse.js +4 -4
- package/doc/CHANGELOG_BETA.md +11 -0
- package/doc/CHANGELOG_DEPRECATED.md +29 -0
- package/lib/api/main.js +8 -5
- package/lib/api/options.js +12 -10
- package/lib/base/builtins.js +1 -0
- package/lib/base/message-registry.js +191 -99
- package/lib/base/messages.js +35 -21
- package/lib/base/model.js +14 -24
- package/lib/checks/actionsFunctions.js +10 -20
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/elements.js +35 -10
- package/lib/checks/enums.js +31 -0
- package/lib/checks/foreignKeys.js +2 -2
- package/lib/checks/hasPersistedElements.js +5 -0
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/managedWithoutKeys.js +5 -4
- package/lib/checks/queryNoDbArtifacts.js +10 -8
- package/lib/checks/types.js +5 -5
- package/lib/checks/validator.js +6 -4
- package/lib/compiler/assert-consistency.js +13 -9
- package/lib/compiler/checks.js +20 -52
- package/lib/compiler/define.js +31 -6
- package/lib/compiler/extend.js +5 -1
- package/lib/compiler/generate.js +14 -17
- package/lib/compiler/populate.js +8 -31
- package/lib/compiler/propagator.js +21 -35
- package/lib/compiler/resolve.js +64 -29
- package/lib/compiler/shared.js +16 -4
- package/lib/compiler/tweak-assocs.js +1 -1
- package/lib/compiler/utils.js +1 -1
- package/lib/edm/annotations/edmJson.js +23 -20
- package/lib/edm/annotations/genericTranslation.js +12 -10
- package/lib/edm/csn2edm.js +50 -56
- package/lib/edm/edm.js +33 -28
- package/lib/edm/edmInboundChecks.js +2 -2
- package/lib/edm/edmPreprocessor.js +54 -88
- package/lib/edm/edmUtils.js +9 -12
- package/lib/gen/BaseParser.js +63 -52
- package/lib/gen/CdlGrammar.checksum +1 -1
- package/lib/gen/CdlParser.js +1153 -1165
- package/lib/gen/Dictionary.json +21 -1
- package/lib/json/from-csn.js +70 -43
- package/lib/json/to-csn.js +6 -8
- package/lib/language/multiLineStringParser.js +3 -2
- package/lib/main.d.ts +58 -24
- package/lib/model/cloneCsn.js +3 -0
- package/lib/model/csnUtils.js +28 -39
- package/lib/model/xprAsTree.js +23 -9
- package/lib/modelCompare/compare.js +5 -4
- package/lib/optionProcessor.js +24 -17
- package/lib/parsers/AstBuildingParser.js +81 -25
- package/lib/parsers/XprTree.js +57 -3
- package/lib/parsers/identifiers.js +1 -1
- package/lib/parsers/index.js +0 -3
- package/lib/render/manageConstraints.js +25 -25
- package/lib/render/toCdl.js +173 -170
- package/lib/render/toHdbcds.js +126 -128
- package/lib/render/toRename.js +7 -7
- package/lib/render/toSql.js +128 -125
- package/lib/render/utils/common.js +47 -22
- package/lib/render/utils/delta.js +25 -25
- package/lib/render/utils/operators.js +2 -2
- package/lib/render/utils/pretty.js +5 -5
- package/lib/render/utils/sql.js +13 -13
- package/lib/render/utils/standardDatabaseFunctions.js +115 -103
- package/lib/render/utils/unique.js +4 -4
- package/lib/transform/db/applyTransformations.js +1 -1
- package/lib/transform/db/assertUnique.js +2 -2
- package/lib/transform/db/associations.js +6 -7
- package/lib/transform/db/assocsToQueries/utils.js +4 -5
- package/lib/transform/db/backlinks.js +12 -9
- package/lib/transform/db/cdsPersistence.js +8 -7
- package/lib/transform/db/constraints.js +13 -10
- package/lib/transform/db/expansion.js +7 -3
- package/lib/transform/db/flattening.js +4 -14
- package/lib/transform/db/processSqlServices.js +2 -1
- package/lib/transform/db/temporal.js +5 -7
- package/lib/transform/db/views.js +2 -4
- package/lib/transform/draft/db.js +8 -8
- package/lib/transform/draft/odata.js +10 -7
- package/lib/transform/forOdata.js +10 -5
- package/lib/transform/forRelationalDB.js +5 -75
- package/lib/transform/localized.js +1 -1
- package/lib/transform/odata/createForeignKeys.js +11 -10
- package/lib/transform/odata/flattening.js +8 -4
- package/lib/transform/odata/foreignKeyRefsInXprAnnos.js +96 -0
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/transformUtils.js +4 -8
- package/lib/transform/translateAssocsToJoins.js +14 -7
- package/lib/transform/universalCsn/universalCsnEnricher.js +10 -4
- package/lib/utils/objectUtils.js +0 -17
- package/package.json +10 -13
- package/share/messages/def-upcoming-virtual-change.md +1 -1
- package/LICENSE +0 -37
- package/bin/cds_remove_invalid_whitespace.js +0 -138
- package/doc/CHANGELOG_ARCHIVE.md +0 -3604
- package/lib/gen/genericAntlrParser.js +0 -3
- package/lib/gen/language.checksum +0 -1
- package/lib/gen/language.interp +0 -456
- package/lib/gen/language.tokens +0 -180
- package/lib/gen/languageLexer.interp +0 -439
- package/lib/gen/languageLexer.js +0 -1483
- package/lib/gen/languageLexer.tokens +0 -167
- package/lib/gen/languageParser.js +0 -24941
- package/lib/language/antlrParser.js +0 -205
- package/lib/language/errorStrategy.js +0 -646
- package/lib/language/genericAntlrParser.js +0 -1572
- package/lib/parsers/CdlGrammar.g4 +0 -2070
|
@@ -37,7 +37,7 @@ function renderFunc( funcName, node, renderArgs, utils ) {
|
|
|
37
37
|
const { sqlDialect } = options;
|
|
38
38
|
if (funcWithoutParen( node, sqlDialect ))
|
|
39
39
|
return funcName;
|
|
40
|
-
const rewriteStandardFunctions = options.transformation !== 'hdbcds' && sqlDialect !== 'plain' && options.standardDatabaseFunctions;
|
|
40
|
+
const rewriteStandardFunctions = options.transformation !== 'hdbcds' && sqlDialect !== 'plain' && options.standardDatabaseFunctions !== false;
|
|
41
41
|
if (rewriteStandardFunctions) {
|
|
42
42
|
// we check function arguments for correctness
|
|
43
43
|
const { error } = messageFunctions;
|
|
@@ -47,7 +47,7 @@ function renderFunc( funcName, node, renderArgs, utils ) {
|
|
|
47
47
|
else if (standardDatabaseFunctions.common[funcName])
|
|
48
48
|
return standardDatabaseFunctions.common[funcName].call(that, node);
|
|
49
49
|
}
|
|
50
|
-
return `${funcName}(${renderArgs( node )})`;
|
|
50
|
+
return `${ funcName }(${ renderArgs( node ) })`;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
/**
|
|
@@ -214,7 +214,7 @@ function getIntermediateContextNames( csn, parentName, artifactName ) {
|
|
|
214
214
|
*/
|
|
215
215
|
function addMissingChildContexts( csn, artifactName, killList ) {
|
|
216
216
|
// Get all other definitions sharing the same prefix, sorted by shortest first
|
|
217
|
-
const possibleNames = Object.keys(csn.definitions).filter(name => name.startsWith(`${artifactName}.`)).sort((a, b) => a.length - b.length);
|
|
217
|
+
const possibleNames = Object.keys(csn.definitions).filter(name => name.startsWith(`${ artifactName }.`)).sort((a, b) => a.length - b.length);
|
|
218
218
|
for (const name of possibleNames) {
|
|
219
219
|
const artifact = csn.definitions[name];
|
|
220
220
|
if (!artifact.$ignore && !hasValidSkipOrExists(artifact))
|
|
@@ -223,7 +223,7 @@ function addMissingChildContexts( csn, artifactName, killList ) {
|
|
|
223
223
|
|
|
224
224
|
function addPossibleGaps( possibleGaps, gapArtifactName ) {
|
|
225
225
|
for (const gap of possibleGaps) {
|
|
226
|
-
gapArtifactName += `.${gap}`;
|
|
226
|
+
gapArtifactName += `.${ gap }`;
|
|
227
227
|
if (!csn.definitions[gapArtifactName]) {
|
|
228
228
|
const contextName = gapArtifactName;
|
|
229
229
|
csn.definitions[contextName] = {
|
|
@@ -378,7 +378,12 @@ const variablesToSql = {
|
|
|
378
378
|
'$at.to': "TO_TIMESTAMP(SESSION_CONTEXT('VALID-TO'))",
|
|
379
379
|
'$valid.from': "TO_TIMESTAMP(SESSION_CONTEXT('VALID-FROM'))",
|
|
380
380
|
'$valid.to': "TO_TIMESTAMP(SESSION_CONTEXT('VALID-TO'))",
|
|
381
|
-
$now: '
|
|
381
|
+
$now: "TO_TIMESTAMP(SESSION_CONTEXT('NOW'))",
|
|
382
|
+
// special handling, see variableForDialect()
|
|
383
|
+
'$now.deprecated': 'CURRENT_TIMESTAMP',
|
|
384
|
+
// special handling, see variableForDialect()
|
|
385
|
+
// in DEFAULT, we can't render SESSION_CONTEXT
|
|
386
|
+
'$now.default': 'CURRENT_TIMESTAMP',
|
|
382
387
|
},
|
|
383
388
|
postgres: {
|
|
384
389
|
'$user.id': "current_setting('cap.applicationuser')",
|
|
@@ -388,7 +393,9 @@ const variablesToSql = {
|
|
|
388
393
|
'$at.to': "current_setting('cap.valid_to')::timestamp",
|
|
389
394
|
'$valid.from': "current_setting('cap.valid_from')::timestamp",
|
|
390
395
|
'$valid.to': "current_setting('cap.valid_to')::timestamp",
|
|
391
|
-
$now: '
|
|
396
|
+
$now: "current_setting('cap.now')::timestamp",
|
|
397
|
+
'$now.deprecated': 'current_timestamp',
|
|
398
|
+
'$now.default': 'current_timestamp',
|
|
392
399
|
},
|
|
393
400
|
sqlite: {
|
|
394
401
|
'$user.id': "session_context( '$user.id' )",
|
|
@@ -398,7 +405,9 @@ const variablesToSql = {
|
|
|
398
405
|
'$at.to': "session_context( '$valid.to' )",
|
|
399
406
|
'$valid.from': "session_context( '$valid.from' )",
|
|
400
407
|
'$valid.to': "session_context( '$valid.to' )",
|
|
401
|
-
$now: '
|
|
408
|
+
$now: "session_context( '$now' )",
|
|
409
|
+
'$now.deprecated': 'CURRENT_TIMESTAMP',
|
|
410
|
+
'$now.default': 'CURRENT_TIMESTAMP',
|
|
402
411
|
},
|
|
403
412
|
'old-sqlite': {
|
|
404
413
|
// For sqlite, we render the string-format-time (strftime) function.
|
|
@@ -420,7 +429,9 @@ const variablesToSql = {
|
|
|
420
429
|
'$at.to': "session_context( '$valid.to' )",
|
|
421
430
|
'$valid.from': "session_context( '$valid.from' )",
|
|
422
431
|
'$valid.to': "session_context( '$valid.to' )",
|
|
423
|
-
$now: '
|
|
432
|
+
$now: "session_context( '$now' )",
|
|
433
|
+
'$now.deprecated': 'CURRENT_TIMESTAMP',
|
|
434
|
+
'$now.default': 'CURRENT_TIMESTAMP',
|
|
424
435
|
},
|
|
425
436
|
h2: {
|
|
426
437
|
'$user.id': '@applicationuser',
|
|
@@ -430,7 +441,9 @@ const variablesToSql = {
|
|
|
430
441
|
'$at.to': '@valid_to',
|
|
431
442
|
'$valid.from': '@valid_from',
|
|
432
443
|
'$valid.to': '@valid_to',
|
|
433
|
-
$now: '
|
|
444
|
+
$now: '@now',
|
|
445
|
+
'$now.deprecated': 'current_timestamp',
|
|
446
|
+
'$now.default': 'current_timestamp',
|
|
434
447
|
},
|
|
435
448
|
};
|
|
436
449
|
|
|
@@ -439,15 +452,29 @@ const variablesToSql = {
|
|
|
439
452
|
* Note that this function does not handle `variableReplacements`. Callers should
|
|
440
453
|
* first check if the user has specified them and use them instead.
|
|
441
454
|
*
|
|
442
|
-
* @param {SqlOptions} options
|
|
443
|
-
*
|
|
444
|
-
* @
|
|
455
|
+
* @param {SqlOptions} options
|
|
456
|
+
* Used for `sqlDialect` and better-sqlite option.
|
|
457
|
+
* @param {string} variable
|
|
458
|
+
* Variable to render, e.g. `$user.id`.
|
|
459
|
+
* @param {null|'default'} [context = null]
|
|
460
|
+
* A context in which the variable is used. Some variables are translated
|
|
461
|
+
* context-dependent, such as '$now'.
|
|
462
|
+
*
|
|
463
|
+
* @return {string|null}
|
|
464
|
+
* `null` if the variable could not be found for the given dialect and in the fallback values.
|
|
445
465
|
*/
|
|
446
|
-
function variableForDialect( options, variable ) {
|
|
466
|
+
function variableForDialect( options, variable, context = null ) {
|
|
447
467
|
const dialect = options.sqlDialect === 'sqlite' && options.betterSqliteSessionVariables === false
|
|
448
468
|
? 'old-sqlite'
|
|
449
469
|
: options.sqlDialect;
|
|
450
|
-
|
|
470
|
+
|
|
471
|
+
if (options.dollarNowAsTimestamp === true && variable === '$now')
|
|
472
|
+
return variablesToSql.hana['$now.deprecated'] ?? variablesToSql.hana.$now;
|
|
473
|
+
|
|
474
|
+
return variablesToSql[dialect]?.[`${ variable }.${ context }`] ||
|
|
475
|
+
variablesToSql[dialect]?.[variable] ||
|
|
476
|
+
variablesToSql.fallback[variable] ||
|
|
477
|
+
null;
|
|
451
478
|
}
|
|
452
479
|
|
|
453
480
|
/**
|
|
@@ -546,8 +573,8 @@ function getHanaComment( obj ) {
|
|
|
546
573
|
* @returns {object} object with .front and .back
|
|
547
574
|
*/
|
|
548
575
|
function getSqlSnippets( options, obj ) {
|
|
549
|
-
const front = obj['@sql.prepend'] ? `${obj['@sql.prepend']} ` : '';
|
|
550
|
-
const back = obj['@sql.append'] ? ` ${obj['@sql.append']}` : '';
|
|
576
|
+
const front = obj['@sql.prepend'] ? `${ obj['@sql.prepend'] } ` : '';
|
|
577
|
+
const back = obj['@sql.append'] ? ` ${ obj['@sql.append'] }` : '';
|
|
551
578
|
|
|
552
579
|
return { front, back };
|
|
553
580
|
}
|
|
@@ -571,7 +598,6 @@ function getSqlSnippets( options, obj ) {
|
|
|
571
598
|
* @property {renderPart} val
|
|
572
599
|
* @property {renderPart} enum
|
|
573
600
|
* @property {renderPart} ref
|
|
574
|
-
* @property {renderPart} aliasOnly
|
|
575
601
|
* @property {renderPart} windowFunction
|
|
576
602
|
* @property {renderPart} func
|
|
577
603
|
* @property {renderPart} xpr
|
|
@@ -591,7 +617,6 @@ function getSqlSnippets( options, obj ) {
|
|
|
591
617
|
* @property {renderPart} val
|
|
592
618
|
* @property {renderPart} enum
|
|
593
619
|
* @property {renderPart} ref
|
|
594
|
-
* @property {renderPart} aliasOnly
|
|
595
620
|
* @property {renderPart} windowFunction
|
|
596
621
|
* @property {renderPart} func
|
|
597
622
|
* @property {renderPart} xpr
|
|
@@ -688,12 +713,12 @@ function visitExpr( x ) {
|
|
|
688
713
|
}
|
|
689
714
|
else if (x.list) {
|
|
690
715
|
// Render as non-nested expr.
|
|
691
|
-
return `(${x.list.map((item, i) => {
|
|
716
|
+
return `(${ x.list.map((item, i) => {
|
|
692
717
|
this.env.path.push('list', i);
|
|
693
718
|
const result = this.renderExpr(item, this.env);
|
|
694
719
|
this.env.path.length -= 2;
|
|
695
720
|
return result;
|
|
696
|
-
}).join(', ')})`;
|
|
721
|
+
}).join(', ') })`;
|
|
697
722
|
}
|
|
698
723
|
else if (x['#']) {
|
|
699
724
|
// Enum symbol
|
|
@@ -722,10 +747,10 @@ function visitExpr( x ) {
|
|
|
722
747
|
return this.SET(x);
|
|
723
748
|
}
|
|
724
749
|
else if (x.as) {
|
|
725
|
-
return
|
|
750
|
+
return '';
|
|
726
751
|
}
|
|
727
752
|
|
|
728
|
-
throw new ModelError(`renderExpr(): Unknown expression: ${JSON.stringify(x)}`);
|
|
753
|
+
throw new ModelError(`renderExpr(): Unknown expression: ${ JSON.stringify(x) }`);
|
|
729
754
|
}
|
|
730
755
|
|
|
731
756
|
module.exports = {
|
|
@@ -13,7 +13,7 @@ class DeltaRenderer {
|
|
|
13
13
|
* Render column additions as SQL. Checks for duplicate elements.
|
|
14
14
|
*/
|
|
15
15
|
addColumnsFromElementStrings(artifactName, eltStrings) {
|
|
16
|
-
return eltStrings.map(eltString => `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ADD ${eltString};`);
|
|
16
|
+
return eltStrings.map(eltString => `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ADD ${ eltString };`);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
@@ -44,14 +44,14 @@ class DeltaRenderer {
|
|
|
44
44
|
* Render key addition as SQL.
|
|
45
45
|
*/
|
|
46
46
|
addKey(artifactName, elementsObj) {
|
|
47
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ADD ${this.primaryKey(elementsObj)};` ];
|
|
47
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ADD ${ this.primaryKey(elementsObj) };` ];
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Render column removals as SQL.
|
|
52
52
|
*/
|
|
53
53
|
dropColumns(artifactName, sqlIds) {
|
|
54
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} DROP ${sqlIds.join(', ')};` ];
|
|
54
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } DROP ${ sqlIds.join(', ') };` ];
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
@@ -65,7 +65,7 @@ class DeltaRenderer {
|
|
|
65
65
|
* Render primary-key removals as SQL.
|
|
66
66
|
*/
|
|
67
67
|
dropKey(artifactName) {
|
|
68
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} DROP PRIMARY KEY;` ];
|
|
68
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } DROP PRIMARY KEY;` ];
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -73,13 +73,13 @@ class DeltaRenderer {
|
|
|
73
73
|
*/
|
|
74
74
|
alterColumns(artifactName, columnName, delta, definitionsStr, _eltName, _env) {
|
|
75
75
|
if (Array.isArray(definitionsStr)) {
|
|
76
|
-
const prefix = `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER (`;
|
|
76
|
+
const prefix = `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER (`;
|
|
77
77
|
const padding = ' '.repeat(prefix.length);
|
|
78
78
|
const body = definitionsStr.map(s => padding + s).join(',\n').slice(padding.length); // no padding for first part
|
|
79
79
|
const postfix = ');';
|
|
80
80
|
return [ prefix + body + postfix ];
|
|
81
81
|
}
|
|
82
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER (${definitionsStr});` ];
|
|
82
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER (${ definitionsStr });` ];
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
@@ -90,21 +90,21 @@ class DeltaRenderer {
|
|
|
90
90
|
.filter(name => elementsObj[name].key && !elementsObj[name].virtual)
|
|
91
91
|
.map(name => this.scopedFunctions.quoteSqlId(name))
|
|
92
92
|
.join(', ');
|
|
93
|
-
return primaryKeys && `PRIMARY KEY(${primaryKeys})`;
|
|
93
|
+
return primaryKeys && `PRIMARY KEY(${ primaryKeys })`;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
97
|
* Render entity-comment modifications as SQL.
|
|
98
98
|
*/
|
|
99
99
|
alterEntityComment(artifactName, comment) {
|
|
100
|
-
return [ `COMMENT ON TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} IS ${this.comment(comment)};` ];
|
|
100
|
+
return [ `COMMENT ON TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } IS ${ this.comment(comment) };` ];
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
/**
|
|
104
104
|
* Render column-comment modifications as SQL.
|
|
105
105
|
*/
|
|
106
106
|
alterColumnComment(artifactName, columnName, comment) {
|
|
107
|
-
return [ `COMMENT ON COLUMN ${this.scopedFunctions.renderArtifactName(artifactName)}.${columnName} IS ${this.comment(comment)};` ];
|
|
107
|
+
return [ `COMMENT ON COLUMN ${ this.scopedFunctions.renderArtifactName(artifactName) }.${ columnName } IS ${ this.comment(comment) };` ];
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
/**
|
|
@@ -118,7 +118,7 @@ class DeltaRenderer {
|
|
|
118
118
|
* Alter SQL snippet for entity.
|
|
119
119
|
*/
|
|
120
120
|
alterEntitySqlSnippet(artifactName, snippet) {
|
|
121
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ${snippet};` ];
|
|
121
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ${ snippet };` ];
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/**
|
|
@@ -147,7 +147,7 @@ class DeltaRendererHana extends DeltaRenderer {
|
|
|
147
147
|
*/
|
|
148
148
|
alterColumns(artifactName, columnName, delta, definitionsStr, _eltName, _env) {
|
|
149
149
|
if (delta.details)
|
|
150
|
-
this.#details.push(`-- [WARNING] this statement could ${delta.lossy ? 'be lossy' : 'fail'}: ${delta.details}`);
|
|
150
|
+
this.#details.push(`-- [WARNING] this statement could ${ delta.lossy ? 'be lossy' : 'fail' }: ${ delta.details }`);
|
|
151
151
|
|
|
152
152
|
this.#alters.push(definitionsStr);
|
|
153
153
|
return [];
|
|
@@ -157,7 +157,7 @@ class DeltaRendererHana extends DeltaRenderer {
|
|
|
157
157
|
* Render column additions as HANA SQL. Checks for duplicate elements.
|
|
158
158
|
*/
|
|
159
159
|
addColumnsFromElementStrings(artifactName, eltStrings) {
|
|
160
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ADD (${eltStrings.join(', ')});` ];
|
|
160
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ADD (${ eltStrings.join(', ') });` ];
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/**
|
|
@@ -168,21 +168,21 @@ class DeltaRendererHana extends DeltaRenderer {
|
|
|
168
168
|
return Object.entries(elementsObj)
|
|
169
169
|
.map(([ name, elt ]) => this.scopedFunctions.renderAssociationElement(name, elt, env))
|
|
170
170
|
.filter(s => s !== '')
|
|
171
|
-
.map(eltStr => `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ADD ASSOCIATION (${eltStr});`);
|
|
171
|
+
.map(eltStr => `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ADD ASSOCIATION (${ eltStr });`);
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
/**
|
|
175
175
|
* Render column removals as HANA SQL.
|
|
176
176
|
*/
|
|
177
177
|
dropColumns(artifactName, sqlIds) {
|
|
178
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} DROP (${sqlIds.join(', ')});` ];
|
|
178
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } DROP (${ sqlIds.join(', ') });` ];
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
182
|
* Render association removals as HANA SQL.
|
|
183
183
|
*/
|
|
184
184
|
dropAssociation(artifactName, sqlId) {
|
|
185
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} DROP ASSOCIATION ${sqlId};` ];
|
|
185
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } DROP ASSOCIATION ${ sqlId };` ];
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -193,15 +193,15 @@ class DeltaRendererPostgres extends DeltaRenderer {
|
|
|
193
193
|
*/
|
|
194
194
|
dropKey(artifactName) {
|
|
195
195
|
const table = this.scopedFunctions.renderArtifactName(artifactName);
|
|
196
|
-
const pkey = this.scopedFunctions.renderArtifactName(`${artifactName}_pkey`);
|
|
197
|
-
return [ `ALTER TABLE ${table} DROP CONSTRAINT ${pkey};` ];
|
|
196
|
+
const pkey = this.scopedFunctions.renderArtifactName(`${ artifactName }_pkey`);
|
|
197
|
+
return [ `ALTER TABLE ${ table } DROP CONSTRAINT ${ pkey };` ];
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
/**
|
|
201
201
|
* Render column removals as SQL.
|
|
202
202
|
*/
|
|
203
203
|
dropColumns(artifactName, sqlIds) {
|
|
204
|
-
return sqlIds.map(sqlId => `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} DROP ${sqlId};`);
|
|
204
|
+
return sqlIds.map(sqlId => `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } DROP ${ sqlId };`);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
/**
|
|
@@ -213,24 +213,24 @@ class DeltaRendererPostgres extends DeltaRenderer {
|
|
|
213
213
|
definitionsStr = this.#removeNullabilityFromElementString(delta, definitionsStr);
|
|
214
214
|
|
|
215
215
|
if (delta.old.default && !delta.old.value) // Drop old default if any exists
|
|
216
|
-
sqls.push(`ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER COLUMN ${columnName} DROP DEFAULT;`);
|
|
216
|
+
sqls.push(`ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER COLUMN ${ columnName } DROP DEFAULT;`);
|
|
217
217
|
|
|
218
218
|
if (delta.new.default && !delta.new.value ) { // Alter column with default
|
|
219
219
|
const df = delta.new.default;
|
|
220
220
|
delete delta.new.default;
|
|
221
221
|
const eltStrNoDefault = this.#removeNullabilityFromElementString(delta, this.scopedFunctions.renderElement(eltName, delta.new, null, null, env));
|
|
222
222
|
delta.new.default = df;
|
|
223
|
-
sqls.push(`ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER ${eltStrNoDefault};`);
|
|
224
|
-
sqls.push(`ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER COLUMN ${columnName} SET DEFAULT ${this.scopedFunctions.renderExpr(delta.new.default, env.withSubPath('default'))};`);
|
|
223
|
+
sqls.push(`ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER ${ eltStrNoDefault };`);
|
|
224
|
+
sqls.push(`ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER COLUMN ${ columnName } SET DEFAULT ${ this.scopedFunctions.renderExpr(delta.new.default, env.withSubPath('default')) };`);
|
|
225
225
|
}
|
|
226
226
|
else { // Alter column without default
|
|
227
|
-
sqls.push(`ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER ${definitionsStr};`);
|
|
227
|
+
sqls.push(`ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER ${ definitionsStr };`);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
if (delta.new.notNull && !delta.old.notNull)
|
|
231
|
-
sqls.push(`ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER ${columnName} SET NOT NULL;`);
|
|
231
|
+
sqls.push(`ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER ${ columnName } SET NOT NULL;`);
|
|
232
232
|
else if (delta.old.notNull && !delta.new.notNull)
|
|
233
|
-
sqls.push(`ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER ${columnName} DROP NOT NULL;`);
|
|
233
|
+
sqls.push(`ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER ${ columnName } DROP NOT NULL;`);
|
|
234
234
|
|
|
235
235
|
return sqls;
|
|
236
236
|
}
|
|
@@ -261,7 +261,7 @@ class DeltaRendererH2 extends DeltaRenderer {
|
|
|
261
261
|
* Render column modifications as H2 SQL - no ().
|
|
262
262
|
*/
|
|
263
263
|
alterColumns(artifactName, columnName, delta, definitionsStr, _eltName, _env) {
|
|
264
|
-
return [ `ALTER TABLE ${this.scopedFunctions.renderArtifactName(artifactName)} ALTER ${definitionsStr};` ];
|
|
264
|
+
return [ `ALTER TABLE ${ this.scopedFunctions.renderArtifactName(artifactName) } ALTER ${ definitionsStr };` ];
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
|
|
@@ -116,8 +116,8 @@ function transformExprOperators( xpr, options, messageFunctions, env ) {
|
|
|
116
116
|
const sqlDialect = options.sqlDialect || 'plain';
|
|
117
117
|
const operators = Object.assign(Object.create(null), operatorsPerDialect[sqlDialect] || operatorsPerDialect.plain);
|
|
118
118
|
|
|
119
|
-
if (
|
|
120
|
-
// don't translate `!=` if the option
|
|
119
|
+
if (options.booleanEquality === false) {
|
|
120
|
+
// don't translate `!=` if the option is set to false (for backward compatibility with v5)
|
|
121
121
|
delete operators['!='];
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -44,7 +44,7 @@ class Line extends Doc {
|
|
|
44
44
|
this._indent = n;
|
|
45
45
|
}
|
|
46
46
|
toString() {
|
|
47
|
-
return `\n${' '.repeat(this._indent)}`;
|
|
47
|
+
return `\n${ ' '.repeat(this._indent) }`;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -127,7 +127,7 @@ function flatten( doc ) {
|
|
|
127
127
|
return doc.x;
|
|
128
128
|
else if (typeof doc === 'string')
|
|
129
129
|
return doc;
|
|
130
|
-
throw new Error(`unhandled case: ${typeof doc}`);
|
|
130
|
+
throw new Error(`unhandled case: ${ typeof doc }`);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**
|
|
@@ -152,7 +152,7 @@ function nestBy( n, doc ) {
|
|
|
152
152
|
return String(doc); // nesting absorbed by string
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
-
throw new Error(`unhandled case: ${typeof doc}`);
|
|
155
|
+
throw new Error(`unhandled case: ${ typeof doc }`);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
/**
|
|
@@ -243,7 +243,7 @@ function be( width, k, i, doc ) {
|
|
|
243
243
|
}
|
|
244
244
|
return result;
|
|
245
245
|
}
|
|
246
|
-
throw new Error(`unhandled case: ${typeof doc}`);
|
|
246
|
+
throw new Error(`unhandled case: ${ typeof doc }`);
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
/**
|
|
@@ -288,7 +288,7 @@ function layout( doc ) {
|
|
|
288
288
|
return doc.toString();
|
|
289
289
|
else if (typeof doc === 'string')
|
|
290
290
|
return doc;
|
|
291
|
-
throw new Error(`unhandled case: ${typeof doc}`);
|
|
291
|
+
throw new Error(`unhandled case: ${ typeof doc }`);
|
|
292
292
|
}
|
|
293
293
|
|
|
294
294
|
/**
|
package/lib/render/utils/sql.js
CHANGED
|
@@ -33,32 +33,32 @@ function renderReferentialConstraint( constraint, indent, toUpperCase, csn, opti
|
|
|
33
33
|
|
|
34
34
|
const { sqlMapping, sqlDialect } = options;
|
|
35
35
|
let result = '';
|
|
36
|
-
result += `${indent}CONSTRAINT ${quoteId(constraint.identifier)}\n`;
|
|
36
|
+
result += `${ indent }CONSTRAINT ${ quoteId(constraint.identifier) }\n`;
|
|
37
37
|
if (renderAsHdbconstraint)
|
|
38
|
-
result += `${indent}ON ${quoteId(getResultingName(csn, sqlMapping, constraint.dependentTable))}\n`;
|
|
38
|
+
result += `${ indent }ON ${ quoteId(getResultingName(csn, sqlMapping, constraint.dependentTable)) }\n`;
|
|
39
39
|
if (!alterConstraint) {
|
|
40
|
-
result += `${indent}FOREIGN KEY(${constraint.foreignKey.map(quoteId).join(', ')})\n`;
|
|
41
|
-
result += `${indent}REFERENCES ${quoteId(getResultingName(csn, sqlMapping, constraint.parentTable))}(${constraint.parentKey.map(quoteId).join(', ')})\n`;
|
|
42
|
-
const onDeleteRemark = constraint.onDeleteRemark ? ` -- ${constraint.onDeleteRemark}` : '';
|
|
40
|
+
result += `${ indent }FOREIGN KEY(${ constraint.foreignKey.map(quoteId).join(', ') })\n`;
|
|
41
|
+
result += `${ indent }REFERENCES ${ quoteId(getResultingName(csn, sqlMapping, constraint.parentTable)) }(${ constraint.parentKey.map(quoteId).join(', ') })\n`;
|
|
42
|
+
const onDeleteRemark = constraint.onDeleteRemark ? ` -- ${ constraint.onDeleteRemark }` : '';
|
|
43
43
|
|
|
44
44
|
// omit 'RESTRICT' action for ON UPDATE / ON DELETE, because it interferes with deferred constraint check
|
|
45
45
|
if (sqlDialect === 'sqlite' || sqlDialect === 'postgres') {
|
|
46
46
|
if (constraint.onDelete === 'CASCADE' )
|
|
47
|
-
result += `${indent}ON DELETE ${constraint.onDelete}${onDeleteRemark}\n`;
|
|
47
|
+
result += `${ indent }ON DELETE ${ constraint.onDelete }${ onDeleteRemark }\n`;
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
|
-
result += `${indent}ON UPDATE RESTRICT\n`;
|
|
51
|
-
result += `${indent}ON DELETE ${constraint.onDelete}${onDeleteRemark}\n`;
|
|
50
|
+
result += `${ indent }ON UPDATE RESTRICT\n`;
|
|
51
|
+
result += `${ indent }ON DELETE ${ constraint.onDelete }${ onDeleteRemark }\n`;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
// constraint enforcement / validation must be switched off using sqlite pragma statement
|
|
55
55
|
// constraint enforcement / validation not supported by postgres
|
|
56
56
|
if (options.transformation === 'hdbcds' || (options.toSql && sqlDialect !== 'sqlite' && sqlDialect !== 'postgres')) {
|
|
57
|
-
result += `${indent}${!constraint.validated ? 'NOT ' : ''}VALIDATED\n`;
|
|
58
|
-
result += `${indent}${!constraint.enforced ? 'NOT ' : ''}ENFORCED\n`;
|
|
57
|
+
result += `${ indent }${ !constraint.validated ? 'NOT ' : '' }VALIDATED\n`;
|
|
58
|
+
result += `${ indent }${ !constraint.enforced ? 'NOT ' : '' }ENFORCED\n`;
|
|
59
59
|
}
|
|
60
60
|
// for sqlite and postgreSQL, the DEFERRABLE keyword is required
|
|
61
|
-
result += `${indent}${sqlDialect === 'sqlite' || sqlDialect === 'postgres' ? 'DEFERRABLE ' : ''}INITIALLY DEFERRED`;
|
|
61
|
+
result += `${ indent }${ sqlDialect === 'sqlite' || sqlDialect === 'postgres' ? 'DEFERRABLE ' : '' }INITIALLY DEFERRED`;
|
|
62
62
|
return result;
|
|
63
63
|
}
|
|
64
64
|
|
|
@@ -110,7 +110,7 @@ function getIdentifierUtils( csn, options ) {
|
|
|
110
110
|
function prepareIdentifier( name ) {
|
|
111
111
|
// Sanity check
|
|
112
112
|
if (options.sqlDialect === 'sqlite' && options.sqlMapping !== 'plain')
|
|
113
|
-
throw new ModelError(`Not expecting ${options.sqlMapping} names for 'sqlite' dialect`);
|
|
113
|
+
throw new ModelError(`Not expecting ${ options.sqlMapping } names for 'sqlite' dialect`);
|
|
114
114
|
|
|
115
115
|
|
|
116
116
|
switch (options.sqlMapping) {
|
|
@@ -121,7 +121,7 @@ function getIdentifierUtils( csn, options ) {
|
|
|
121
121
|
case 'hdbcds':
|
|
122
122
|
return name;
|
|
123
123
|
default:
|
|
124
|
-
throw new ModelError(`No matching rendering found for naming mode ${options.sqlMapping}`);
|
|
124
|
+
throw new ModelError(`No matching rendering found for naming mode ${ options.sqlMapping }`);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
|