@sap/cds-compiler 6.7.3 → 6.9.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 (116) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +4 -0
  3. package/bin/cdsc.js +5 -5
  4. package/bin/cdshi.js +1 -0
  5. package/bin/cdsse.js +1 -1
  6. package/lib/api/main.js +17 -9
  7. package/lib/api/options.js +5 -2
  8. package/lib/api/validate.js +1 -1
  9. package/lib/base/builtins.js +13 -9
  10. package/lib/{model → base}/csnRefs.js +8 -10
  11. package/lib/base/error.js +2 -0
  12. package/lib/base/message-registry.js +68 -4
  13. package/lib/base/messages.js +4 -2
  14. package/lib/{optionProcessor.js → base/optionProcessor.js} +5 -3
  15. package/lib/base/{model.js → specialOptions.js} +16 -39
  16. package/lib/checks/arrayOfs.js +1 -1
  17. package/lib/checks/elements.js +1 -1
  18. package/lib/checks/enricher.js +2 -2
  19. package/lib/checks/featureFlags.js +54 -24
  20. package/lib/checks/foreignKeys.js +1 -1
  21. package/lib/checks/invalidTarget.js +1 -1
  22. package/lib/checks/managedInType.js +1 -1
  23. package/lib/checks/onConditions.js +1 -1
  24. package/lib/checks/queryNoDbArtifacts.js +1 -1
  25. package/lib/checks/validator.js +10 -14
  26. package/lib/compiler/assert-consistency.js +11 -9
  27. package/lib/compiler/base.js +5 -1
  28. package/lib/compiler/builtins.js +1 -1
  29. package/lib/compiler/checks.js +3 -3
  30. package/lib/compiler/define.js +6 -3
  31. package/lib/{base → compiler}/dictionaries.js +4 -3
  32. package/lib/compiler/extend.js +121 -21
  33. package/lib/compiler/generate.js +2 -2
  34. package/lib/compiler/index.js +11 -3
  35. package/lib/compiler/kick-start.js +1 -1
  36. package/lib/compiler/lsp-api.js +3 -3
  37. package/lib/compiler/populate.js +6 -7
  38. package/lib/compiler/resolve.js +53 -36
  39. package/lib/compiler/shared.js +68 -18
  40. package/lib/compiler/tweak-assocs.js +2 -2
  41. package/lib/compiler/utils.js +28 -27
  42. package/lib/compiler/xpr-rewrite.js +3 -3
  43. package/lib/edm/EdmPrimitiveTypeDefinitions.js +4 -1
  44. package/lib/edm/annotations/edmJson.js +2 -4
  45. package/lib/edm/annotations/genericTranslation.js +51 -7
  46. package/lib/edm/csn2edm.js +3 -2
  47. package/lib/edm/edmAnnoPreprocessor.js +1 -1
  48. package/lib/edm/edmInboundChecks.js +2 -1
  49. package/lib/edm/edmPreprocessor.js +3 -3
  50. package/lib/edm/edmUtils.js +2 -2
  51. package/lib/gen/BaseParser.js +59 -108
  52. package/lib/gen/CdlGrammar.checksum +1 -1
  53. package/lib/gen/CdlParser.js +2052 -1965
  54. package/lib/gen/Dictionary.json +67 -7
  55. package/lib/json/from-csn.js +14 -14
  56. package/lib/json/to-csn.js +77 -38
  57. package/lib/main.js +3 -3
  58. package/lib/model/csnUtils.js +2 -2
  59. package/lib/modelCompare/compare.js +1 -1
  60. package/lib/modelCompare/utils/filter.js +1 -0
  61. package/lib/parsers/AstBuildingParser.js +83 -33
  62. package/lib/parsers/index.js +1 -1
  63. package/lib/render/manageConstraints.js +1 -1
  64. package/lib/render/toCdl.js +49 -30
  65. package/lib/render/toHdbcds.js +2 -2
  66. package/lib/render/toSql.js +16 -7
  67. package/lib/render/utils/common.js +11 -3
  68. package/lib/render/utils/sql.js +14 -5
  69. package/lib/render/utils/standardDatabaseFunctions.js +108 -99
  70. package/lib/sql-identifier.js +9 -1
  71. package/lib/{model → tool-lib}/enrichCsn.js +3 -2
  72. package/lib/{model → tool-lib}/revealInternalProperties.js +2 -1
  73. package/lib/transform/addTenantFields.js +1 -1
  74. package/lib/transform/db/applyTransformations.js +1 -1
  75. package/lib/transform/db/assertUnique.js +1 -1
  76. package/lib/transform/db/assocsToQueries/transformExists.js +1 -1
  77. package/lib/transform/db/backlinks.js +2 -2
  78. package/lib/transform/db/expansion.js +2 -2
  79. package/lib/transform/db/flattening.js +3 -4
  80. package/lib/transform/db/killAnnotations.js +1 -0
  81. package/lib/transform/db/processSqlServices.js +2 -1
  82. package/lib/transform/db/rewriteCalculatedElements.js +2 -2
  83. package/lib/transform/db/temporal.js +30 -5
  84. package/lib/transform/db/views.js +16 -20
  85. package/lib/transform/draft/db.js +1 -2
  86. package/lib/transform/effective/associations.js +1 -1
  87. package/lib/transform/effective/flattening.js +6 -5
  88. package/lib/transform/effective/main.js +24 -4
  89. package/lib/transform/effective/types.js +1 -1
  90. package/lib/transform/{odata/fioriTreeViews.js → fioriTreeViews.js} +48 -25
  91. package/lib/transform/forOdata.js +25 -7
  92. package/lib/transform/forRelationalDB.js +48 -12
  93. package/lib/transform/localized.js +2 -2
  94. package/lib/transform/odata/createForeignKeys.js +1 -1
  95. package/lib/transform/odata/flattening.js +2 -2
  96. package/lib/transform/odata/toFinalBaseType.js +3 -2
  97. package/lib/transform/odata/typesExposure.js +3 -2
  98. package/lib/transform/transformUtils.js +2 -2
  99. package/lib/transform/translateAssocsToJoins.js +2 -1
  100. package/lib/transform/tupleExpansion.js +44 -4
  101. package/lib/transform/universalCsn/universalCsnEnricher.js +7 -3
  102. package/lib/transform/universalCsn/utils.js +1 -1
  103. package/lib/{base → utils}/lazyload.js +9 -0
  104. package/lib/{base → utils}/node-helpers.js +2 -0
  105. package/lib/utils/objectUtils.js +29 -6
  106. package/lib/{base → utils}/optionProcessorHelper.js +16 -6
  107. package/package.json +3 -40
  108. /package/lib/{model → base}/cloneCsn.js +0 -0
  109. /package/lib/{model/api.js → base/model-api.js} +0 -0
  110. /package/lib/{api → base}/trace.js +0 -0
  111. /package/lib/{model → base}/xprAsTree.js +0 -0
  112. /package/lib/{inspect → tool-lib}/index.js +0 -0
  113. /package/lib/{inspect → tool-lib}/inspectModelStatistics.js +0 -0
  114. /package/lib/{inspect → tool-lib}/inspectPropagation.js +0 -0
  115. /package/lib/{inspect → tool-lib}/inspectUtils.js +0 -0
  116. /package/lib/{base → utils}/shuffle.js +0 -0
