@sap/cds-compiler 3.9.4 → 4.0.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 (95) hide show
  1. package/CHANGELOG.md +107 -4
  2. package/README.md +0 -1
  3. package/bin/cdsc.js +11 -23
  4. package/bin/cdsse.js +3 -3
  5. package/doc/API.md +5 -0
  6. package/doc/CHANGELOG_ARCHIVE.md +1 -1
  7. package/doc/CHANGELOG_BETA.md +17 -1
  8. package/doc/CHANGELOG_DEPRECATED.md +28 -0
  9. package/lib/api/.eslintrc.json +1 -1
  10. package/lib/api/main.js +55 -9
  11. package/lib/api/options.js +2 -0
  12. package/lib/base/error.js +2 -0
  13. package/lib/base/message-registry.js +143 -64
  14. package/lib/base/messages.js +213 -107
  15. package/lib/base/model.js +11 -11
  16. package/lib/checks/.eslintrc.json +1 -1
  17. package/lib/checks/annotationsOData.js +2 -2
  18. package/lib/checks/elements.js +1 -1
  19. package/lib/checks/enricher.js +26 -3
  20. package/lib/checks/onConditions.js +67 -12
  21. package/lib/checks/queryNoDbArtifacts.js +106 -105
  22. package/lib/checks/sql-snippets.js +2 -0
  23. package/lib/checks/types.js +12 -6
  24. package/lib/checks/validator.js +2 -2
  25. package/lib/compiler/assert-consistency.js +10 -8
  26. package/lib/compiler/builtins.js +8 -2
  27. package/lib/compiler/checks.js +52 -35
  28. package/lib/compiler/define.js +31 -26
  29. package/lib/compiler/extend.js +120 -65
  30. package/lib/compiler/finalize-parse-cdl.js +12 -43
  31. package/lib/compiler/generate.js +16 -5
  32. package/lib/compiler/index.js +8 -5
  33. package/lib/compiler/kick-start.js +4 -3
  34. package/lib/compiler/populate.js +96 -95
  35. package/lib/compiler/propagator.js +7 -8
  36. package/lib/compiler/resolve.js +377 -103
  37. package/lib/compiler/shared.js +794 -517
  38. package/lib/compiler/tweak-assocs.js +8 -6
  39. package/lib/compiler/utils.js +44 -0
  40. package/lib/edm/annotations/genericTranslation.js +41 -5
  41. package/lib/edm/csn2edm.js +34 -32
  42. package/lib/edm/edm.js +34 -31
  43. package/lib/edm/edmAnnoPreprocessor.js +0 -23
  44. package/lib/edm/edmInboundChecks.js +7 -2
  45. package/lib/edm/edmPreprocessor.js +25 -18
  46. package/lib/edm/edmUtils.js +8 -4
  47. package/lib/gen/Dictionary.json +18 -0
  48. package/lib/gen/language.checksum +1 -1
  49. package/lib/gen/language.interp +4 -2
  50. package/lib/gen/languageParser.js +5006 -4582
  51. package/lib/json/from-csn.js +157 -112
  52. package/lib/json/to-csn.js +60 -89
  53. package/lib/language/antlrParser.js +17 -13
  54. package/lib/language/docCommentParser.js +11 -1
  55. package/lib/language/genericAntlrParser.js +13 -10
  56. package/lib/language/language.g4 +168 -97
  57. package/lib/main.d.ts +128 -36
  58. package/lib/main.js +1 -1
  59. package/lib/model/csnRefs.js +24 -5
  60. package/lib/model/csnUtils.js +9 -8
  61. package/lib/model/revealInternalProperties.js +7 -12
  62. package/lib/model/sortViews.js +4 -2
  63. package/lib/modelCompare/compare.js +1 -1
  64. package/lib/modelCompare/utils/filter.js +40 -2
  65. package/lib/optionProcessor.js +0 -3
  66. package/lib/render/toCdl.js +247 -214
  67. package/lib/render/toHdbcds.js +197 -181
  68. package/lib/render/toSql.js +325 -289
  69. package/lib/render/utils/common.js +42 -4
  70. package/lib/render/utils/delta.js +1 -1
  71. package/lib/render/utils/sql.js +3 -3
  72. package/lib/transform/braceExpression.js +2 -2
  73. package/lib/transform/db/.eslintrc.json +1 -1
  74. package/lib/transform/db/applyTransformations.js +3 -3
  75. package/lib/transform/db/associations.js +24 -12
  76. package/lib/transform/db/expansion.js +17 -18
  77. package/lib/transform/db/flattening.js +17 -21
  78. package/lib/transform/db/rewriteCalculatedElements.js +171 -64
  79. package/lib/transform/db/views.js +3 -4
  80. package/lib/transform/draft/db.js +21 -12
  81. package/lib/transform/draft/odata.js +4 -0
  82. package/lib/transform/forOdataNew.js +62 -47
  83. package/lib/transform/forRelationalDB.js +12 -7
  84. package/lib/transform/localized.js +4 -2
  85. package/lib/transform/odata/toFinalBaseType.js +5 -5
  86. package/lib/transform/odata/typesExposure.js +3 -3
  87. package/lib/transform/parseExpr.js +3 -0
  88. package/lib/transform/transformUtilsNew.js +43 -23
  89. package/lib/transform/translateAssocsToJoins.js +7 -6
  90. package/lib/transform/universalCsn/.eslintrc.json +1 -1
  91. package/lib/transform/universalCsn/coreComputed.js +7 -5
  92. package/lib/transform/universalCsn/universalCsnEnricher.js +12 -12
  93. package/package.json +2 -2
  94. package/share/messages/{duplicate-autoexposed.md → def-duplicate-autoexposed.md} +5 -1
  95. package/share/messages/message-explanations.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,15 +7,118 @@
