@sap/cds-compiler 2.11.2 → 2.13.6

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 (140) hide show
  1. package/CHANGELOG.md +175 -2
  2. package/bin/.eslintrc.json +1 -2
  3. package/bin/cds_update_identifiers.js +10 -8
  4. package/bin/cdsc.js +23 -17
  5. package/bin/cdsse.js +2 -2
  6. package/bin/cdsv2m.js +3 -2
  7. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  8. package/doc/CHANGELOG_BETA.md +25 -6
  9. package/doc/CHANGELOG_DEPRECATED.md +22 -6
  10. package/doc/NameResolution.md +21 -16
  11. package/lib/api/main.js +32 -79
  12. package/lib/api/options.js +3 -2
  13. package/lib/api/validate.js +2 -1
  14. package/lib/backends.js +16 -26
  15. package/lib/base/dictionaries.js +0 -8
  16. package/lib/base/error.js +26 -0
  17. package/lib/base/keywords.js +10 -19
  18. package/lib/base/location.js +9 -4
  19. package/lib/base/message-registry.js +75 -9
  20. package/lib/base/messages.js +31 -35
  21. package/lib/base/model.js +2 -62
  22. package/lib/base/optionProcessorHelper.js +246 -183
  23. package/lib/checks/.eslintrc.json +2 -0
  24. package/lib/checks/actionsFunctions.js +2 -1
  25. package/lib/checks/annotationsOData.js +1 -1
  26. package/lib/checks/cdsPersistence.js +2 -1
  27. package/lib/checks/emptyOrOnlyVirtual.js +2 -2
  28. package/lib/checks/enricher.js +17 -1
  29. package/lib/checks/foreignKeys.js +4 -4
  30. package/lib/checks/invalidTarget.js +3 -1
  31. package/lib/checks/managedInType.js +4 -4
  32. package/lib/checks/managedWithoutKeys.js +3 -1
  33. package/lib/checks/queryNoDbArtifacts.js +1 -3
  34. package/lib/checks/selectItems.js +4 -4
  35. package/lib/checks/sql-snippets.js +94 -0
  36. package/lib/checks/types.js +1 -1
  37. package/lib/checks/unknownMagic.js +1 -1
  38. package/lib/checks/validator.js +12 -7
  39. package/lib/compiler/assert-consistency.js +12 -8
  40. package/lib/compiler/base.js +0 -1
  41. package/lib/compiler/builtins.js +42 -21
  42. package/lib/compiler/checks.js +46 -12
  43. package/lib/compiler/cycle-detector.js +1 -1
  44. package/lib/compiler/define.js +1103 -0
  45. package/lib/compiler/extend.js +983 -0
  46. package/lib/compiler/finalize-parse-cdl.js +231 -0
  47. package/lib/compiler/index.js +46 -39
  48. package/lib/compiler/kick-start.js +190 -0
  49. package/lib/compiler/moduleLayers.js +4 -4
  50. package/lib/compiler/populate.js +1226 -0
  51. package/lib/compiler/propagator.js +113 -47
  52. package/lib/compiler/resolve.js +1433 -0
  53. package/lib/compiler/shared.js +100 -65
  54. package/lib/compiler/tweak-assocs.js +529 -0
  55. package/lib/compiler/utils.js +215 -33
  56. package/lib/edm/.eslintrc.json +5 -0
  57. package/lib/edm/annotations/genericTranslation.js +38 -25
  58. package/lib/edm/annotations/preprocessAnnotations.js +3 -3
  59. package/lib/edm/csn2edm.js +10 -9
  60. package/lib/edm/edm.js +19 -20
  61. package/lib/edm/edmPreprocessor.js +166 -95
  62. package/lib/edm/edmUtils.js +127 -34
  63. package/lib/gen/Dictionary.json +92 -43
  64. package/lib/gen/language.checksum +1 -1
  65. package/lib/gen/language.interp +11 -1
  66. package/lib/gen/language.tokens +86 -82
  67. package/lib/gen/languageLexer.interp +18 -1
  68. package/lib/gen/languageLexer.js +925 -847
  69. package/lib/gen/languageLexer.tokens +78 -74
  70. package/lib/gen/languageParser.js +5434 -4298
  71. package/lib/json/from-csn.js +59 -17
  72. package/lib/json/to-csn.js +189 -71
  73. package/lib/language/antlrParser.js +3 -3
  74. package/lib/language/docCommentParser.js +3 -3
  75. package/lib/language/errorStrategy.js +26 -8
  76. package/lib/language/genericAntlrParser.js +144 -53
  77. package/lib/language/language.g4 +424 -200
  78. package/lib/language/multiLineStringParser.js +536 -0
  79. package/lib/main.d.ts +550 -61
  80. package/lib/main.js +38 -11
  81. package/lib/model/api.js +3 -1
  82. package/lib/model/csnRefs.js +322 -198
  83. package/lib/model/csnUtils.js +226 -370
  84. package/lib/model/enrichCsn.js +124 -69
  85. package/lib/model/revealInternalProperties.js +29 -7
  86. package/lib/model/sortViews.js +10 -2
  87. package/lib/modelCompare/compare.js +17 -12
  88. package/lib/optionProcessor.js +8 -3
  89. package/lib/render/.eslintrc.json +1 -2
  90. package/lib/render/DuplicateChecker.js +1 -1
  91. package/lib/render/manageConstraints.js +36 -33
  92. package/lib/render/toCdl.js +174 -275
  93. package/lib/render/toHdbcds.js +203 -122
  94. package/lib/render/toRename.js +7 -10
  95. package/lib/render/toSql.js +161 -82
  96. package/lib/render/utils/common.js +22 -8
  97. package/lib/render/utils/sql.js +10 -7
  98. package/lib/render/utils/stringEscapes.js +111 -0
  99. package/lib/sql-identifier.js +1 -1
  100. package/lib/transform/.eslintrc.json +5 -0
  101. package/lib/transform/braceExpression.js +4 -2
  102. package/lib/transform/db/.eslintrc.json +2 -0
  103. package/lib/transform/db/applyTransformations.js +212 -0
  104. package/lib/transform/db/assertUnique.js +1 -1
  105. package/lib/transform/db/associations.js +187 -0
  106. package/lib/transform/db/cdsPersistence.js +150 -0
  107. package/lib/transform/db/constraints.js +61 -56
  108. package/lib/transform/db/expansion.js +50 -29
  109. package/lib/transform/db/flattening.js +556 -106
  110. package/lib/transform/db/groupByOrderBy.js +3 -1
  111. package/lib/transform/db/temporal.js +236 -0
  112. package/lib/transform/db/transformExists.js +103 -28
  113. package/lib/transform/db/views.js +92 -44
  114. package/lib/transform/draft/.eslintrc.json +38 -0
  115. package/lib/transform/{db/draft.js → draft/db.js} +9 -7
  116. package/lib/transform/draft/odata.js +227 -0
  117. package/lib/transform/forHanaNew.js +98 -783
  118. package/lib/transform/forOdataNew.js +22 -175
  119. package/lib/transform/localized.js +36 -32
  120. package/lib/transform/odata/generateForeignKeyElements.js +3 -3
  121. package/lib/transform/odata/referenceFlattener.js +95 -89
  122. package/lib/transform/odata/structureFlattener.js +1 -1
  123. package/lib/transform/odata/toFinalBaseType.js +86 -12
  124. package/lib/transform/odata/typesExposure.js +5 -5
  125. package/lib/transform/odata/utils.js +2 -2
  126. package/lib/transform/transformUtilsNew.js +47 -33
  127. package/lib/transform/translateAssocsToJoins.js +13 -30
  128. package/lib/transform/universalCsn/.eslintrc.json +36 -0
  129. package/lib/transform/universalCsn/coreComputed.js +170 -0
  130. package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
  131. package/lib/transform/universalCsn/utils.js +63 -0
  132. package/lib/utils/file.js +8 -3
  133. package/lib/utils/objectUtils.js +30 -0
  134. package/lib/utils/timetrace.js +8 -2
  135. package/package.json +1 -1
  136. package/share/messages/README.md +26 -0
  137. package/lib/compiler/definer.js +0 -2349
  138. package/lib/compiler/resolver.js +0 -2922
  139. package/lib/transform/db/helpers.js +0 -58
  140. package/lib/transform/universalCsnEnricher.js +0 -67