package/CHANGELOG.md CHANGED
@@ -13,6 +13,76 @@ we might not list every change in its behavior here.
13
13
  Productive code should never require a `beta` flag to be set, and
14
14
  might use a deprecated flag only for a limited period of time.
15
15
 
16
+ ## Version 6.9.0 - 2026-04-21
17
+
18
+ ### Features
19
+
20
+ - **compiler:**
21
+ + add support for extending views/projections with several SQL clauses:
22
+ `where`, `group by`, `having`, `order by`, `limit`
23
+ + allow extending derived enum types/elements by adding enum symbols
24
+ + inside `extend … with enum {…}`, it is now possible to use `extend existingEnumSymbol with @Anno`,
25
+ like it is already possible inside `extend … with {…}`
26
+ + when the new options `v7KeyPropagation` is set, the propagation of the `key` property in queries is simplified,
27
+ and the `key` property is not propagated when including structures into types
28
+ - **odata:** set `meta.compilerCsnFlavor` in the OData transformed CSN
29
+ - **seal**: set `meta.compilerCsnFlavor` in the SEAL transformed CSN
30
+ - **effective:** set `meta.compilerCsnFlavor` in the effective CSN
31
+ - **sql:**
32
+ + set `meta.compilerCsnFlavor` in SQL transformed CSN
33
+ + allow single-leafed structures within a `list` on the left-hand side of the `IN` operator.
34
+ For example `(author, struct) in (...)` becomes `(author_ID, struct_leaf) in (...)`.
35
+ + support `cds.Vector` on Postgres and H2
36
+
37
+ ### Bug Fixes
38
+
39
+ - **compiler:**
40
+ + don't introduce a strange `cast` property in the CSN for a column with an expand on a to-many association
41
+ + while crawling tokens for LSP, allow extensions without name
42
+ - **effective:** don't absolutify paths in filters in annotations
43
+ - **sql:** properly resolve references in annotation values and `on` conditions for a column inside an expand without base reference
44
+
45
+ ### Improvements
46
+
47
+ - **compiler:**
48
+ + add `compilerVersion` to CSN meta
49
+ + issue a warning if a structure in an annotation value would have the same CSN representation as an expression
50
+ + issue warnings for extends on built-in types
51
+ + warn on duplicate members from includes via extend
52
+ - **odata:**
53
+ + update OData vocabularies: Common, Core, UI
54
+ + using `@readonly` with an expression value on entities or aspects is no longer silently accepted and now produces an error
55
+
56
+
57
+
58
+ ## Version 6.8.0 - 2026-03-05
59
+
60
+ ### Features
61
+
62
+ - **api:** basic experimental support for code completion in `cds repl`
63
+ - **compiler:**
64
+ + retain original meta property in CSN
65
+ + add compilerCsnFlavor to meta property
66
+ - **sql:**
67
+ + Add support for `cds.Vector`
68
+ + Allow migration from cds.String to cds.LargeString
69
+ + Fiori Tree Views in the database backend
70
+ + For postgres: warning for identifiers that exceed the databases length limit
71
+
72
+ ### Bug Fixes
73
+
74
+ - **sql:**
75
+ + do not report validation errors on entities marked as `@cds.persistence.skip`
76
+ + normalize named arguments for portable functions
77
+ + properly flatten associations for temporal unique constraints
78
+
79
+ ### Improvements
80
+
81
+ - **compiler:**
82
+ + improve warning in case of invalid type for key
83
+ + simplify syntax error text when expecting Comparison and Operator tokens
84
+ + improve support for code completion with `case` expressions, queries, and subqueries
85
+
16
86
  ## Version 6.7.3 - 2026-02-11
