@sap/cds-compiler 2.10.4 → 2.11.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 (70) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/bin/cdsc.js +42 -25
  3. package/bin/cdsse.js +1 -0
  4. package/doc/CHANGELOG_BETA.md +4 -0
  5. package/lib/api/.eslintrc.json +2 -0
  6. package/lib/api/main.js +9 -23
  7. package/lib/api/options.js +12 -4
  8. package/lib/api/validate.js +23 -2
  9. package/lib/backends.js +9 -8
  10. package/lib/base/dictionaries.js +2 -1
  11. package/lib/base/message-registry.js +10 -2
  12. package/lib/base/messages.js +23 -9
  13. package/lib/base/model.js +5 -4
  14. package/lib/base/optionProcessorHelper.js +56 -22
  15. package/lib/checks/selectItems.js +4 -0
  16. package/lib/checks/unknownMagic.js +6 -3
  17. package/lib/compiler/assert-consistency.js +7 -0
  18. package/lib/compiler/base.js +65 -0
  19. package/lib/compiler/builtins.js +28 -1
  20. package/lib/compiler/checks.js +2 -1
  21. package/lib/compiler/definer.js +58 -91
  22. package/lib/compiler/index.js +16 -4
  23. package/lib/compiler/propagator.js +5 -2
  24. package/lib/compiler/resolver.js +93 -34
  25. package/lib/compiler/shared.js +29 -202
  26. package/lib/compiler/utils.js +173 -0
  27. package/lib/edm/annotations/genericTranslation.js +1 -1
  28. package/lib/edm/csn2edm.js +3 -2
  29. package/lib/edm/edmPreprocessor.js +31 -36
  30. package/lib/edm/edmUtils.js +3 -3
  31. package/lib/gen/language.checksum +1 -1
  32. package/lib/gen/language.interp +17 -1
  33. package/lib/gen/language.tokens +79 -73
  34. package/lib/gen/languageLexer.interp +19 -1
  35. package/lib/gen/languageLexer.js +779 -731
  36. package/lib/gen/languageLexer.tokens +71 -65
  37. package/lib/gen/languageParser.js +4668 -4072
  38. package/lib/json/from-csn.js +10 -10
  39. package/lib/json/to-csn.js +169 -34
  40. package/lib/language/antlrParser.js +11 -0
  41. package/lib/language/genericAntlrParser.js +72 -14
  42. package/lib/language/language.g4 +73 -0
  43. package/lib/main.d.ts +136 -17
  44. package/lib/main.js +3 -1
  45. package/lib/model/api.js +2 -2
  46. package/lib/model/csnRefs.js +108 -31
  47. package/lib/model/csnUtils.js +63 -29
  48. package/lib/model/enrichCsn.js +36 -9
  49. package/lib/model/revealInternalProperties.js +20 -4
  50. package/lib/modelCompare/compare.js +2 -1
  51. package/lib/optionProcessor.js +29 -18
  52. package/lib/render/DuplicateChecker.js +1 -1
  53. package/lib/render/toCdl.js +9 -3
  54. package/lib/render/toHdbcds.js +16 -36
  55. package/lib/render/toSql.js +23 -5
  56. package/lib/transform/db/constraints.js +278 -119
  57. package/lib/transform/db/draft.js +3 -2
  58. package/lib/transform/db/expansion.js +6 -4
  59. package/lib/transform/db/flattening.js +17 -1
  60. package/lib/transform/db/transformExists.js +61 -2
  61. package/lib/transform/db/views.js +438 -0
  62. package/lib/transform/forHanaNew.js +56 -435
  63. package/lib/transform/forOdataNew.js +9 -2
  64. package/lib/transform/localized.js +2 -0
  65. package/lib/transform/transformUtilsNew.js +10 -0
  66. package/lib/transform/translateAssocsToJoins.js +5 -13
  67. package/lib/utils/file.js +5 -3
  68. package/lib/utils/term.js +65 -42
  69. package/lib/utils/timetrace.js +48 -26
  70. package/package.json +1 -1