7
7
  Note: `beta` fixes, changes and features are usually not listed in this ChangeLog but [here](doc/CHANGELOG_BETA.md).
8
8
  The compiler behavior concerning `beta` features can change at any time without notice.
9
9
 
10
- ## Version 3.9.4 - 2023-06-07
10
+
11
+ ## Version 4.0.2 - 2023-06-22
11
12
 
12
13
  ### Fixed
13
14
 
14
- - compiler: `USING` empty files were incorrectly marked as "not found".
15
+ - to.sql.migration: When drop-creating views, also drop-create (transitively) dependent views.
16
+ - to.edm(x):
17
+ + Forward `@odata.singleton { nullable }` annotation to parameter entity.
18
+ + Annotations assigned to a parameterized entity are propagated to the parameter entity if the annotation is
19
+ applicable to either an `edm.EntitySet` or `edm.Singleton`. This especially covers all `@Capabilities` and their
20
+ shortcut forms like `@readonly` and `@insertonly`. The original annotation is not removed from the original entity.
21
+ Annotations that should be rendered at the parameter `edm.EntityType` can be qualified with `$parameters`.
22
+ Explicitly qualified annotations are removed from the original entity allowing individual assignments.
23
+
24
+
25
+ ## Version 4.0.0 - 2023-06-06
26
+
27
+ ### Added
28
+
29
+ - Calculated elements "on-write" are now supported, e.g. `elem = field + 1 stored;` will be rendered in SQL
30
+ as `GENERATED ALWAYS AS`.
31
+ - compiler:
32
+ + `returns` of actions and functions can now be annotated, e.g.
33
+
34
+ ```cds
35
+ action A() returns @direct { … };
36
+ annotate A with returns {
37
+ @anno val;
38
+ }
39
+ ```
40
+ + It is now possible to use `*/` inside doc comments by escaping it `*\/`. Only this exact string can be escaped.
41
+ + Functions `parse.expr` and `parse.cql` now support `group by`, `having`, `order by`, `limit`, and `offset` in infix filters.
42
+ + In expressions, you can now use function names after the `new` keyword which do
43
+ not start with `st_`, if the name is followed by an open parenthesis.
44
+
45
+ ### Changed
46
+
47
+ - API:
48
+ + `messageContext()` is now deprecated; use `messageStringMultiline()` instead with `config.sourceMap`.
49
+ + `messageString(err, config)` has a new signature; the old one is still supported for backward compatibility.
50
+ + Option `docComment: false` now removes doc comments during compilation even for CSN.
51
+ If this option is not defined, doc comments are checked, but not put into CSN.
52
+ - compiler:
53
+ + CSN: Specified elements of queries are now resolved and checked (previously ignored except for annotations).
54
+ Type properties (`length`, …) and some element properties are now taken from the specified elements
55
+ instead of relying only on the elements inferred by the compiler.
56
+ + CSN: Compiler accepts CSN input with CSN version `0.1.0` (produced by cds-compiler version 1.10.0 and older)
57
+ only if the version attribute is properly set, i.e. `"version": {"csn": "0.1.0"}`.
58
+ + CSN: Type properties (`length`, `precision`, `scale`, and `srid`) next to `elements` or `items` in CSN input
59
+ is now an error. Previously ignored.
60
+ + An extension of the form `extend Def with { name = 42 };` is now represented in parsed CSN as
61
+ adding a calculated element.
62
+ + `having` as the first word in an infix filter is now interpreted as keyword. Write `![having]`
63
+ to have it parsed as identifier.
64
+ + If a definition overrides elements of an included definition, it is sorted according
65
+ to the included definition's element order. This is similar to how `*` works in projections.
66
+ It is no longer possible to overwrite a scalar element with a structure and vice versa.
67
+ + Two included definitions cannot have the same element. The including entity must override the element.
68
+ + If a type with properties precision and scale is extended, the `extend` statement must extend both properties.
69
+ + `annotate E:elem with actions {};` is now a parser error and no longer a compiler error.
70
+ Only relevant if you use `parseCdl`-style CSN.
71
+ + Annotations (and other properties) are now propagated to `returns` as well, if the returned artifact
72
+ is a non-entity, e.g. a type.
73
+ + `annotate E with returns {…}` is now only applied to actions/functions. Previous compiler versions
74
+ autocorrected the `annotate` statements to apply them to an entity's elements.
75
+ + Calculated elements can't refer to localized elements.
76
+ + Table aliases can't be used in `extend Query with columns {…}` any longer. Use direct element references instead.
77
+ + Table alias and mixin names can no longer start with `$`. Choose a different name. With this change
78
+ we avoid unexpected name resolution effects in combination with built-in `$`-variables.
79
+ + A semicolon is now required after a type definition like `type T : many {} null`.
80
+ + It is no longer possible to write `type of $self.‹elem›` to refer to the element `‹Def›.‹elem›`
81
+ where `‹Def›` is the main artifact where the type expression is embedded in. Replace by `type of <Def>:‹elem›`.
82
+ + Message ID `duplicate-autoexposed` was changed to `def-duplicate-autoexposed`.
83
+ - Update OData vocabularies 'Common', 'UI'.
84
+ - to.sql:
85
+ + Change default `length` for `cds.String` for all SQL dialects except `hana` to 255.
86
+ + for the sql dialect `postgres`, the `ON DELETE RESTRICT` / `ON UPDATE RESTRICT` rules
87
+ are omitted from the referential constraint definitions.
88
+ - to.cdl:
89
+ + If associations are used inside `items`, an error is emitted instead of rendering invalid CDL.
90
+ + `items` inside `items`, where the outer one does not have a `type`, is now always an error,
91
+ because it can't be rendered in CDL
92
+
93
+ ### Fixed
94
+
95
+ - compiler:
96
+ + `parseCdl` CSN did not include correct `...` entries for annotations containing `... up to`
97
+ + Type references inside calculated elements were not always correctly resolved.
98
+ + `USING` empty files were incorrectly marked as "not found".
99
+ + If an association was inside `items`, e.g. via type chains, the compiler crashes instead of emitting proper errors.
15
100
  - Localized convenience views for projections (not views) did not have references rewritten.