@@ -5,6 +5,7 @@ const {
5
5
  forEachDefinition,
6
6
  getResultingName,
7
7
  } = require('../model/csnUtils');
8
+ const { forEach } = require('../utils/objectUtils');
8
9
 
9
10
  const {
10
11
  renderReferentialConstraint, getIdentifierUtils,
@@ -13,7 +14,7 @@ const {
13
14
  /**
14
15
  * This render middleware can be used to generate SQL DDL ALTER TABLE <table> ALTER / ADD / DROP CONSTRAINT <constraint> statements for a given CDL model.
15
16
  * Moreover, it can be used to generate .hdbconstraint artifacts.
16
- * Depending on the options.manageConstraints provided,the VALIDATED / ENFORCED flag of the constraints can be adjusted.
17
+ * Depending on the options.manageConstraints provided, the VALIDATED / ENFORCED flag of the constraints can be adjusted.
17
18
  *
18
19
  * @param {CSN.Model} csn
19
20
  * @param {CSN.Options} options
@@ -29,25 +30,24 @@ function manageConstraints(csn, options) {
29
30
  const { quoteSqlId } = getIdentifierUtils(options);
30
31
  forEachDefinition(csn, (artifact) => {
31
32
  if (artifact.$tableConstraints && artifact.$tableConstraints.referential) {
32
- Object.entries(artifact.$tableConstraints.referential)
33
- .forEach(([ fileName, constraint ]) => {
34
- const renderAlterConstraintStatement = alter && src !== 'hdi';
35
- const renderedConstraint = renderReferentialConstraint(constraint, indent, false, csn, options, renderAlterConstraintStatement);
36
- if (src === 'hdi') {
37
- resultArtifacts[fileName] = renderedConstraint;
38
- return;
39
- }
40
- let alterTableStatement = '';
41
- alterTableStatement += `${indent}ALTER TABLE ${quoteSqlId(getResultingName(csn, options.toSql.names, constraint.dependentTable))}`;
42
- if (renderAlterConstraintStatement)
43
- alterTableStatement += `\n${indent}ALTER ${renderedConstraint};`;
44
- else if (drop)
45
- alterTableStatement += `${indent} DROP CONSTRAINT ${quoteSqlId(constraint.identifier)};`;
46
- else
47
- alterTableStatement += `\n${indent}ADD ${renderedConstraint};`;
48
-
49
- resultArtifacts[fileName] = alterTableStatement;
50
- });
33
+ forEach(artifact.$tableConstraints.referential, (fileName, constraint) => {
34
+ const renderAlterConstraintStatement = alter && src !== 'hdi';
35
+ const renderedConstraint = renderReferentialConstraint(constraint, indent, false, csn, options, renderAlterConstraintStatement);
36
+ if (src === 'hdi') {
37
+ resultArtifacts[fileName] = renderedConstraint;
38
+ return;
39
+ }
40
+ let alterTableStatement = '';
41
+ alterTableStatement += `${indent}ALTER TABLE ${quoteSqlId(getResultingName(csn, options.toSql.names, constraint.dependentTable))}`;
42
+ if (renderAlterConstraintStatement)
43
+ alterTableStatement += `\n${indent}ALTER ${renderedConstraint};`;
44
+ else if (drop)
45
+ alterTableStatement += `${indent} DROP CONSTRAINT ${quoteSqlId(constraint.identifier)};`;
46
+ else
47
+ alterTableStatement += `\n${indent}ADD ${renderedConstraint};`;
48
+
49
+ resultArtifacts[fileName] = alterTableStatement;
50
+ });
51
51
  }
52
52
  });
53
53
  return resultArtifacts;
@@ -65,25 +65,29 @@ function listReferentialIntegrityViolations(csn, options) {
65
65
  const referentialConstraints = getListOfAllConstraints(csn);
66
66
  const resultArtifacts = {};
67
67
  const indent = ' ';
68
- const increaseIndent = indent => `${indent} `;
68
+ const increaseIndent = str => ` ${str}`;
69
69
  // helper function to reduce parent key / foreign key array to a comma separated string which can be used in a select clause
70
70
  const keyStringReducer = prefix => (prev, curr, index) => (index > 0 ? `${prev},\n${curr} AS "${prefix}:${curr}"` : prev);
71
71
  // helper function to reduce the parent key / foreign key arrays of a referential constraint to a join list which can be used in a where clause
72
72
  const joinPkWithFkReducer = (constraint, subQueryAlias, mainQueryAlias) => (prev, curr, index) => (index > 0
73
73
  ? `${prev} AND
74
- ${increaseIndent(indent)}${mainQueryAlias}.${quoteSqlId(constraint.foreignKey[index])} = ${subQueryAlias}.${quoteSqlId(constraint.parentKey[index])}`
74
+ ${increaseIndent(indent)}"${mainQueryAlias}".${quoteSqlId(constraint.foreignKey[index])} = ${subQueryAlias}.${quoteSqlId(constraint.parentKey[index])}`
75
75
  : increaseIndent(increaseIndent(indent)) + prev);
76
76
 
77
- Object.entries(referentialConstraints).forEach(([ identifier, constraint ]) => {
77
+ Object.entries(referentialConstraints).forEach(([ identifier, constraint ], index) => {
78
78
  let selectViolations = 'SELECT\n';
79
+ // this column indicates which SELECT revealed the integrity violation
80
+ // and helps to identify the corrupted table
81
+ selectViolations += `${index} as "SELECT-ID",\n`;
79
82
  // SELECT <primary_key>,
80
83
  const primaryKeyList = selectPrimaryKeyColumns(constraint);
81
84
  if (primaryKeyList)
82
85
  selectViolations += `${primaryKeyList},\n`;
83
86
  // ... <foreign_key>
84
87
  selectViolations += selectForeignKeyColumns(constraint);
85
- // ... FROM <dependent table> AS "MAIN"
86
- selectViolations += `\nFROM ${quoteAndGetResultingName(constraint.dependentTable)} AS "MAIN"\n`;
88
+ const mainQueryAlias = `MAIN_${index}`;
89
+ // ... FROM <dependent table> AS "${index}"
90
+ selectViolations += `\nFROM ${quoteAndGetResultingName(constraint.dependentTable)} AS "${mainQueryAlias}"\n`;
87
91
  // ... WHERE NOT (<(part of) foreign key is null>)
88
92
  selectViolations += whereNotForeignKeyIsNull(constraint);
89
93
  /*
@@ -91,7 +95,7 @@ function listReferentialIntegrityViolations(csn, options) {
91
95
  SELECT * FROM <parent_table> WHERE <dependent_table>.<foreign_key> = <parent_table>.<parent_key>
92
96
  )
93
97
  */
94
- selectViolations += andNoMatchingPrimaryKeyExists(constraint);
98
+ selectViolations += andNoMatchingPrimaryKeyExists(constraint, mainQueryAlias);
95
99
  resultArtifacts[identifier] = selectViolations;
96
100
  });