@@ -2,6 +2,7 @@
2
2
 
3
3
  const { setProp } = require('../base/model');
4
4
  const { csnRefs } = require('../model/csnRefs');
5
+ const { isBuiltinType } = require('../compiler/builtins.js')
5
6
  const { sortCsn, cloneCsnDictionary: _cloneCsnDictionary } = require('../json/to-csn');
6
7
  const version = require('../../package.json').version;
7
8
 
@@ -11,8 +12,8 @@ const version = require('../../package.json').version;
11
12
  * Generic Callback
12
13
  *
13
14
  * @callback genericCallback
14
- * @param {CSN.Artifact} art
15
- * @param {CSN.FQN} name Artifact Name
15
+ * @param {any} art
16
+ * @param {string} name Artifact Name
16
17
  * @param {string} prop Dictionary Property
17
18
  * @param {CSN.Path} path Location
18
19
  * @param {CSN.Artifact} [dictionary]
@@ -457,8 +458,8 @@ function getUtils(model) {
457
458
  return resultNode;
458
459
  }
459
460
  }
460
-
461
-
461
+
462
+
462
463
  /**
463
464
  * Resolve to the final type of a type, that means follow type chains, references to other types or
464
465
  * elements a.s.o
@@ -497,12 +498,12 @@ function getUtils(model) {
497
498
  * Composed types (structures, entities, views, ...) are returned as type objects, if not drilled down into
498
499
  * the elements. Path steps that have no corresponding element lead to 'undefined'. Refs to something that has
499
500
  * no type (e.g. expr in a view without explicit type) returns 'null'
500
- *
501
+ *
501
502
  * @param {string|object} type Type - either string or ref
502
- * @param {CSN.Path} path
503
+ * @param {CSN.Path} path
503
504
  * @param {WeakMap} [resolved=new WeakMap()] WeakMap containing already resolved refs - if a ref is not cached, it will be resolved JIT
504
- * @param {object} [cycleCheck] Dictionary to remember already resolved types - to be cycle-safe
505
- * @returns
505
+ * @param {object} [cycleCheck] Dictionary to remember already resolved types - to be cycle-safe
506
+ * @returns
506
507
  */
507
508
  function getFinalBaseType(type, path = [], resolved = new WeakMap(), cycleCheck = undefined) {
508
509
  if (!type)
@@ -552,16 +553,6 @@ function getUtils(model) {
552
553
  }
553
554
  }
554
555
 
555
- // Tell if a type is (directly) a builtin type
556
- // Note that in CSN builtins are not in the definition of the model, so we can only check against their absolute names.
557
- // Builtin types are "cds.<something>", i.e. they are directly in 'cds', but not for example
558
- // in 'cds.foundation'. Also note, that a type might be a ref object, that refers to something else,
559
- // so if you consider type chains don't forget first to resolve to the final type before
560
- function isBuiltinType(type) {
561
- return typeof(type) === 'string' && type.startsWith('cds.') && !type.startsWith('cds.foundation.')
562
- }
563
-
564
-
565
556
  /**
566
557
  * Deeply clone the given CSN model and return it.
567
558
  * In testMode (or with testSortCsn), definitions are sorted.
@@ -817,11 +808,25 @@ function forAllQueries(query, callback, path = []){
817
808
  }
818
809
  }
819
810
 
820
- function forAllElements(artifact, artifactName, cb){
811
+ function forAllElements(artifact, artifactName, cb, includeActions = false){
821
812
  if(artifact.elements) {
822
813
  cb(artifact, artifact.elements, ['definitions', artifactName, 'elements']);
823
814
  }
824
815
 
816
+ if(includeActions && artifact.actions) {
817
+ Object.entries(artifact.actions).forEach( ([actionName, action]) => {
818
+ const path = ['definitions', artifactName, 'actions', actionName];
819
+ if(action.params) {
820
+ Object.entries(action.params).forEach( ([paramName, param]) => {
821
+ if(param.elements)
822
+ cb(param, param.elements, path.concat(['params', paramName, 'elements']));
823
+ });
824
+ }
825
+ if(action.returns && action.returns.elements)
826
+ cb(action.returns, action.returns.elements,path.concat(['returns', 'elements']));
827
+ });
828
+ }
829
+
825
830
  if(artifact.query) {
826
831
  forAllQueries(artifact.query, (q, p) => {
827
832
  const s = q.SELECT;
@@ -871,7 +876,7 @@ function hasAnnotationValue(artifact, annotationName, expected = true) {
871
876
  * function accepts EDM internal and external options
872
877
  *
873
878
  * @param {CSN.Element} elementCsn
874
- * @param {CSN.Options & CSN.ODataOptions} options EDM specific options
879
+ * @param {ODataOptions} options EDM specific options
875
880
  */