16
101
  This only affects CSN, the SQL result was correct.
17
- - to.edm(x): Render correct EntitySetPath and annotation target path for actions/functions
18
- with explicit binding parameter.
102
+ - Calculated elements in composition-of-aspect lost their `value` when generating composition targets.
103
+ - to.sql/to.hdi/for.odata: Foreign keys in ON-conditions were not always properly checked and flattened if explicit
104
+ `keys` were provided that reference structures.
105
+ - Extending bound actions with elements is not possible, but was not reported by the compiler and elements were silently lost.
106
+ - for.odata:
107
+ + Don't propagate `@odata { Type, MaxLength, Precision, Scale }` from structured to flattened leaf elements.
108
+ + Remove `type: null` attribute from element definitions referencing an undefined type via `type of`.
109
+ - to.edm(x):
110
+ + Don't reject untyped properties that are API typed with a valid `@odata.Type` annotation.
111
+ + Render correct `EntitySetPath` and annotation target path for actions/functions with explicit binding parameter.
112
+ - to.cdl: ParseCdl-style CSN containing annotations with `...` were not properly rendered.
113
+
114
+ ### Removed
115
+
116
+ - NodeJs 14 is no longer supported.
117
+ - `CompileMessage` no longer has property `location`, which was deprecated in v2.1.0, but `$location`,
118
+ which is supported since v2.1.0
119
+ - "Smart type references" such as `Entity.myElement` instead of `Entity:myElement` are removed, because since
120
+ compiler v2, `Entity.myElement` could also be a definition, creating ambiguities.
121
+ - Element type references can no longer follow associations, i.e. `E:assoc.id` is not allowed.
19
122
 