97
101
 
@@ -147,21 +151,21 @@ function listReferentialIntegrityViolations(csn, options) {
147
151
  * Generate SQL sub-SELECT, listing all rows of the parent table where no matching primary key column for the respective foreign key is found.
148
152
  *
149
153
  * @param {CSN.ReferentialConstraint} constraint
154
+ * @param {string} mainQueryAlias
150
155
  * @returns AND NOT EXISTS ( SELECT * FROM <parent_table> WHERE <dependent_table>.<foreign_key> = <parent_table>.<parent_key> ) statement
151
156
  */
152
- function andNoMatchingPrimaryKeyExists(constraint) {
157
+ function andNoMatchingPrimaryKeyExists(constraint, mainQueryAlias) {
153
158
  let andNotExists = `\n${indent}AND NOT EXISTS (\n`;
154
159
  andNotExists += `${increaseIndent(indent)}SELECT * FROM ${quoteAndGetResultingName(constraint.parentTable)}`;
155
160
  // add an alias to both queries so that they can be distinguished at all times
156
161
  const subQueryAlias = '"SUB"';
157
- const mainQueryAlias = '"MAIN"';
158
162
  andNotExists += ` AS ${subQueryAlias}`;
159
163
  andNotExists += '\n';
160
164
  const joinListReducer = joinPkWithFkReducer(constraint, subQueryAlias, mainQueryAlias);
161
165
  andNotExists += `${increaseIndent(indent)}WHERE (\n`;
162
166
  andNotExists += constraint.foreignKey
163
167
  .reduce(joinListReducer,
164
- `${mainQueryAlias}.${quoteSqlId(constraint.foreignKey[0])} = ${subQueryAlias}.${quoteSqlId(constraint.parentKey[0])}`);
168
+ `"${mainQueryAlias}".${quoteSqlId(constraint.foreignKey[0])} = ${subQueryAlias}.${quoteSqlId(constraint.parentKey[0])}`);
165
169
  andNotExists += `\n${increaseIndent(indent)})`;
166
170
  andNotExists += `\n${indent});`;
167
171
  return andNotExists;
@@ -179,10 +183,9 @@ function getListOfAllConstraints(csn) {
179
183
  const referentialConstraints = {};
180
184
  forEachDefinition(csn, (artifact) => {
181
185
  if (artifact.$tableConstraints && artifact.$tableConstraints.referential) {
182
- Object.entries(artifact.$tableConstraints.referential)
183
- .forEach(([ identifier, referentialConstraint ]) => {
184
- referentialConstraints[identifier] = referentialConstraint;
185
- });
186
+ forEach(artifact.$tableConstraints.referential, (identifier, referentialConstraint) => {
187
+ referentialConstraints[identifier] = referentialConstraint;
188
+ });
186
189
  }
187
190
  });
188
191
  return referentialConstraints;