876
881
  function isEdmPropertyRendered(elementCsn, options) {
877
882
  if(options.toOdata)
@@ -921,10 +926,10 @@ function getArtifactDatabaseNameOf(artifactName, namingConvention, csn) {
921
926
  throw new Error('Unknown naming convention: ' + namingConvention);
922
927
  }
923
928
  else {
924
- const namespace = csn;
925
929
  console.error(`This invocation of "getArtifactCdsPersistenceName" is deprecated, as it doesn't produce correct output with definition names containing dots - please provide a CSN as the third parameter.`);
926
930
  if (namingConvention === 'hdbcds') {
927
- if (namespace) {
931
+ if (csn) {
932
+ const namespace = String(csn);
928
933
  return `${namespace}::${artifactName.substring(namespace.length + 1)}`;
929
934
  }
930
935
  return artifactName;
@@ -1532,7 +1537,7 @@ function sortCsnDefinitionsForTests(csn, options) {
1532
1537
  if (!options.testMode)
1533
1538
  return;
1534
1539
  const sorted = Object.create(null);
1535
- Object.keys(csn.definitions).sort().forEach((name) => {
1540
+ Object.keys(csn.definitions || {}).sort().forEach((name) => {
1536
1541
  sorted[name] = csn.definitions[name];
1537
1542
  });
1538
1543
  csn.definitions = sorted;
@@ -1542,7 +1547,7 @@ function sortCsnDefinitionsForTests(csn, options) {
1542
1547
  * Return an array of non-abstract service names contained in CSN
1543
1548
  *
1544
1549
  * @param {CSN.Model} csn
1545
- * @returns {CSN.Service[]}
1550
+ * @returns {string[]}
1546
1551
  */
1547
1552
  function getServiceNames(csn) {
1548
1553
  let result = [];
@@ -1556,8 +1561,8 @@ function getServiceNames(csn) {
1556
1561
 
1557
1562
  /**
1558
1563
  * Check wether the artifact is @cds.persistence.skip
1559
- *
1560
- * @param {CSN.Artifact} artifact
1564
+ *
1565
+ * @param {CSN.Artifact} artifact
1561
1566
  * @returns {Boolean}
1562
1567
  */
1563
1568
  function isSkipped(artifact) {
@@ -1566,9 +1571,9 @@ function isSkipped(artifact) {
1566
1571
 
1567
1572
  /**
1568
1573
  * Walk path in the CSN and return the result.
1569
- *
1570
- * @param {CSN.Model} csn
1571
- * @param {CSN.Path} path
1574
+ *
1575
+ * @param {CSN.Model} csn
1576
+ * @param {CSN.Path} path
1572
1577
  * @returns {object} Whatever is at the end of path
1573
1578
  */
1574
1579
  function walkCsnPath(csn, path) {
@@ -1581,6 +1586,34 @@ function walkCsnPath(csn, path) {
1581
1586
  return obj;
1582
1587
  }
1583
1588
 
1589
+ /**
1590
+ * If provided, get the replacement string for the given magic variable ref.
1591
+ * No validation is done that the ref is actually magic!
1592
+ *
1593
+ * @param {array} ref
1594
+ * @param {CSN.Options} options
1595
+ * @returns {string|null}
1596
+ */
1597
+ function getVariableReplacement(ref, options) {
1598
+ if(options && options.variableReplacements) {
1599
+ let replacement = options.variableReplacements;
1600
+ for(let i = 0; i < ref.length; i++) {
1601
+ replacement = replacement[ref[i]];
1602
+ if(replacement === undefined)
1603
+ return null;
1604
+ }
1605
+
1606
+ if(replacement === undefined)
1607
+ return null; // no valid replacement found
1608
+ else if(typeof replacement === 'string')
1609
+ return replacement; // valid replacement
1610
+ else
1611
+ return null; // $user.foo, but we only have configured $user.foo.bar -> error
1612
+ } else {
1613
+ return null;
1614
+ }
1615
+ }
1616
+
1584
1617
  module.exports = {
1585
1618
  getUtils,
1586
1619
  cloneCsn,
@@ -1621,4 +1654,5 @@ module.exports = {
1621
1654
  getServiceNames,
1622
1655
  isSkipped,
1623
1656
  walkCsnPath,
1657
+ getVariableReplacement
1624
1658
  };
@@ -39,6 +39,8 @@ function enrichCsn( csn, options = {} ) {
39
39
  params: dictionary,
40
40
  enum: dictionary,
41
41
  mixin: dictionary,
42
+ returns: definition,
43
+ items: definition,
42
44
  ref: pathRef,
43
45
  type: simpleRef,
44
46
  targetAspect: simpleRef,
@@ -81,10 +83,19 @@ function enrichCsn( csn, options = {} ) {
81
83
  csnPath.pop();
82
84
  }
83
85
 
86
+ function definition( parent, prop, obj ) {
87
+ const origin = getOrigin( obj ); // before standard for implicit protos inside
88
+ standard( parent, prop, obj );
89
+ if (obj.$origin === undefined && origin != null)
90
+ obj._origin = refLocation( origin );
91
+ }
92
+
84
93
  function dictionary( parent, prop, dict ) {
94
+ if (!dict) // value null for inheritance interruption
95
+ return;
85
96
  csnPath.push( prop );
86
97
  for (let name of Object.getOwnPropertyNames( dict )) {
87
- standard( dict, name, dict[name] );
98
+ definition( dict, name, dict[name] );
88
99
  }
89
100
  if (!Object.prototype.propertyIsEnumerable.call( parent, prop ))
90
101
  parent['$'+prop] = dict;
@@ -123,13 +134,17 @@ function enrichCsn( csn, options = {} ) {
123
134
 
124
135
  function $origin( parent, prop, ref ) {
125
136
  if (options.testMode) {
126
- if (Array.isArray( ref )) // $origin: […], not $origin: {…}
127
- parent._origin = refLocation( getOrigin( parent ) );
137
+ if (Array.isArray( ref ) || typeof ref === 'string') // $origin: […], not $origin: {…}
138
+ parent._origin = refLocation( getOrigin( parent, true ) );
139
+ else if ( ref )
140
+ standard( parent, prop, ref )
128
141
  }
129
142
  else {
130
143
  try {
131
- if (Array.isArray( ref )) // $origin: […], not $origin: {…}
132
- parent._origin = refLocation( getOrigin( parent ) );
144
+ if (Array.isArray( ref ) || typeof ref === 'string') // $origin: […], not $origin: {…}
145
+ parent._origin = refLocation( getOrigin( parent, true ) );
146
+ else if ( ref )
147
+ standard( parent, prop, ref )
133
148
  } catch (e) {
134
149
  parent._origin = e.toString();
135
150
  }
@@ -171,10 +186,10 @@ function enrichCsn( csn, options = {} ) {
171
186
  csnPath.pop();
172
187
  }
173
188
 
174
- function _cache_debug( obj ) {
189
+ function _cache_debug( obj, subCache ) {
175
190
  if (options.enrichCsn !== 'DEBUG')
176
191
  return;
177
- const cache = __getCache_forEnrichCsnDebugging( obj );
192
+ const cache = subCache || __getCache_forEnrichCsnDebugging( obj );
178
193
  if (!cache)
179
194
  return;
180
195
  if (cache.$$objectNumber > 0) {
@@ -197,8 +212,20 @@ function enrichCsn( csn, options = {} ) {
197
212
  }
198
213
  else if (name[0] !== '$' || !Object.getPrototypeOf( val )) {
199
214
  // ‹name›: dictionary of CSN nodes,
200
- // ‹$name›: dictionary of cache values if no prototype,
201
- obj.$$cacheObject[name] = Object.keys( val ); // TODO: or dict?
215
+ // ‹$name›: dictionary of cache values if no prototype
216
+ if (name !== '$aliases') {
217
+ obj.$$cacheObject[name] = Object.keys( val ); // TODO: or dict?
218
+ }
219
+ else {
220
+ const sub = Object.create(null);
221
+ for (const n in val) {
222
+ const alias = val[n];
223
+ const c = {};
224
+ _cache_debug( c, alias );
225
+ sub[n] = c.$$cacheObject;
226
+ }
227
+ obj.$$cacheObject[name] = sub;
228
+ }
202
229
  }
203
230
  else if (Array.isArray( val )) {
204
231
  obj.$$cacheObject[name] = val.map( item => {
@@ -13,6 +13,8 @@
13
13
 
14
14
  const msg = require('../base/messages');
15
15
 
16
+ const $inferred = Symbol.for('cds.$inferred');
17
+
16
18
  class NOT_A_DICTIONARY {} // used for consol.log display
17
19
 
18
20
  function locationString( loc ) {
@@ -32,15 +34,22 @@ const kindsRepresentedAsLinks = {
32
34
  // represent SELECTs in query / SET-args property as link:
33
35
  select: (art, parent) => art._main && parent !== art._main.$queries,
34
36
  // represent table alias in from / join-args property as link:
35
- $tableAlias: (art, parent) => art._parent && parent !== art._parent.$tableAliases,
36
- // represent table alias in JOIN node as link:
37
+ $tableAlias: tableAliasAsLink,
38
+ // represent "navigation elemens" in _combined as links:
37
39
  $navElement: (art, parent) => art._parent && parent !== art._parent.elements,
38
40
  // represent mixin in $tableAliases as link:
39
- mixin: (art, parent) => art._parent && parent !== art._parent.mixin,
41
+ mixin: tableAliasAsLink,
40
42
  // represent $projection as link, as it is just another search name for $self:
41
43
  $self: (_a, _p, name) => name !== '$self',
42
44
  }
43
45
 
46
+ function tableAliasAsLink( art, parent, name ) {
47
+ return art._parent && art._parent.$tableAliases && // initXYZ() is run
48
+ parent !== art._parent.$tableAliases && // not in $tableAliases
49
+ !(art.$duplicates === true && name && // and its $duplicates
50
+ parent === art._parent.$tableAliases[name].$duplicates);
51
+ }
52
+
44
53
  function revealInternalProperties( model, name ) {
45
54
  const transformers = {
46
55
  messages: m => m,
@@ -65,6 +74,7 @@ function revealInternalProperties( model, name ) {
65
74
  mixin: dictionary,
66
75
  args: dictionary,
67
76
  $tableAliases: dictionary,
77
+ $duplicates: duplicates,
68
78
  $keysNavigation: dictionary,
69
79
  $layerNumber: n => n,
70
80
  $extra: e => e,
@@ -203,6 +213,8 @@ function revealInternalProperties( model, name ) {
203
213
  for (let prop of Object.getOwnPropertyNames( node )) { // also non-enumerable
204
214
  r[prop] = reveal( node[prop], node, prop );
205
215
  }
216
+ if (node[$inferred] && !node['[$inferred]'])
217
+ r['[$inferred]'] = node[$inferred];
206
218
  return r;
207
219
  }
208
220
 
@@ -228,7 +240,7 @@ function revealInternalProperties( model, name ) {
228
240
  if (node == null || typeof node !== 'object' )
229
241
  return node
230
242
  if (Array.isArray(node))
231
- return node.map( n => reveal( n, node ) );
243
+ return node.map( n => reveal( n, node, name ) );
232
244
 
233
245
  const asLinkTest = kindsRepresentedAsLinks[ node.kind ];
234
246
  if (asLinkTest && asLinkTest( node, parent, name ))
@@ -246,6 +258,10 @@ function revealInternalProperties( model, name ) {
246
258
  }
247
259
  return r;
248
260
  }
261
+
262
+ function duplicates( node, parent ) {
263
+ return reveal( node, parent, parent.name && parent.name.id );
264
+ }
249
265
  }
250
266
 
251
267
  function artifactIdentifier( node, parent ) {
@@ -12,11 +12,12 @@ const {
12
12
  *
13
13
  * @param beforeModel the before-model
14
14
  * @param afterModel the after-model
15
- * @param {hdiOptions|false} options
15
+ * @param {import('../api/main.js').hdiOptions|false} options
16
16
  * @returns {object} the sets of deletions, extensions, and migrations of entities necessary to transform the before-model
17
17
  * to the after-model, together with all the definitions of the after-model
18
18
  */
19
19
  function compareModels(beforeModel, afterModel, options) {
20
+ // @ts-ignore
20
21
  if(!(options && options.testMode)) // no $version with testMode
21
22
  validateCsnVersions(beforeModel, afterModel, options);
22
23
 
@@ -27,8 +27,10 @@ optionProcessor
27
27
  .option(' --internal-msg')
28
28
  .option(' --beta-mode')
29
29
  .option(' --beta <list>')
30
- .option(' --constraints-not-validated')
31
- .option(' --constraints-not-enforced')
30
+ .option(' --integrity-not-validated')
31
+ .option(' --integrity-not-enforced')
32
+ .option(' --assert-integrity <mode>', [ 'true', 'false', 'individual' ])
33
+ .option(' --assert-integrity-type <type>', [ 'RT', 'DB' ])
32
34
  .option(' --deprecated <list>')
33
35
  .option(' --hana-flavor')
34
36
  .option(' --direct-backend')
@@ -39,7 +41,8 @@ optionProcessor
39
41
  .option(' --doc-comment')
40
42
  .option(' --add-texts-language-assoc')
41
43
  .option(' --localized-without-coalesce')
42
- .option(' --defaultStringLength <length>')
44
+ .option(' --default-binary-length <length>')
45
+ .option(' --default-string-length <length>')
43
46
  .option(' --no-recompile')
44
47
  .positionalArgument('<files...>')
45
48
  .help(`
@@ -75,7 +78,8 @@ optionProcessor
75
78
  -- Indicate the end of options (helpful if source names start with "-")
76
79
 
77
80
  Type options
78
- --defaultStringLength <length> Default 'length' for 'cds.String'
81
+ --default-binary-length <length> Default 'length' for 'cds.Binary'
82
+ --default-string-length <length> Default 'length' for 'cds.String'
79
83
 
80
84
  Diagnostic options
81
85
  --trace-parser Trace parser
@@ -90,16 +94,23 @@ optionProcessor
90
94
  --beta-mode Enable all unsupported, incomplete (beta) features
91
95
  --beta <list> Comma separated list of unsupported, incomplete (beta) features to use.
92
96
  Valid values are:
93
- foreignKeyConstraints
94
97
  addTextsLanguageAssoc
95
98
  hanaAssocRealCardinality
96
99
  mapAssocToJoinCardinality
97
100
  ignoreAssocPublishingInUnion
98
- windowFunctions
99
- --constraints-not-enforced If this option is supplied, referential constraints are NOT ENFORCED
100
- This option is also applied to result of "cdsc manageConstraints"
101
- --constraints-not-validated If this option is supplied, referential constraints are NOT VALIDATED
102
- This option is also applied to result of "cdsc manageConstraints"
101
+ --integrity-not-enforced If this option is supplied, referential constraints are NOT ENFORCED.
102
+ This option is also applied to result of "cdsc manageConstraints"
103
+ --integrity-not-validated If this option is supplied, referential constraints are NOT VALIDATED.
104
+ This option is also applied to result of "cdsc manageConstraints"
105
+ --assert-integrity <mode> Turn DB constraints on/off:
106
+ true : Constraints will be generated for all associations if
107
+ the assert-integrity-type is set to DB
108
+ false : No constraints will be generated
109
+ individual : Constraints will be generated for selected associations
110
+ --assert-integrity-type <type> Specifies how the referential integrity checks should be performed:
111
+ RT : (default) No database constraint for an association
112
+ if not explicitly demanded via annotation
113
+ DB : Create database constraints for associations
103
114
  --deprecated <list> Comma separated list of deprecated options.
104
115
  Valid values are:
105
116
  noElementsExpansion
@@ -130,7 +141,7 @@ optionProcessor
130
141
  to "sap.common.Languages" if it exists
131
142
  --localized-without-coalesce Omit coalesce in localized convenience views
132
143
  --no-recompile Don't recompile in case of internal errors
133
-
144
+
134
145
  Commands
135
146
  H, toHana [options] <files...> Generate HANA CDS source files
136
147
  O, toOdata [options] <files...> Generate ODATA metadata and annotations
@@ -140,7 +151,7 @@ optionProcessor
140
151
  parseCdl [options] <file> Generate a CSN that is close to the CDL source.
141
152
  explain <message-id> Explain a compiler message.
142
153
  toRename [options] <files...> (internal) Generate SQL DDL rename statements
143
- manageConstraints [options] <files...> (internal) Generate ALTER TABLE statements to
154
+ manageConstraints [options] <files...> (internal) Generate ALTER TABLE statements to
144
155
  add / modify referential constraints.
145
156
  `);
146
157
 
@@ -150,7 +161,6 @@ optionProcessor.command('H, toHana')
150
161
  .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
151
162
  .option(' --render-virtual')
152
163
  .option(' --joinfk')
153
- .option(' --skip-db-constraints')
154
164
  .option('-u, --user <user>')
155
165
  .option('-s, --src')
156
166
  .option('-c, --csn')
@@ -174,7 +184,6 @@ optionProcessor.command('H, toHana')
174
184
  using element names with dots).
175
185
  --render-virtual Render virtual elements in views and draft tables
176
186
  --joinfk Create JOINs for foreign key accesses
177
- --skip-db-constraints Do not render referential constraints for associations
178
187
  -u, --user <user> Value for the "$user" variable
179
188
  -s, --src (default) Generate HANA CDS source files "<artifact>.hdbcds"
180
189
  -c, --csn Generate "hana_csn.json" with HANA-preprocessed model
@@ -241,7 +250,6 @@ optionProcessor.command('Q, toSql')
241
250
  .option('-n, --names <style>', ['plain', 'quoted', 'hdbcds'])
242
251
  .option(' --render-virtual')
243
252
  .option(' --joinfk')
244
- .option(' --skip-db-constraints')
245
253
  .option('-d, --dialect <dialect>', ['hana', 'sqlite', 'plain'])
246
254
  .option('-u, --user <user>')
247
255
  .option('-l, --locale <locale>')
@@ -267,7 +275,6 @@ optionProcessor.command('Q, toSql')
267
275
  combination with "hana" dialect.
268
276
  --render-virtual Render virtual elements in views and draft tables
269
277
  --joinfk Create JOINs for foreign key accesses
270
- --skip-db-constraints Do not render referential constraints for associations
271
278
  -d, --dialect <dialect> SQL dialect to be generated:
272
279
  plain : (default) Common SQL - no assumptions about DB restrictions
273
280
  hana : SQL with HANA specific language features
@@ -315,7 +322,7 @@ optionProcessor.command('manageConstraints')
315
322
 
316
323
  (internal, subject to change): Generate SQL DDL ALTER TABLE statements to add / modify
317
324
  referential constraints on an existing model.
318
- Combine with options "--constraints-not-enforced" and "--constraint-not-validated"
325
+ Combine with options "--integrity-not-enforced" and "--integrity-not-validated"
319
326
  to switch off foreign key constraint enforcement / validation.
320
327
 
321
328
  Options
@@ -363,6 +370,7 @@ optionProcessor.command('toCsn')
363
370
 
364
371
  optionProcessor.command('parseCdl')
365
372
  .option('-h, --help')
373
+ .positionalArgument('<file>')
366
374
  .help(`
367
375
  Usage: cdsc parseCdl [options] <file>
368
376
 
@@ -375,14 +383,17 @@ optionProcessor.command('parseCdl')
375
383
 
376
384
  optionProcessor.command('explain')
377
385
  .option('-h, --help')
386
+ .positionalArgument('<message-id>')
378
387
  .help(`
379
388
  Usage: cdsc explain [options] <message-id>
380
389
 
381
390
  Explain the compiler message that has the given message-id.
382
391
  The explanation contains a faulty example and a solution.
383
392
 
393
+ Use \`explain list\` to list all available messages.
394
+
384
395
  Options
385
- -h, --help Show this help text
396
+ -h, --help Show this help text
386
397
  `);
387
398
 
388
399
  module.exports = {
@@ -44,7 +44,7 @@ class DuplicateChecker {
44
44
  * Add an artifact to the "seen"-list
45
45
  *
46
46
  * @param {string} name Persistence name of the artifact
47
- * @param {CSN.Location} location CSN location of the artifact
47
+ * @param {CSN.Location|CSN.Path} location CSN location of the artifact
48
48
  * @param {string} modelName CSN artifact name
49
49
  */
50
50
  addArtifact( name, location, modelName ) {
@@ -10,7 +10,7 @@ const {
10
10
  const keywords = require('../base/keywords');
11
11
  const { renderFunc, beautifyExprArray, findElement } = require('./utils/common');
12
12
  const { checkCSNVersion } = require('../json/csnVersion');
13
- const timetrace = require('../utils/timetrace');
13
+ const { timetrace } = require('../utils/timetrace');
14
14
  const { csnRefs } = require('../model/csnRefs');
15
15
  const { forEachDefinition } = require('../model/csnUtils');
16
16
  const enrichUniversalCsn = require('../transform/universalCsnEnricher');
@@ -579,7 +579,7 @@ function toCdsSourceCsn(csn, options) {
579
579
  * @return {string}
580
580
  */
581
581
  function renderQueryActionsAndFunctions(artifactName, art, env) {
582
- let result = renderDocComment(art, env) + renderActionsAndFunctions(art, env);
582
+ let result = renderActionsAndFunctions(art, env);
583
583
  // Even if we have seen actions/functions, they might all have been ignored
584
584
  if (result !== '')
585
585
  result = `${env.indent}extend entity ${artifactName} with${result};`;
@@ -612,7 +612,7 @@ function toCdsSourceCsn(csn, options) {
612
612
  }
613
613
  // Now iterate elements - render an annotation if it is different from the column's
614
614
  const childEnv = increaseIndent(env);
615
- let result = renderDocComment(art, env);
615
+ let result = '';
616
616
  for (const elemName in art.elements) {
617
617
  let elemAnnotations = '';
618
618
  const elem = art.elements[elemName];
@@ -1404,6 +1404,12 @@ function toCdsSourceCsn(csn, options) {
1404
1404
  // FIXME: no extra magic with x.param or x.global
1405
1405
  return `${(x.param || x.global) ? ':' : ''}${x.ref.map(renderPathStep).join('.')}`;
1406
1406
  }
1407
+ else if (x.xpr && x.func) {
1408
+ // window function
1409
+ const funcDef = renderFunc( x.func, x, null, a => renderArgs(a, '=>', env) );
1410
+ const windowFunctionOperator = x.xpr.shift(); // OVER ...
1411
+ return `${funcDef} ${windowFunctionOperator} ( ${renderExpr(x.xpr, env, true)} )`;
1412
+ }
1407
1413
  // Function call, possibly with args (use '=>' for named args)
1408
1414
  else if (x.func) {
1409
1415
  // test for non-regular HANA identifier that needs to be quoted