17
87
 
18
88
  ### Fixed
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Getting started
2
2
 
3
3
 
4
+
4
5
  ## Installation and Usage
5
6
 
6
7
  Install with npm:
@@ -20,16 +21,19 @@ Or maintain your package.json dependencies as follows:
20
21
  If your project already has a dependency to `@sap/cds`, nothing has to be done.
21
22
 
22
23
 
24
+
23
25
  ## Documentation
24
26
 
25
27
  Please refer to the [official CDS documentation](https://cap.cloud.sap/docs/cds/).
26
28
 
27
29
 
30
+
28
31
  ## How to Obtain Support
29
32
 
30
33
  In case you find a bug, please report an [incident](https://cap.cloud.sap/docs/resources/#reporting-incidents) on SAP Support Portal.
31
34
 
32
35
 
36
+
33
37
  ## History and License
34
38
 
35
39
  The cds-compiler uses [Semantic Versioning](./doc/Versioning.md) for its version numbers.
package/bin/cdsc.js CHANGED
@@ -25,9 +25,9 @@ const { toRename: _toRename } = require('../lib/render/toRename');
25
25
  const util = require('util');
26
26
  const fs = require('fs');
27
27
  const path = require('path');
28
- const { reveal } = require('../lib/model/revealInternalProperties');
29
- const enrichCsn = require('../lib/model/enrichCsn');
30
- const { optionProcessor } = require('../lib/optionProcessor');
28
+ const { reveal } = require('../lib/tool-lib/revealInternalProperties');
29
+ const enrichCsn = require('../lib/tool-lib/enrichCsn');
30
+ const { optionProcessor } = require('../lib/base/optionProcessor');
31
31
  const {
32
32
  explainMessage, hasMessageExplanation, sortMessages,
33
33
  messageIdsWithExplanation, makeMessageFunction,
@@ -35,7 +35,7 @@ const {
35
35
  const { term } = require('../lib/utils/term');
36
36
  const { addLocalizationViews } = require('../lib/transform/localized');
37
37
  const { addTenantFields } = require('../lib/transform/addTenantFields');
38
- const { availableBetaFlags } = require('../lib/base/model');
38
+ const { availableBetaFlags } = require('../lib/base/specialOptions');
39
39
  const { alterConstraintsWithCsn } = require('../lib/render/manageConstraints');
40
40
  const { tmpFilePath, readStream } = require('../lib/utils/file');
41
41
 
@@ -548,7 +548,7 @@ async function executeCommandLine( command, options, args ) {
548
548
  }
549
549
 
550
550
  function inspect( model ) {
551
- const inspectModel = require('../lib/inspect');
551
+ const inspectModel = require('../lib/tool-lib');
552
552
 
553
553
  if (options.statistics) {
554
554
  const result = inspectModel.inspectModelStatistics(model, options);
package/bin/cdshi.js CHANGED
@@ -32,6 +32,7 @@ const categoryChars = { // default: first char of category name
32
32
  ExtService: 'S', // highlight like service definition
33
33
  ExtContext: 'C', // highlight like context definition
34
34
  // ExtElement: 'E', // using the first letter is the default
35
+ ExtEnum: 'H', // highlight like enum symbol definition
35
36
  ExtBoundAction: 'B', // highlight like bound action definition
36
37
  ExtParam: 'P', // highlight like entity/action parameter definition
37
38
  FromImplicit: 'W',
package/bin/cdsse.js CHANGED
@@ -25,7 +25,7 @@ const path = require('path');
25
25
  const compiler = require('../lib/compiler');
26
26
  const main = require('../lib/main');
27
27
  const { locationString } = require('../lib/base/messages');
28
- const { availableBetaFlags: beta } = require('../lib/base/model');
28
+ const { availableBetaFlags: beta } = require('../lib/base/specialOptions');
29
29
 
30
30
  const { argv } = process;
31
31
  const cmd = commands[argv[2]];
package/lib/api/main.js CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  'use strict';
4
4
 
5
- const lazyload = require('../base/lazyload')( module );
5
+ const lazyload = require('../utils/lazyload')( module );
6
6
 
7
7
  const prepareOptions = lazyload('./options');
8
- const baseModel = lazyload('../base/model');
8
+ const specialOptions = lazyload('../base/specialOptions');
9
9
  const location = lazyload('../base/location');
10
10
  const messages = lazyload('../base/messages');
11
11
  const compiler = lazyload('../compiler/index');
@@ -27,8 +27,8 @@ const effective = lazyload('../transform/effective/main');
27
27
  const toHdbcds = lazyload('../render/toHdbcds');
28
28
  const baseError = lazyload('../base/error');
29
29
  const csnToEdm = lazyload('../edm/csn2edm');
30
- const trace = lazyload('./trace');
31
- const cloneCsn = lazyload('../model/cloneCsn');
30
+ const trace = lazyload('../base/trace');
31
+ const cloneCsn = lazyload('../base/cloneCsn');
32
32
  const objectUtils = lazyload('../utils/objectUtils');
33
33
 
34
34
  /**
@@ -56,6 +56,7 @@ const warnAboutMismatchOdata = [ 'odataVersion' ];
56
56
  * @param {string[]} relevantOptionNames Option names that are defining characteristics
57
57
  * @param {string[]} [optionalOptionNames] Option names that should be attached as a fyi
58
58
  */
59
+ // TODO: move this function to some other place
59
60
  function attachTransformerCharacteristics( csn, transformation, options,
60
61
  relevantOptionNames, optionalOptionNames = [] ) {
61
62
  const relevant = {};
@@ -75,10 +76,10 @@ function attachTransformerCharacteristics( csn, transformation, options,
75
76
  relevant[name] = options[name];
76
77
  }
77
78
  if (!csn.meta)
78
- baseModel.setProp(csn, 'meta', {});
79
+ objectUtils.setProp(csn, 'meta', {});
79
80
 
80
- baseModel.setProp(csn.meta, 'options', relevant);
81
- baseModel.setProp(csn.meta, 'transformation', transformation);
81
+ objectUtils.setProp(csn.meta, 'options', relevant);
82
+ objectUtils.setProp(csn.meta, 'transformation', transformation);
82
83
  }
83
84
 
84
85
  /**
@@ -306,7 +307,14 @@ function forEffectiveInternal( csn, options, internalOptions, messageFunctions )
306
307
  function forSeal( csn, options, messageFunctions ) {
307
308
  const internalOptions = prepareOptions.for.seal(options);
308
309
  internalOptions.transformation = 'effective';
309
- return forEffectiveInternal(csn, options, internalOptions, messageFunctions);
310
+ const result = forEffectiveInternal(csn, options, internalOptions, messageFunctions);
311
+
312
+ if (!options.testMode) {
313
+ result.meta ??= {};
314
+ result.meta.compilerCsnFlavor = 'seal';
315
+ }
316
+
317
+ return result;
310
318
  }
311
319
 
312
320
  /**
@@ -1166,7 +1174,7 @@ function publishCsnProcessor( processor, _name ) {
1166
1174
  try {
1167
1175
  const messageFunctions = messages.makeMessageFunction(csn, options, _name);
1168
1176
  if (options.deprecated)
1169
- baseModel.checkRemovedDeprecatedFlags( options, messageFunctions );
1177
+ specialOptions.checkRemovedDeprecatedFlags( options, messageFunctions );
1170
1178
 
1171
1179
  checkOutdatedOptions( options, messageFunctions );
1172
1180
  csn = ensureClientCsn( csn, options, messageFunctions, _name );
@@ -1,8 +1,9 @@
1
1
  'use strict';
2
2
 
3
- // The options are specified in ../optionProcessor.js (and some other files).
3
+ // The options are specified in ../base/optionProcessor.js (and some other files).
4
4
  // Some backends feel the need to "translate" option, which require to list
5
- // all options also here (as public" or "private" option).
5
+ // all options also here (as "public" or "private" option).
6
+ // Parser and core compiler options might not have been listed here.
6
7
 
7
8
  const { validate, generateStringValidator } = require('./validate');
8
9
  const { makeMessageFunction } = require('../base/messages');
@@ -25,6 +26,7 @@ const publicOptionsNewAPI = [
25
26
  'defaultStringLength',
26
27
  'csnFlavor',
27
28
  'noDollarCalc',
29
+ 'v7KeyPropagation',
28
30
  // DB
29
31
  'sqlDialect',
30
32
  'sqlMapping',
@@ -36,6 +38,7 @@ const publicOptionsNewAPI = [
36
38
  'pre2134ReferentialConstraintNames',
37
39
  'betterSqliteSessionVariables',
38
40
  'fewerLocalizedViews',
41
+ 'sqliteRealAffinityForDecimal',
39
42
  'withHanaAssociations',
40
43
  'standardDatabaseFunctions',
41
44
  'booleanEquality',
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- // The options are specified in ../optionProcessor.js (and some other files).
3
+ // The options are specified in ../base/optionProcessor.js (and some other files).
4
4
  // Options with non-boolean values must also be listed in this file.
5
5
 
6
6
  const { forEach } = require('../utils/objectUtils');
@@ -89,29 +89,33 @@ function isMagicVariable( name ) {
89
89
  }
90
90
 
91
91
  /**
92
- * Properties that are required next to `=` to make an annotation value an actual expression
93
- * and not some foreign structure.
92
+ * Properties (without those from CSN v0.1.0) that make an annotation object value
93
+ * an actual expression and not some foreign structure.
94
94
  *
95
95
  * @type {string[]}
96
96
  */
97
- const xprInAnnoProperties = [
98
- 'ref', 'xpr', 'list', 'literal', 'val',
99
- '#', 'func', 'args', 'SELECT', 'SET',
100
- 'cast',
97
+ const primaryExprProperties = [
98
+ 'ref', 'xpr', 'list', 'val', '#', 'func', 'SELECT', 'SET',
99
+ ];
100
+ // only with 'ref'/'val'/'func'/misc:
101
+ const exprProperties = [
102
+ ...primaryExprProperties,
103
+ 'param', 'literal', 'args', 'cast',
101
104
  ];
102
-
103
105
 
104
106
  /**
105
107
  * Return whether JSON object `val` is a representation for an annotation expression
106
108
  */
107
109
  function isAnnotationExpression( val ) {
108
- return val?.['='] !== undefined && xprInAnnoProperties.some( prop => val[prop] !== undefined );
110
+ return val?.['='] !== undefined && // TODO: truthy
111
+ primaryExprProperties.some( prop => val[prop] !== undefined );
109
112
  }
110
113
 
111
114
  module.exports = {
112
115
  propagationRules,
113
116
  acceptsExprValues,
114
- xprInAnnoProperties,
117
+ primaryExprProperties,
118
+ exprProperties,
115
119
  isInReservedNamespace,
116
120
  isBuiltinType,
117
121
  isMagicVariable,
@@ -784,14 +784,15 @@ function csnRefs( csn, universalReady ) {
784
784
  const target = assocTarget( parent, refCtx );
785
785
  return resolvePath( path, target.elements[head], target, 'target' );
786
786
  }
787
- if (baseEnv) { // ref-target (filter condition), expand, inline
788
- if (semantics.dynamic !== 'query')
789
- return resolvePath( path, baseEnv.elements[head], baseEnv, semantics.dynamic );
790
- // in an ON condition of an association inside inner expand/inline:
787
+ if (semantics.dynamic === 'query') {
788
+ // in an anno, or an ON condition of an association inside inner expand/inline:
791
789
  const elemParent = getCache( parent, '_element' );
792
- if (elemParent) // expand in expand
790
+ if (elemParent?.elements) // expand in expand
793
791
  return resolvePath( path, elemParent.elements[head], null, 'query' );
794
792
  }
793
+ else if (baseEnv) { // ref-target (filter condition), expand, inline
794
+ return resolvePath( path, baseEnv.elements[head], baseEnv, semantics.dynamic );
795
+ }
795
796
  if (!query) { // outside queries - TODO: items?
796
797
  // refs in annos on foreign keys use fk name, not fk ref name:
797
798
  const dict = parent.elements ?? getCache( parent, '_keys' );
@@ -810,11 +811,9 @@ function csnRefs( csn, universalReady ) {
810
811
  if (!qcache)
811
812
  throw new CompilerAssertion( `For semantics '${ refCtx }', query not in cache at: ${ locationString(query.$location) }` );
812
813
 
813
- if (semantics.dynamic === 'query') {
814
- // TODO: for ON condition in expand, would need to use cached _element
815
- // TODO: test and implement - Issue #11792!
814
+ if (semantics.dynamic === 'query')
816
815
  return resolvePath( path, qcache.elements[head], null, 'query' );
817
- }
816
+
818
817
  for (const name in qcache.$aliases) {
819
818
  const alias = qcache.$aliases[name];
820
819
  const found = alias.elements[head];
@@ -1144,7 +1143,6 @@ function analyseCsnPath( csnPath, csn, resolve ) {
1144
1143
  baseEnv = resolve.expandInline( obj, baseCtx, main, query, parent, baseEnv );
1145
1144
  refCtx = prop;
1146
1145
  }
1147
- // TODO: for on condition in expand, also set an environment
1148
1146
  isName = prop;
1149
1147
  }
1150
1148
  else if (prop === 'on') {
package/lib/base/error.js CHANGED
@@ -1,3 +1,5 @@
1
+ // Special error classes for compiler
2
+
1
3
  'use strict';
2
4
 
3
5
  /**
@@ -36,7 +36,7 @@
36
36
  'use strict';
37
37
 
38
38
  const { CompilerAssertion } = require( './error' );
39
- const { isDeprecatedEnabled } = require( './model' );
39
+ const { isDeprecatedEnabled } = require( './specialOptions' );
40
40
 
41
41
  const configurableForValidValues = {
42
42
  __proto__: null,
@@ -89,6 +89,7 @@ const centralMessages = {
89
89
  'anno-invalid-sql-kind': { severity: 'Error', configurableFor: true }, // @sql.prepend/append - configurable for "I know what I'm doing"
90
90
  'anno-invalid-sql-view': { severity: 'Error', configurableFor: true }, // @sql.prepend/append - configurable for "I know what I'm doing"
91
91
  'anno-invalid-sql-view-element': { severity: 'Error', configurableFor: true }, // @sql.prepend/append - configurable for "I know what I'm doing"
92
+ 'ext-duplicate-include': { severity: 'Warning', errorFor: [ 'v7' ] },
92
93
  'ext-undefined-action': { severity: 'Warning' },
93
94
  'ext-undefined-art': { severity: 'Warning' }, // for annotate statement (for CDL path root)
94
95
  'ext-undefined-def': { severity: 'Warning' }, // for annotate statement (for CSN or CDL path cont)
@@ -100,6 +101,7 @@ const centralMessages = {
100
101
  'ext-undefined-element-sec': { severity: 'Error', configurableFor: true }, // for security-relevant…
101
102
  'ext-undefined-action-sec': { severity: 'Error', configurableFor: true }, // for security-relevant…
102
103
  'ext-undefined-param-sec': { severity: 'Error', configurableFor: true }, // … annotate statement
104
+ 'ext-unexpected-type-property': { severity: 'Warning', errorFor: [ 'v7' ] },
103
105
  'ext-unexpected-returns': { severity: 'Warning' },
104
106
  'ext-unexpected-returns-sec': { severity: 'Error', configurableFor: true }, // … annotate statement
105
107
  'anno-unexpected-ellipsis': { severity: 'Error', configurableFor: 'deprecated' },
@@ -125,8 +127,11 @@ const centralMessages = {
125
127
  'empty-type': { severity: 'Info' }, // only still an error in old transformers
126
128
 
127
129
  'ref-deprecated-orderby': { severity: 'Error', configurableFor: true },
128
- 'ref-deprecated-self-element': { severity: 'Error', configurableFor: true },
130
+ 'ref-deprecated-self-element': { severity: 'Error', configurableFor: 'v7' },
129
131
  'ref-deprecated-variable': { severity: 'Warning' },
132
+ 'ref-deprecated-in-extend': { severity: 'Warning' },
133
+ 'ref-special-in-extend': { severity: 'Warning' },
134
+ 'ref-unexpected-in-extend': { severity: 'Error' },
130
135
  'ref-invalid-type': { severity: 'Error' },
131
136
  'ref-unexpected-self': { severity: 'Error' },
132
137
  'ref-invalid-include': { severity: 'Error' },
@@ -135,6 +140,7 @@ const centralMessages = {
135
140
  'type-ignoring-argument': { severity: 'Error', configurableFor: true },
136
141
  'type-expected-builtin': { severity: 'Error', configurableFor: true },
137
142
  'type-expecting-service-target': { severity: 'Error', configurableFor: true },
143
+ 'type-invalid-for-key': { severity: 'Warning' },
138
144
  'ref-expecting-const': { severity: 'Error' },
139
145
  'ref-expecting-foreign-key': { severity: 'Error' },
140
146
  'ref-invalid-source': { severity: 'Error' },
@@ -154,6 +160,7 @@ const centralMessages = {
154
160
  'query-unexpected-structure-hdbcds': { severity: 'Error' },
155
161
  'query-ignoring-param-nullability': { severity: 'Info' },
156
162
  'query-expected-identifier': { severity: 'Error' },
163
+ 'query-invalid-identifier': { severity: 'Warning' },
157
164
 
158
165
  'recalculated-localized': { severity: 'Info' }, // KEEP: Downgrade in lib/transform/translateAssocsToJoins.js
159
166
  'redirected-implicitly-ambiguous': { severity: 'Error', configurableFor: true }, // does not hurt us - TODO: ref-ambiguous-target
@@ -202,6 +209,8 @@ const centralMessages = {
202
209
  // remark: a hard syntax error in new parser for `null` together with `not null`
203
210
  'syntax-duplicate-equal-clause': { severity: 'Warning' },
204
211
  'syntax-invalid-name': { severity: 'Error' },
212
+ 'syntax-invalid-anno-struct': { severity: 'Warning', errorFor: [ 'v7' ] },
213
+ 'syntax-invalid-nested-proj': { severity: 'Warning', errorFor: [ 'v7' ] },
205
214
  'syntax-missing-as': { severity: 'Error', configurableFor: true },
206
215
  'syntax-missing-proj-semicolon': { severity: 'Warning' },
207
216
  'syntax-unexpected-after': { severity: 'Error' },
@@ -246,6 +255,7 @@ const centralMessages = {
246
255
  'odata-unexpected-nullable-key': { severity: 'Error', configurableFor: true },
247
256
  'odata-invalid-key-type': { severity: 'Warning' },
248
257
  'odata-invalid-property-name': { severity: 'Warning' },
258
+ 'odata-unexpected-xpr-anno': { severity: 'Error', configurableFor: true },
249
259
  'odata-anno-preproc': { severity: 'Warning' },
250
260
  'odata-anno-dict': { severity: 'Warning' },
251
261
  'odata-anno-vocref': { severity: 'Warning' },
@@ -533,6 +543,10 @@ const centralMessageTexts = {
533
543
  dot: 'Use a $(NEWCODE), not a $(CODE) after the arguments or filter on an entity',
534
544
  colon: 'Use a $(NEWCODE), not a $(CODE) between the element names in a reference',
535
545
  },
546
+ 'syntax-invalid-anno-struct': {
547
+ std: 'Most CSN processors interpret a structure with property $(PROP) as expression',
548
+ ref: 'Most CSN processors interpret a structure with property $(PROP) as reference',
549
+ },
536
550
  // 'syntax-ignoring-doc-comment' (Info)
537
551
  'syntax-unexpected-reserved-word': '$(CODE) is a reserved word - write $(DELIMITED) instead if you want to use it as name',
538
552
  'syntax-invalid-text-block': 'Missing newline in text block',
@@ -708,6 +722,14 @@ const centralMessageTexts = {
708
722
  type: 'Illegal recursive type definition to $(TYPE)',
709
723
  },
710
724
  'ref-deprecated-orderby': 'Replace source element reference $(ID) by $(NEWCODE); auto-corrected',
725
+ 'ref-deprecated-in-extend': {
726
+ std: 'In an extension, do not use the table alias $(ID) to refer to source elements',
727
+ columns: 'In an added column, do not use the table alias $(ID) to refer to source elements',
728
+ where: 'In an added WHERE, do not use the table alias $(ID) to refer to source elements',
729
+ groupBy: 'In an added GROUP BY, do not use the table alias $(ID) to refer to source elements',
730
+ having: 'In an added HAVING, do not use the table alias $(ID) to refer to source elements',
731
+ orderBy: 'In an added ORDER BY, do not use the table alias $(ID) to refer to source elements',
732
+ },
711
733
  'ref-missing-self-counterpart' : {
712
734
  std: 'Expected to find a matching element in $self-comparison for foreign key $(PROP) of association $(NAME)',
713
735
  unmanaged: 'Expected to find a matching element in $self-comparison for $(PROP) of association $(NAME)',
@@ -728,6 +750,7 @@ const centralMessageTexts = {
728
750
  'ref-undefined-def': {
729
751
  std: 'Artifact $(ART) has not been found',
730
752
  // TODO: proposal 'No definition of $(NAME) found',
753
+ hint: 'Artifact $(ART) has not been found. Did you mean to write $(CODE)?',
731
754
  element: 'Artifact $(ART) has no element $(MEMBER)',
732
755
  },
733
756
  'ref-undefined-param': 'Entity $(ART) has no parameter $(ID)',
@@ -866,6 +889,7 @@ const centralMessageTexts = {
866
889
  std: 'Unexpected arguments in path $(ELEMREF)', // unused
867
890
  'on-condition': 'ON-conditions must not contain parameters, step $(ID) of path $(ELEMREF)',
868
891
  calc: 'Unexpected arguments in path $(ELEMREF) of stored calculated element; only simple paths can be used here',
892
+ vector_length: 'Unexpected length of vector $(ELEMREF). The length must be divisble by 4',
869
893
  },
870
894
  'ref-unsupported-type': {
871
895
  std: 'Type $(TYPE) is not supported',
@@ -955,6 +979,7 @@ const centralMessageTexts = {
955
979
  missing: 'Expecting service entity $(TARGET); it does not have the key element $(ID) of the provided model target',
956
980
  order: 'Expecting service entity $(TARGET); its key elements are in a different order than those of the provided model target',
957
981
  },
982
+ 'type-invalid-for-key': 'Type $(TYPE) is not supported for key elements',
958
983
 
959
984
  'anno-builtin': 'Builtin types should not be annotated nor extended. Use custom type instead',
960
985
  'ext-undefined-def': 'Artifact $(ART) has not been found',
@@ -1025,7 +1050,6 @@ const centralMessageTexts = {
1025
1050
  std: '$(KEYWORD) is not supported here', // unused variant
1026
1051
  kind: '$(KEYWORD) is only supported for elements in an entity or an aspect',
1027
1052
  sub: '$(KEYWORD) is only supported for top-level elements',
1028
- type: '$(KEYWORD) is not supported for elements of type $(TYPE)',
1029
1053
  },
1030
1054
  'def-unexpected-localized': {
1031
1055
  std: 'Unexpected $(KEYWORD)',
@@ -1076,6 +1100,12 @@ const centralMessageTexts = {
1076
1100
 
1077
1101
  'def-expected-structured': 'Events must either be structured or be projections',
1078
1102
 
1103
+ 'ext-duplicate-include': {
1104
+ std: 'Duplicate $(NAME) through multiple includes $(SORTED_ARTS)',
1105
+ elements: 'Duplicate element $(NAME) through multiple includes $(SORTED_ARTS)',
1106
+ actions: 'Duplicate action or function $(NAME) through multiple includes $(SORTED_ARTS)',
1107
+ },
1108
+
1079
1109
  'duplicate-definition': {
1080
1110
  std: 'Duplicate definition of $(NAME)',
1081
1111
  absolute: 'Duplicate definition of artifact $(NAME)',
@@ -1153,6 +1183,32 @@ const centralMessageTexts = {
1153
1183
  join: 'Artifact $(ART) can\'t be extended with columns, because it contains a JOIN',
1154
1184
  union: 'Artifact $(ART) can\'t be extended with columns, because it contains a UNION',
1155
1185
  },
1186
+ 'extend-where': {
1187
+ std: 'Artifact $(ART) can\'t be extended with WHERE, only simple views/projections without JOINs and UNIONs can',
1188
+ join: 'Artifact $(ART) can\'t be extended with WHERE, because it contains a JOIN',
1189
+ union: 'Artifact $(ART) can\'t be extended with WHERE, because it contains a UNION',
1190
+ },
1191
+ 'extend-groupby': {
1192
+ std: 'Artifact $(ART) can\'t be extended with GROUP BY, only simple views/projections without JOINs and UNIONs can',
1193
+ join: 'Artifact $(ART) can\'t be extended with GROUP BY, because it contains a JOIN',
1194
+ union: 'Artifact $(ART) can\'t be extended with GROUP BY, because it contains a UNION',
1195
+ },
1196
+ 'extend-having': {
1197
+ std: 'Artifact $(ART) can\'t be extended with HAVING, only simple views/projections without JOINs and UNIONs can',
1198
+ join: 'Artifact $(ART) can\'t be extended with HAVING, because it contains a JOIN',
1199
+ union: 'Artifact $(ART) can\'t be extended with HAVING, because it contains a UNION',
1200
+ },
1201
+ 'extend-orderby': {
1202
+ std: 'Artifact $(ART) can\'t be extended with ORDER BY, only simple views/projections without JOINs and UNIONs can',
1203
+ join: 'Artifact $(ART) can\'t be extended with ORDER BY, because it contains a JOIN',
1204
+ union: 'Artifact $(ART) can\'t be extended with ORDER BY, because it contains a UNION',
1205
+ },
1206
+ 'extend-limit': {
1207
+ std: 'Artifact $(ART) can\'t be extended with LIMIT, only simple views/projections without JOINs and UNIONs can',
1208
+ join: 'Artifact $(ART) can\'t be extended with LIMIT, because it contains a JOIN',
1209
+ union: 'Artifact $(ART) can\'t be extended with LIMIT, because it contains a UNION',
1210
+ },
1211
+ 'ext-unexpected-sql-clause': 'Artifact $(ART) can\'t be extended with a $(KEYWORD) clause, because it already exists',
1156
1212
  'extend-repeated-intralayer': 'Unstable element order due to repeated extensions in same layer',
1157
1213
  'extend-unexpected-include': 'Can\'t extend $(META) with includes',
1158
1214
 
@@ -1199,6 +1255,7 @@ const centralMessageTexts = {
1199
1255
  std: 'Expected identifier for select item',
1200
1256
  assoc: 'Expected identifier as the association\'s name',
1201
1257
  },
1258
+ 'query-invalid-identifier': 'Expected identifier for SQL dialect $(NAME) to not exceed $(NUMBER) characters',
1202
1259
  'query-unsupported-calc': {
1203
1260
  std: 'Using nested projections next to calculated elements is not supported, yet',
1204
1261
  inside: 'Using calculated elements in nested projections is not supported, yet',
@@ -1252,11 +1309,17 @@ const centralMessageTexts = {
1252
1309
  },
1253
1310
 
1254
1311
  'ref-special-in-extend': {
1255
- std: 'In an added column, $(ID) refers to the element of the projection source $(ART), not the table alias or mixin',
1312
+ std: 'In an extension, $(ID) refers to the element of the projection source $(ART), not the table alias or mixin',
1256
1313
  alias: 'In an added column, $(ID) refers to the element of the projection source $(ART), not the table alias',
1257
1314
  mixin: 'In an added column, $(ID) refers to the element of the projection source $(ART), not the mixin',
1258
1315
  },
1259
1316
 
1317
+ 'ref-unexpected-in-extend': {
1318
+ std: 'Unexpected $(ID) in an extension; it matches both a source element of $(ART) and the table alias or mixin',
1319
+ alias: 'Unexpected $(ID) in an added $(KEYWORD); it matches both a source element of $(ART) and the table alias',
1320
+ mixin: 'Unexpected $(ID) in an added $(KEYWORD); it matches both a source element of $(ART) and the mixin',
1321
+ },
1322
+
1260
1323
  'type-managed-composition': {
1261
1324
  std: 'Managed compositions can\'t be used in types', // yet
1262
1325
  sub: 'Managed compositions can\'t be used in sub elements',
@@ -1396,6 +1459,7 @@ const centralMessageTexts = {
1396
1459
  xpr: 'Ignoring unexpected expression as default value',
1397
1460
  colitem: 'Ignoring unexpected default value for a structured or collection like parameter',
1398
1461
  },
1462
+ 'odata-unexpected-xpr-anno': 'Annotation $(ANNO) with expression value is not allowed for kind $(KIND)',
1399
1463
  // -----------------------------------------------------------------------------------
1400
1464
  // All odata-anno MUST have a '$(ANNO)' parameter to indicate error location
1401
1465
  // -----------------------------------------------------------------------------------
@@ -6,7 +6,7 @@
6
6
 
7
7
  const { term } = require('../utils/term');
8
8
  const { Location, locationString } = require('./location');
9
- const { isBetaEnabled } = require('./model');
9
+ const { isBetaEnabled } = require('./specialOptions');
10
10
  const {
11
11
  centralMessages,
12
12
  configurableForValidValues,
@@ -14,7 +14,7 @@ const {
14
14
  oldMessageIds,
15
15
  } = require('./message-registry');
16
16
  const _messageIdsWithExplanation = require('../../share/messages/message-explanations.json').messages;
17
- const { analyseCsnPath, traverseQuery } = require('../model/csnRefs');
17
+ const { analyseCsnPath, traverseQuery } = require('../base/csnRefs');
18
18
  const { CompilerAssertion } = require('./error');
19
19
  const { getArtifactName } = require('../compiler/base');
20
20
  const { cdlNewLineRegEx } = require('../language/textUtils');
@@ -854,6 +854,8 @@ function value( val ) {
854
854
  const keywordRepresentations = {
855
855
  association: 'Association',
856
856
  composition: 'Composition',
857
+ groupby: 'group by',
858
+ orderby: 'order by',
857
859
  };
858
860
  function keyword( val ) {
859
861
  const v = val.toLowerCase();
@@ -8,12 +8,12 @@
8
8
  // - Also list the option in the `help` text, used with `cdsc -h`.
9
9
  // - All options must also be added to ./api/options.js.
10
10
  // - Specify valid values for non-boolean options in ./api/validate.js.
11
- // - Beta and deprecated options are specified in ./base/model.js.
11
+ // - Beta and deprecated options are specified in ./base/specialOptions.js.
12
12
 
13
13
  'use strict';
14
14
 
15
- const { createOptionProcessor } = require('./base/optionProcessorHelper');
16
- const { availableBetaFlags } = require('./base/model');
15
+ const { createOptionProcessor } = require('../utils/optionProcessorHelper');
16
+ const { availableBetaFlags } = require('./specialOptions');
17
17
 
18
18
  // This option processor is used both by the command line parser (to translate cmd line options
19
19
  // into an options object) and by the API functions (to verify options)
@@ -53,6 +53,7 @@ optionProcessor
53
53
  .option(' --test-sort-csn')
54
54
  .option(' --doc-comment')
55
55
  .option(' --propagate-doc-comments')
56
+ .option(' --v7-key-propagation')
56
57
  .option(' --add-texts-language-assoc')
57
58
  .option(' --localized-without-coalesce')
58
59
  .option(' --tenant-discriminator')
@@ -156,6 +157,7 @@ optionProcessor
156
157
  option is implicitly enabled as well.
157
158
  --doc-comment Preserve /** */ comments at annotation positions as doc property in CSN
158
159
  --propagate-doc-comments Propagate doc comments ('--doc-comment')
160
+ --v7-key-propagation Use simplified propagation of 'key' in query entities
159
161
  --add-texts-language-assoc In generated texts entities, add association "language"
160
162
  to "sap.common.Languages" if it exists
161
163
  --localized-without-coalesce Omit coalesce in localized convenience views