@sap/cds-compiler 3.4.4 → 3.5.2

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 (129) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +1 -0
  3. package/bin/cds_update_identifiers.js +5 -5
  4. package/bin/cdsc.js +12 -12
  5. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  6. package/doc/CHANGELOG_BETA.md +9 -1
  7. package/doc/CHANGELOG_DEPRECATED.md +2 -0
  8. package/lib/api/main.js +58 -59
  9. package/lib/api/options.js +4 -2
  10. package/lib/api/validate.js +2 -2
  11. package/lib/base/cleanSymbols.js +2 -3
  12. package/lib/base/dictionaries.js +6 -6
  13. package/lib/base/error.js +2 -2
  14. package/lib/base/keywords.js +6 -6
  15. package/lib/base/location.js +11 -12
  16. package/lib/base/message-registry.js +124 -28
  17. package/lib/base/messages.js +247 -179
  18. package/lib/base/model.js +14 -11
  19. package/lib/base/node-helpers.js +9 -10
  20. package/lib/base/optionProcessorHelper.js +138 -129
  21. package/lib/checks/actionsFunctions.js +5 -5
  22. package/lib/checks/annotationsOData.js +4 -4
  23. package/lib/checks/arrayOfs.js +1 -1
  24. package/lib/checks/cdsPersistence.js +1 -1
  25. package/lib/checks/checkForTypes.js +3 -3
  26. package/lib/checks/defaultValues.js +3 -3
  27. package/lib/checks/elements.js +7 -7
  28. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  29. package/lib/checks/foreignKeys.js +1 -1
  30. package/lib/checks/invalidTarget.js +4 -4
  31. package/lib/checks/managedInType.js +1 -1
  32. package/lib/checks/managedWithoutKeys.js +1 -1
  33. package/lib/checks/nonexpandableStructured.js +5 -3
  34. package/lib/checks/nullableKeys.js +1 -1
  35. package/lib/checks/onConditions.js +5 -6
  36. package/lib/checks/parameters.js +1 -1
  37. package/lib/checks/queryNoDbArtifacts.js +2 -2
  38. package/lib/checks/selectItems.js +4 -4
  39. package/lib/checks/sql-snippets.js +4 -4
  40. package/lib/checks/types.js +7 -7
  41. package/lib/checks/utils.js +4 -4
  42. package/lib/checks/validator.js +16 -13
  43. package/lib/compiler/.eslintrc.json +1 -1
  44. package/lib/compiler/assert-consistency.js +0 -1
  45. package/lib/compiler/builtins.js +1 -1
  46. package/lib/compiler/checks.js +73 -15
  47. package/lib/compiler/define.js +3 -7
  48. package/lib/compiler/extend.js +212 -32
  49. package/lib/compiler/finalize-parse-cdl.js +7 -2
  50. package/lib/compiler/index.js +17 -14
  51. package/lib/compiler/populate.js +2 -5
  52. package/lib/compiler/propagator.js +2 -0
  53. package/lib/compiler/shared.js +23 -12
  54. package/lib/compiler/tweak-assocs.js +5 -6
  55. package/lib/compiler/utils.js +6 -0
  56. package/lib/edm/annotations/genericTranslation.js +553 -319
  57. package/lib/edm/annotations/preprocessAnnotations.js +39 -35
  58. package/lib/edm/csn2edm.js +88 -75
  59. package/lib/edm/edm.js +17 -3
  60. package/lib/edm/edmAnnoPreprocessor.js +5 -5
  61. package/lib/edm/edmPreprocessor.js +106 -76
  62. package/lib/edm/edmUtils.js +41 -2
  63. package/lib/gen/Dictionary.json +34 -0
  64. package/lib/gen/language.checksum +1 -1
  65. package/lib/gen/language.interp +66 -63
  66. package/lib/gen/language.tokens +81 -81
  67. package/lib/gen/languageLexer.interp +4 -10
  68. package/lib/gen/languageLexer.js +854 -869
  69. package/lib/gen/languageLexer.tokens +79 -81
  70. package/lib/gen/languageParser.js +14360 -14146
  71. package/lib/inspect/inspectModelStatistics.js +2 -2
  72. package/lib/inspect/inspectPropagation.js +6 -6
  73. package/lib/inspect/inspectUtils.js +2 -2
  74. package/lib/json/from-csn.js +82 -40
  75. package/lib/json/to-csn.js +82 -157
  76. package/lib/language/.eslintrc.json +1 -4
  77. package/lib/language/genericAntlrParser.js +59 -38
  78. package/lib/language/language.g4 +1508 -1490
  79. package/lib/language/multiLineStringParser.js +1 -1
  80. package/lib/main.js +3 -3
  81. package/lib/model/csnUtils.js +130 -122
  82. package/lib/model/revealInternalProperties.js +1 -1
  83. package/lib/model/sortViews.js +4 -6
  84. package/lib/modelCompare/utils/filter.js +4 -3
  85. package/lib/optionProcessor.js +5 -0
  86. package/lib/render/DuplicateChecker.js +1 -1
  87. package/lib/render/manageConstraints.js +12 -12
  88. package/lib/render/toCdl.js +225 -159
  89. package/lib/render/toHdbcds.js +63 -63
  90. package/lib/render/toRename.js +5 -5
  91. package/lib/render/toSql.js +55 -65
  92. package/lib/render/utils/common.js +20 -37
  93. package/lib/render/utils/delta.js +3 -3
  94. package/lib/render/utils/sql.js +22 -6
  95. package/lib/render/utils/stringEscapes.js +3 -3
  96. package/lib/transform/db/applyTransformations.js +3 -3
  97. package/lib/transform/db/assertUnique.js +13 -12
  98. package/lib/transform/db/associations.js +5 -5
  99. package/lib/transform/db/cdsPersistence.js +10 -8
  100. package/lib/transform/db/constraints.js +14 -14
  101. package/lib/transform/db/expansion.js +20 -22
  102. package/lib/transform/db/flattening.js +24 -42
  103. package/lib/transform/db/groupByOrderBy.js +3 -3
  104. package/lib/transform/db/temporal.js +6 -6
  105. package/lib/transform/db/transformExists.js +23 -23
  106. package/lib/transform/db/views.js +16 -16
  107. package/lib/transform/draft/db.js +10 -10
  108. package/lib/transform/draft/odata.js +2 -2
  109. package/lib/transform/forOdataNew.js +12 -40
  110. package/lib/transform/forRelationalDB.js +17 -7
  111. package/lib/transform/localized.js +2 -2
  112. package/lib/transform/odata/toFinalBaseType.js +41 -27
  113. package/lib/transform/odata/typesExposure.js +106 -62
  114. package/lib/transform/parseExpr.js +209 -106
  115. package/lib/transform/transformUtilsNew.js +2 -2
  116. package/lib/transform/translateAssocsToJoins.js +24 -19
  117. package/lib/transform/universalCsn/coreComputed.js +10 -10
  118. package/lib/transform/universalCsn/universalCsnEnricher.js +26 -26
  119. package/lib/transform/universalCsn/utils.js +3 -3
  120. package/lib/utils/file.js +5 -5
  121. package/lib/utils/moduleResolve.js +13 -13
  122. package/lib/utils/objectUtils.js +6 -6
  123. package/lib/utils/term.js +5 -2
  124. package/lib/utils/timetrace.js +51 -24
  125. package/package.json +5 -7
  126. package/share/messages/check-proper-type-of.md +1 -1
  127. package/share/messages/message-explanations.json +1 -1
  128. package/share/messages/redirected-to-complex.md +4 -4
  129. package/share/messages/{syntax-expecting-integer.md → syntax-expecting-unsigned-int.md} +7 -4