20
123
  ## Version 3.9.2 - 2023-04-27
21
124
 
package/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # Getting started
2
2
 
3
-
4
3
  <!-- markdownlint-disable MD001 MD022 -->
5
4
  ##### Table of Contents
6
5
  <!-- markdownlint-enable MD001 MD022 -->
package/bin/cdsc.js CHANGED
@@ -30,7 +30,6 @@ const {
30
30
  explainMessage, hasMessageExplanation, sortMessages, messageIdsWithExplanation,
31
31
  } = require('../lib/base/messages');
32
32
  const { term } = require('../lib/utils/term');
33
- const { splitLines } = require('../lib/utils/file');
34
33
  const { addLocalizationViews } = require('../lib/transform/localized');
35
34
  const { availableBetaFlags } = require('../lib/base/model');
36
35
  const { alterConstraintsWithCsn } = require('../lib/render/manageConstraints');
@@ -505,35 +504,24 @@ function executeCommandLine( command, options, args ) {
505
504
  .forEach(msg => log(msg));
506
505
  }
507
506
  else if (options.noMessageContext) {
508
- // TODO: currently, ‹↓› = "downgradable" is only shown here
509
507
  messages.filter(msg => (messageLevels[msg.severity] <= options.warning))
510
508
  .forEach(msg => log(main.messageString(msg, normalizeFilename, !!options.noMessageId, false, options.testMode && 'compile'))); // TODO: use module name
511
509
  }