@@ -124,7 +124,7 @@ function revealInternalProperties( model, nameOrPath ) {
124
124
  // Examples:
125
125
  // `name.space/S/E/elements/a/kind/`
126
126
  // `name.space/S/E/elements/a/type/scope/`
127
- function revealXsnPath(path, xsn) {
127
+ function revealXsnPath( path, xsn ) {
128
128
  if (!path || path === '+')
129
129
  return reveal( xsn );
130
130
 
@@ -20,7 +20,7 @@ const { ModelError } = require('../base/error');
20
20
  * @param {Symbol} _dependencies Symbol used to attach the dependencies
21
21
  * @returns {Layers}
22
22
  */
23
- function sortTopologically(csn, _dependents, _dependencies) {
23
+ function sortTopologically( csn, _dependents, _dependencies ) {
24
24
  const layers = [];
25
25
  let { zero, nonZero } = _calculateDepth(Object.entries(csn.definitions), _dependents, _dependencies);
26
26
  while (zero.length !== 0) {
@@ -41,7 +41,7 @@ function sortTopologically(csn, _dependents, _dependencies) {
41
41
  return { layers, leftover: nonZero };
42
42
  }
43
43
 
44
- function _calculateDepth(definitionsArray, _dependents, _dependencies) {
44
+ function _calculateDepth( definitionsArray, _dependents, _dependencies ) {
45
45
  const zero = [];
46
46
  const nonZero = [];
47
47
 
@@ -61,7 +61,7 @@ function _calculateDepth(definitionsArray, _dependents, _dependencies) {
61
61
  };
62
62
  }
63
63
 
64
- function _findWithXPointers(definitionsArray, x, _dependents, _dependencies) {
64
+ function _findWithXPointers( definitionsArray, x, _dependents, _dependencies ) {
65
65
  const zero = [];
66
66
  const nonZero = [];
67
67
 
@@ -87,9 +87,7 @@ function _findWithXPointers(definitionsArray, x, _dependents, _dependencies) {
87
87
  * For ordering, only the FROM clause of views is checked - this requires A2J to
88
88
  * be run beforehand to resolve association usages.
89
89
  *
90
- * @param {object} sql Map of <object name>: "CREATE STATEMENT"
91
- * @param {CSN.Model} csn
92
- *
90
+ * @param {{sql: string, csn: CSN.Model}} arg sql: Map of <object name>: "CREATE STATEMENT", csn: Model
93
91
  * @returns {{name: string, sql: string}[]} Sorted array of artifact name / "CREATE STATEMENTS" pairs
94
92
  */
95
93
  module.exports = function sortViews({ sql, csn }) {
@@ -6,7 +6,7 @@
6
6
  const { forEach } = require('../../utils/objectUtils');
7
7
  const { isPersistedAsTable } = require('../../model/csnUtils');
8
8
 
9
- function isKey(element) {
9
+ function isKey( element ) {
10
10
  return element.key;
11
11
  }
12
12
 
@@ -31,9 +31,10 @@ module.exports = {
31
31
  ),
32
32
  postgres: getFilterObject('postgres'),
33
33
  h2: getFilterObject('h2'),
34
+ hana: getFilterObject('hana'),
34
35
  };
35
36
 
36
- function getFilterObject(dialect, extensionCallback, migrationCallback) {
37
+ function getFilterObject( dialect, extensionCallback, migrationCallback ) {
37
38
  return {
38
39
  // will be called with a simple Array.forEach
39
40
  extension: ({ elements, extend }, error) => {
@@ -90,7 +91,7 @@ const allowedTypeChanges = {
90
91
  h2: defaultAllowedTypeChanges,
91
92
  };
92
93
 
93
- function typeChangeIsNotCompatible(dialect, before, after) {
94
+ function typeChangeIsNotCompatible( dialect, before, after ) {
94
95
  if (allowedTypeChanges[dialect]) {
95
96
  const map = allowedTypeChanges[dialect];
96
97
  return map[before] ? !map[before].includes(after) : true;
@@ -106,6 +106,7 @@ optionProcessor
106
106
  postgres
107
107
  aspectWithoutElements
108
108
  odataOpenType
109
+ odtaTerms
109
110
  optionalActionFunctionParameters
110
111
  --deprecated <list> Comma separated list of deprecated options.
111
112
  Valid values are:
@@ -209,6 +210,7 @@ optionProcessor.command('O, toOdata')
209
210
  .option('-x, --xml')
210
211
  .option('-j, --json')
211
212
  .option(' --odata-containment')
213
+ .option(' --odata-capabilities-pullup')
212
214
  .option(' --odata-proxies')
213
215
  .option(' --odata-x-service-refs')
214
216
  .option(' --odata-foreign-keys')
@@ -235,6 +237,7 @@ optionProcessor.command('O, toOdata')
235
237
  flat : (default) Flat type and property names
236
238
  structured : (V4 only) Render structured metadata
237
239
  --odata-containment Generate Containment Navigation Properties for compositions (V4 only)
240
+ --odata-capabilities-pullup Rewrite @Capabilities annotations (V4 containment only).
238
241
  --odata-proxies Generate Proxies for out-of-service navigation targets (V4 only).
239
242
  --odata-x-service-refs Generate schema references (V4 only).
240
243
  --odata-foreign-keys Render foreign keys in structured format (V4 only)
@@ -395,6 +398,7 @@ optionProcessor.command('toCsn')
395
398
  .option('-f, --csn-flavor <flavor>', ['client', 'gensrc', 'universal'], { aliases: ['--flavor'] })
396
399
  .option(' --with-localized')
397
400
  .option(' --with-locations')
401
+ .option(' --struct-xpr')
398
402
  .help(`
399
403
  Usage: cdsc toCsn [options] <files...>
400
404
 
@@ -414,6 +418,7 @@ optionProcessor.command('toCsn')
414
418
 
415
419
  Internal options (for testing only, may be changed/removed at any time)
416
420
  --with-localized Add localized convenience views to the CSN output.
421
+ --struct-xpr Write structured expressions to the CSN output.
417
422
  `);
418
423
 
419
424
  optionProcessor.command('parseCdl')
@@ -17,7 +17,7 @@ const { forEach } = require('../utils/objectUtils');
17
17
  *
18
18
  * @returns {string} Name as it is present on the database
19
19
  */
20
- function asDBName(name) {
20
+ function asDBName( name ) {
21
21
  return (name[0] === '"')
22
22
  ? name
23
23
  : name.toUpperCase();
@@ -21,7 +21,7 @@ const {
21
21
  * @param {CSN.Model} csn
22
22
  * @param {CSN.Options} options
23
23
  */
24
- function alterConstraintsWithCsn(csn, options) {
24
+ function alterConstraintsWithCsn( csn, options ) {
25
25
  const { error } = makeMessageFunction(csn, options, 'manageConstraints');
26
26
 
27
27
  const {
@@ -54,7 +54,7 @@ function alterConstraintsWithCsn(csn, options) {
54
54
  return intermediateResult;
55
55
  }
56
56
 
57
- function _transformSqlOptions(model, options) {
57
+ function _transformSqlOptions( model, options ) {
58
58
  // Merge options with defaults.
59
59
  options = Object.assign({ sqlMapping: 'plain', sqlDialect: 'plain' }, options);
60
60
  options.toSql = true;
@@ -91,14 +91,14 @@ function _transformSqlOptions(model, options) {
91
91
  * @param {CSN.Options} options
92
92
  * @returns a map holding the constraint identifier as key and the corresponding, rendered SQL statement / hdbconstraint artifact as value.
93
93
  */
94
- function manageConstraints(csn, options) {
94
+ function manageConstraints( csn, options ) {
95
95
  const {
96
96
  drop, alter, src,
97
97
  } = options.manageConstraints || {};
98
98
  const indent = '';
99
99
  // either ALTER TABLE statements or .hdbconstraint artifacts
100
100
  const resultArtifacts = {};
101
- const { quoteSqlId } = getIdentifierUtils(options);
101
+ const { quoteSqlId } = getIdentifierUtils(csn, options);
102
102
  forEachDefinition(csn, (artifact) => {
103
103
  if (artifact.$tableConstraints && artifact.$tableConstraints.referential) {
104
104
  forEach(artifact.$tableConstraints.referential, (fileName, constraint) => {
@@ -131,8 +131,8 @@ function manageConstraints(csn, options) {
131
131
  * @param {CSN.Model} csn
132
132
  * @returns a map holding the constraint identifier as key and the corresponding rendered SQL-SELECT statement as value.
133
133
  */
134
- function listReferentialIntegrityViolations(csn, options) {
135
- const { quoteSqlId } = getIdentifierUtils(options);
134
+ function listReferentialIntegrityViolations( csn, options ) {
135
+ const { quoteSqlId } = getIdentifierUtils(csn, options);
136
136
  const referentialConstraints = getListOfAllConstraints(csn);
137
137
  const resultArtifacts = {};
138
138
  const indent = ' ';
@@ -176,7 +176,7 @@ function listReferentialIntegrityViolations(csn, options) {
176
176
  * @param {CSN.ReferentialConstraint} constraint
177
177
  * @returns comma separated list of primary key columns
178
178
  */
179
- function selectPrimaryKeyColumns(constraint) {
179
+ function selectPrimaryKeyColumns( constraint ) {
180
180
  const pkReducer = keyStringReducer('K');
181
181
  const primaryKeyOfDependentTable = Object.keys(csn.definitions[constraint.dependentTable].elements)
182
182
  .filter((key) => {
@@ -195,7 +195,7 @@ function listReferentialIntegrityViolations(csn, options) {
195
195
  * @param {CSN.ReferentialConstraint} constraint
196
196
  * @returns comma separated list of foreign key columns
197
197
  */
198
- function selectForeignKeyColumns(constraint) {
198
+ function selectForeignKeyColumns( constraint ) {
199
199
  const fkReducer = keyStringReducer('FK');
200
200
  return constraint.foreignKey.reduce(fkReducer, `${quoteSqlId(constraint.foreignKey[0])} AS "FK:${constraint.foreignKey[0]}"`);
201
201
  }
@@ -206,7 +206,7 @@ function listReferentialIntegrityViolations(csn, options) {
206
206
  * @param {CSN.ReferentialConstraint} constraint
207
207
  * @returns WHERE NOT ( <foreign_key IS NULL ... ) statement
208
208
  */
209
- function whereNotForeignKeyIsNull(constraint) {
209
+ function whereNotForeignKeyIsNull( constraint ) {
210
210
  let whereNot = `${indent}WHERE NOT (\n`;
211
211
  whereNot += constraint.foreignKey
212
212
  .reduce((prev, curr, index) => {
@@ -225,7 +225,7 @@ function listReferentialIntegrityViolations(csn, options) {
225
225
  * @param {string} mainQueryAlias
226
226
  * @returns AND NOT EXISTS ( SELECT * FROM <parent_table> WHERE <dependent_table>.<foreign_key> = <parent_table>.<parent_key> ) statement
227
227
  */
228
- function andNoMatchingPrimaryKeyExists(constraint, mainQueryAlias) {
228
+ function andNoMatchingPrimaryKeyExists( constraint, mainQueryAlias ) {
229
229
  let andNotExists = `\n${indent}AND NOT EXISTS (\n`;
230
230
  andNotExists += `${increaseIndent(indent)}SELECT * FROM ${quoteAndGetResultingName(constraint.parentTable)}`;
231
231
  // add an alias to both queries so that they can be distinguished at all times
@@ -242,7 +242,7 @@ function listReferentialIntegrityViolations(csn, options) {
242
242
  return andNotExists;
243
243
  }
244
244
 
245
- function quoteAndGetResultingName(id) {
245
+ function quoteAndGetResultingName( id ) {
246
246
  return quoteSqlId(getResultingName(csn, options.sqlMapping, id));
247
247
  }
248
248
 
@@ -250,7 +250,7 @@ function listReferentialIntegrityViolations(csn, options) {
250
250
  }
251
251
 
252
252
 
253
- function getListOfAllConstraints(csn) {
253
+ function getListOfAllConstraints( csn ) {
254
254
  const referentialConstraints = {};
255
255
  forEachDefinition(csn, (artifact) => {
256
256
  if (artifact.$tableConstraints && artifact.$tableConstraints.referential) {