512
510
  else {
513
- // Contains file-contents that are split at '\n'. Try to avoid multiple `.split()` calls.
514
- const splitCache = Object.create(null);
515
- const sourceLines = (name) => {
516
- if (!splitCache[name])
517
- splitCache[name] = fileCache[name] ? splitLines(fileCache[name]) : fileCache;
518
- return splitCache[name];
519
- };
520
511
  let hasAtLeastOneExplanation = false;
512
+ const config = {
513
+ normalizeFilename,
514
+ noMessageId: !!options.noMessageId,
515
+ hintExplanation: true,
516
+ color: options.color,
517
+ module: options.testMode && 'compile', // TODO: use module name
518
+ sourceMap: fileCache,
519
+ cwd: '',
520
+ };
521
+
521
522
  messages.filter(msg => messageLevels[msg.severity] <= options.warning).forEach((msg) => {
522
523
  hasAtLeastOneExplanation = hasAtLeastOneExplanation || main.hasMessageExplanation(msg.messageId);
523
- const name = msg.$location && msg.$location.file;
524
- const fullFilePath = name ? path.resolve('', name) : undefined;
525
- log(main.messageStringMultiline(msg, {
526
- normalizeFilename,
527
- noMessageId: !!options.noMessageId,
528
- withLineSpacer: true,
529
- hintExplanation: true,
530
- color: options.color,
531
- }));
532
- if (fullFilePath && msg.$location.line) {
533
- // A message context only makes sense, if we have at least start line
534
- const context = sourceLines(fullFilePath);
535
- log(main.messageContext(context, msg, { color: options.color }));
536
- }
524
+ log(main.messageStringMultiline(msg, config));
537
525
  log(); // newline
538
526
  });
539
527
  if (!options.noMessageId && hasAtLeastOneExplanation)
package/bin/cdsse.js CHANGED
@@ -4,11 +4,11 @@
4
4
  // intend to support all capabilities of a LSP server, nor do we adhere to the
5
5
  // LSP protocol. This is just a little playground to optimize the CDS Compiler
6
6
  // support for the CDS LSP server and to detect potential issues with
7
- // corrupted, incomplete or errorneous CDL sources.
7
+ // corrupted, incomplete or erroneous CDL sources.
8
8
  //
9
9
  // The output could be used directly by some editors, e.g. Emacs. The
10
10
  // capabilities supported at the moments is: complete - work in progress.
11
- // Planned are: gotoDefinition, highlight (for syntax highighting).
11
+ // Planned are: gotoDefinition, highlight (for syntax highlighting).
12
12
 
13
13
  /* eslint no-console:off */
14
14
  // @ts-nocheck
@@ -168,7 +168,7 @@ function tokensAt( buf, _offset, col, symbol ) {
168
168
 
169
169
  function messageAt( model, prop, col ) {
170
170
  const msg = (model.messages || model.options && model.options.messages).find(
171
- m => m[prop] && m.location.line === line && m.location.col === col && m.location.file === frel
171
+ m => m[prop] && m.$location.line === line && m.$location.col === col && m.$location.file === frel
172
172
  );
173
173
  return msg && msg[prop];
174
174
  }
package/doc/API.md CHANGED
@@ -7,5 +7,10 @@ Refer to that file for documentation on option names, API calls, and more.
7
7
 
8
8
  You can use [TypeDoc] to render an HTML documentation from it.
9
9
 
10
+ ## Important Notes
11
+
12
+ The cds-compiler expects that `Object.prototype` is not polluted by enumerable
13
+ properties. Non-enumerable properties such as custom functions are fine.
14
+
10
15
 
11
16
  [TypeDoc]: https://typedoc.org/
@@ -206,7 +206,7 @@ The compiler behaviour concerning `beta` features can change at any time without
206
206
  ### Fixed
207
207
 
208
208
  - Fix memory issue: do not keep reference to last-compiled model.
209
- - Fix dump which occured when trying to report that the user has defined an element to be both `key` and `localized` if
209
+ - Fix dump which occurred when trying to report that the user has defined an element to be both `key` and `localized` if
210
210
  `localized` was inherited via the provided type, or in the generated entity for a managed composition of aspect.
211
211
  - Properly auto-expose targets of associations in parameters and `many`.
212
212
  - for.Odata:
@@ -8,13 +8,29 @@ Note: `beta` fixes, changes and features are listed in this ChangeLog just for i
8
8
  The compiler behavior concerning `beta` features can change at any time without notice.
9
9
  **Don't use `beta` fixes, changes and features in productive mode.**
10
10
 
11
+ ## Version 4.0.0 - 2023-06-06
12
+
13
+ ### Removed `v4preview`
14
+
15
+ `v4preview` is now the default.
16
+
17
+ ### Removed `calculatedElementsOnWrite`
18
+
19
+ It is now enabled by default. The feature is still "beta".
20
+
21
+ ### Removed `ignoreAssocPublishingInUnion`
22
+
23
+ The behavior is now the default. If you still want to get an error message for
24
+ ignored published associations in unions, you can change the severity of message
25
+ `query-ignoring-assoc-in-union` to an error via `options.severities`.
26
+
11
27
  ## Version 3.9.2 - 2023-04-27
12
28
 
13
29
  ### Removed `odataOpenType`
14
30
 
15
31
  This feature is now set to production mode.
16
32
 
17
- ## Version 3.9.0 - 2023-04-XX
33
+ ## Version 3.9.0 - 2023-04-20
18
34
 
19
35
  ### Added `calculatedElementsOnWrite`
20
36
 
@@ -11,6 +11,34 @@ Note: `deprecated` features are listed in this ChangeLog just for information.
11
11
  **When the `deprecated` option is set, the `beta` option is ignored,
12
12
  and several new features are not available.**
13
13
 
14
+ ## Version 4.0.0 - 2023-06-06
15
+
16
+ ### Added `downgradableErrors`
17
+
18
+ Allow to change the severity of some errors which are meant to stay errors in v4.
19
+
20
+ ### Added `includesNonShadowedFirst`
21
+
22
+ Use this flag to keep adding elements from included definitions first, example:
23
+
24
+ ```cds
25
+ entity A { one: Integer; two: String(10); three: Integer; }
26
+ entity E : A { two: String(12); }
27
+ // v3: one, three, two
28
+ // v4: one, two, three
29
+ ```
30
+
31
+ ### Added `ignoreSpecifiedQueryElements`
32
+
33
+ Use this flag if you want to ignore a query's `elements`, except for annotations and doc comments.
34
+ cds-compiler v3 and earlier simply ignored a query element except for its annotations.
35
+ cds-compiler v4 resolves the element's type.
36
+
37
+ ### Removed `autoCorrectOrderBySourceRefs`
38
+
39
+ Instead of this deprecated flag, you can downgrade error message `ref-deprecated-orderby`.
40
+
41
+
14
42
  ## Version 3.1.0 - 2022-08-04
15
43
 
16
44
  ### Added `autoCorrectOrderBySourceRefs`
@@ -5,7 +5,7 @@
5
5
  "node": true
6
6
  },
7
7
  // we actually do not extend airbnb-base, as it weakens some eslint:recommended rules
8
- "extends": ["../../.eslintrc-ydkjsi.json", "plugin:jsdoc/recommended"],
8
+ "extends": ["plugin:jsdoc/recommended", "../../.eslintrc-ydkjsi.json"],
9
9
  "parserOptions": {
10
10
  "ecmaVersion": 2022,
11
11
  "sourceType": "script"
package/lib/api/main.js CHANGED
@@ -164,20 +164,35 @@ function cdl( csn, options = {} ) {
164
164
  }
165
165
 
166
166
  /**
167
- * Transform a CSN like to.sql
167
+ * Transform a CSN like to.sql().
168
+ * Expects that internalOptions have been validated via prepareOptions.to.sql().
168
169
  *
169
170
  * @param {CSN.Model} csn Plain input CSN
170
- * @param {SqlOptions} [options={}] Options
171
+ * @param {SqlOptions} internalOptions Options
171
172
  * @returns {CSN.Model} CSN transformed like to.sql
172
173
  * @private
173
174
  */
174
- function forSql( csn, options = {} ) {
175
- const internalOptions = prepareOptions.to.sql(options);
175
+ function csnForSql( csn, internalOptions ) {
176
176
  internalOptions.transformation = 'sql';
177
177
  const transformedCsn = forRelationalDB.transformForRelationalDBWithCsn(csn, internalOptions, 'to.sql');
178
178
 
179
179
  return internalOptions.testMode ? toCsn.sortCsn(transformedCsn, internalOptions) : transformedCsn;
180
180
  }
181
+
182
+ /**
183
+ * Transform a CSN like to.sql(). Also performs options-checks.
184
+ * Pseudo-public version of csnForSql().
185
+ *
186
+ * @param {CSN.Model} csn Plain input CSN
187
+ * @param {SqlOptions} [options={}] Options
188
+ * @returns {CSN.Model} CSN transformed like to.sql
189
+ * @private
190
+ */
191
+ function forSql( csn, options = {} ) {
192
+ const internalOptions = prepareOptions.to.sql(options);
193
+ return csnForSql(csn, internalOptions);
194
+ }
195
+
181
196
  /**
182
197
  * Transform a CSN like to.hdi
183
198
  *
@@ -223,7 +238,7 @@ function sql( csn, options = {} ) {
223
238
  internalOptions.transformation = 'sql';
224
239
 
225
240
  // we need the CSN for view sorting
226
- const transformedCsn = forSql(csn, options);
241
+ const transformedCsn = csnForSql(csn, internalOptions);
227
242
  const sqls = toSql.toSqlDdl(transformedCsn, internalOptions);
228
243
 
229
244
  const result = sortViews({ csn: transformedCsn, sql: sqls.sql });
@@ -347,7 +362,8 @@ function sqlMigration( csn, options, beforeImage ) {
347
362
  const { error, throwWithError } = messages.makeMessageFunction(csn, internalOptions, 'to.sql.migration');
348
363
 
349
364
  // Prepare after-image.
350
- const afterImage = forSql(csn, internalOptions);
365
+ const afterImage = internalOptions.filterCsn
366
+ ? diffFilter.csn(csnForSql(csn, internalOptions)) : csnForSql(csn, internalOptions);
351
367
  // Compare both images.
352
368
  const diff = modelCompare.compareModels(beforeImage || afterImage, afterImage, internalOptions);
353
369
  const diffFilterObj = diffFilter[internalOptions.sqlDialect];
@@ -368,6 +384,7 @@ function sqlMigration( csn, options, beforeImage ) {
368
384
  }, {}),
369
385
  };
370
386
 
387
+ const markedSkipByUs = {};
371
388
  const cleanup = [];
372
389
  // Delete artifacts that are already present in csn
373
390
  if (beforeImage?.definitions) {
@@ -388,10 +405,38 @@ function sqlMigration( csn, options, beforeImage ) {
388
405
  ) { // don't render again, but need info for primary key extension
389
406
  diffArtifact['@cds.persistence.skip'] = true;
390
407
  cleanup.push(() => delete diffArtifact['@cds.persistence.skip']);
408
+ markedSkipByUs[artifactName] = true;
391
409
  }
392
410
  });
393
411
  }
394
412
 
413
+ const sortOrder = sortViews({ sql: {}, csn: afterImage });
414
+
415
+ const dependentsDict = {};
416
+ sortOrder.forEach(({ name, dependents }) => {
417
+ dependentsDict[name] = dependents;
418
+ });
419
+
420
+ const stack = Object.keys(drops.creates);
421
+ while (stack.length > 0) {
422
+ const name = stack.pop();
423
+ const artifact = diff.definitions[name];
424
+ if (drops.creates[name] === undefined) {
425
+ if (artifact['@cds.persistence.skip'] && markedSkipByUs[name]) {
426
+ // Remove the skip so we render a CREATE VIEW
427
+ diff.definitions[name]['@cds.persistence.skip'] = false;
428
+ drops.creates[name] = `DROP VIEW ${ identifierUtils.renderArtifactName(name) };`;
429
+ }
430
+ }
431
+
432
+ const dependents = dependentsDict[name];
433
+ if (dependents) { // schedule any dependents for processing that don't have a drop-create yet
434
+ for (const dependantName in dependents) {
435
+ if (!drops.creates[dependantName])
436
+ stack.push(dependantName);
437
+ }
438
+ }
439
+ }
395
440
  // Convert the diff to SQL.
396
441
  if (!internalOptions.beta)
397
442
  internalOptions.beta = {};
@@ -403,7 +448,6 @@ function sqlMigration( csn, options, beforeImage ) {
403
448
 
404
449
  cleanup.forEach(fn => fn());
405
450
  // TODO: Handle `ADD CONSTRAINT` etc!
406
- const sortOrder = sortViews({ sql: {}, csn: afterImage });
407
451
 
408
452
  const dropSqls = [];
409
453
  const createAndAlterSqls = [];
@@ -844,8 +888,10 @@ function publishCsnProcessor( processor, _name ) {
844
888
 
845
889
  const { info } = messages.makeMessageFunction( csn, options, 'compile' );
846
890
  const msg = info( 'api-recompiled-csn', location.emptyLocation('csn.json'), {}, 'CSN input had to be recompiled' );
847
- if (options.internalMsg)
848
- msg.error = err; // Attach original error
891
+ if (options.internalMsg || options.testMode)
892
+ msg.error = err; // Attach original error;
893
+ if (options.testMode) // Attach recompilation reason in testMode
894
+ msg.message += `\n ↳ cause: ${ err.message }`;
849
895
 
850
896
  // next line to be replaced by CSN parser call which reads the CSN object
851
897
  const xsn = compiler.recompileX(csn, options);
@@ -49,6 +49,8 @@ const publicOptionsNewAPI = [
49
49
 
50
50
  // Internal options used for testing/debugging etc.
51
51
  const privateOptions = [
52
+ // Not callable via cdsc, keep private for now until we are sure that we want this
53
+ 'filterCsn',
52
54
  'lintMode',
53
55
  'fuzzyCsnError',
54
56
  'traceFs',
package/lib/base/error.js CHANGED
@@ -7,6 +7,7 @@
7
7
  class CompilerAssertion extends Error {
8
8
  constructor(message) {
9
9
  super(`cds-compiler assertion failed: ${ message }`);
10
+ this.code = 'ERR_CDS_COMPILER_ASSERTION';
10
11
  }
11
12
  }
12
13
 
@@ -17,6 +18,7 @@ class CompilerAssertion extends Error {
17
18
  class ModelError extends Error {
18
19
  constructor(message) {
19
20
  super(`cds-compiler model error: ${ message }`);
21
+ this.code = 'ERR_CDS_COMPILER_MODEL';
20
22
  }
21
23
  }
22
24