@sap/cds-compiler 6.4.2 → 6.5.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 (71) hide show
  1. package/CHANGELOG.md +87 -1159
  2. package/README.md +1 -10
  3. package/doc/IncompatibleChanges_v5.md +436 -0
  4. package/doc/IncompatibleChanges_v6.md +659 -0
  5. package/doc/Versioning.md +3 -7
  6. package/lib/api/main.js +1 -0
  7. package/lib/api/options.js +5 -0
  8. package/lib/api/validate.js +3 -0
  9. package/lib/base/message-registry.js +25 -2
  10. package/lib/base/messages.js +1 -1
  11. package/lib/base/model.js +3 -2
  12. package/lib/checks/actionsFunctions.js +6 -3
  13. package/lib/checks/existsExpressionsOnlyForeignKeys.js +16 -10
  14. package/lib/checks/existsInForbiddenPlaces.js +32 -0
  15. package/lib/checks/existsMustEndInAssoc.js +1 -1
  16. package/lib/checks/existsMustNotStartWithDollarSelf.js +31 -0
  17. package/lib/checks/validator.js +6 -2
  18. package/lib/compiler/assert-consistency.js +5 -7
  19. package/lib/compiler/builtins.js +5 -6
  20. package/lib/compiler/checks.js +4 -8
  21. package/lib/compiler/define.js +244 -459
  22. package/lib/compiler/extend.js +297 -11
  23. package/lib/compiler/finalize-parse-cdl.js +2 -10
  24. package/lib/compiler/generate.js +29 -1
  25. package/lib/compiler/populate.js +21 -63
  26. package/lib/compiler/propagator.js +1 -2
  27. package/lib/compiler/resolve.js +2 -12
  28. package/lib/compiler/shared.js +145 -114
  29. package/lib/compiler/tweak-assocs.js +14 -10
  30. package/lib/compiler/utils.js +97 -0
  31. package/lib/compiler/xpr-rewrite.js +113 -140
  32. package/lib/edm/annotations/edmJson.js +9 -6
  33. package/lib/edm/annotations/genericTranslation.js +8 -4
  34. package/lib/edm/csn2edm.js +3 -4
  35. package/lib/edm/edmInboundChecks.js +1 -2
  36. package/lib/edm/edmPreprocessor.js +3 -3
  37. package/lib/gen/CdlGrammar.checksum +1 -1
  38. package/lib/gen/CdlParser.js +4 -3
  39. package/lib/gen/Dictionary.json +16 -1
  40. package/lib/json/from-csn.js +4 -6
  41. package/lib/json/to-csn.js +3 -3
  42. package/lib/model/csnRefs.js +13 -4
  43. package/lib/model/enrichCsn.js +4 -2
  44. package/lib/optionProcessor.js +8 -4
  45. package/lib/parsers/AstBuildingParser.js +1 -1
  46. package/lib/render/utils/sql.js +3 -2
  47. package/lib/transform/db/applyTransformations.js +1 -1
  48. package/lib/transform/db/assertUnique.js +3 -3
  49. package/lib/transform/db/assocsToQueries/normalizeFrom.js +33 -0
  50. package/lib/transform/db/assocsToQueries/transformExists.js +17 -13
  51. package/lib/transform/db/assocsToQueries/utils.js +1 -6
  52. package/lib/transform/db/backlinks.js +4 -4
  53. package/lib/transform/db/cdsPersistence.js +4 -4
  54. package/lib/transform/db/constraints.js +4 -4
  55. package/lib/transform/db/expansion.js +5 -5
  56. package/lib/transform/db/flattening.js +4 -5
  57. package/lib/transform/db/rewriteCalculatedElements.js +3 -3
  58. package/lib/transform/db/temporal.js +11 -11
  59. package/lib/transform/draft/db.js +2 -0
  60. package/lib/transform/draft/odata.js +5 -7
  61. package/lib/transform/effective/flattening.js +1 -2
  62. package/lib/transform/forOdata.js +3 -3
  63. package/lib/transform/forRelationalDB.js +1 -1
  64. package/lib/transform/localized.js +13 -20
  65. package/lib/transform/odata/createForeignKeys.js +1 -2
  66. package/lib/transform/odata/flattening.js +1 -2
  67. package/lib/transform/odata/toFinalBaseType.js +52 -55
  68. package/lib/transform/transformUtils.js +3 -4
  69. package/package.json +3 -3
  70. package/doc/CHANGELOG_BETA.md +0 -464
  71. package/doc/CHANGELOG_DEPRECATED.md +0 -235
package/README.md CHANGED
@@ -1,13 +1,5 @@
1
1
  # Getting started
2
2
 
3
- <!-- markdownlint-disable MD001 MD022 -->
4
- ##### Table of Contents
5
- <!-- markdownlint-enable MD001 MD022 -->
6
-
7
- [Installation and Usage](#installation-and-usage)
8
- [Documentation](#documentation)
9
- [How to Obtain Support](#how-to-obtain-support)
10
- [History and License](#history-and-license)
11
3
 
12
4
  ## Installation and Usage
13
5
 
@@ -42,8 +34,7 @@ In case you find a bug, please report an [incident](https://cap.cloud.sap/docs/r
42
34
 
43
35
  The cds-compiler uses [Semantic Versioning](./doc/Versioning.md) for its version numbers.
44
36
 
45
- Our [changelog](./CHANGELOG.md) lists recent changes.
46
- <!-- If you upgrade from a previous version, TODO: incompatible changes -->
37
+ Our [CHANGELOG.md](./CHANGELOG.md) lists recent changes.
47
38
 
48
39
  This package is provided under the terms of the [SAP Developer License Agreement, Version 3.2 CAP](LICENSE).
49
40
  <!-- https://cap.cloud.sap/resources/license/developer-license-3_2_CAP.txt -->
@@ -0,0 +1,436 @@
1
+ # Incompatible Changes in CDS Compiler Version 5
2
+
3
+ This document lists (potentially) incompatible changes
4
+ which came with Compiler Version 5.
5
+
6
+ <!-- toc: start -->
7
+
8
+ 1. [Preamble](#preamble)
9
+ 2. [General](#general)
10
+ 1. [Increase Required Node.js Version to 18](#increase-required-nodejs-version-to-18)
11
+ 2. [`CompilationError` no longer contains all messages as stringified text](#compilationerror-no-longer-contains-all-messages-as-stringified-text)
12
+ 3. [Deprecate HDBCDS backend](#deprecate-hdbcds-backend)
13
+ 4. [Remove deprecated API functions `preparedCsnToEdmx` and `preparedCsnToEdm`](#remove-deprecated-api-functions-preparedcsntoedmx-and-preparedcsntoedm)
14
+ 3. [Changes in CDL and CSN parser](#changes-in-cdl-and-csn-parser)
15
+ 1. [Syntax restriction for nested inlines](#syntax-restriction-for-nested-inlines)
16
+ 2. [Reject nonassignable annotations](#reject-nonassignable-annotations)
17
+ 3. [Reject annotations on Mixin definitions via CSN input](#reject-annotations-on-mixin-definitions-via-csn-input)
18
+ 4. [Reject missing space between number and keyword](#reject-missing-space-between-number-and-keyword)
19
+ 4. [Changes in Core Compiler](#changes-in-core-compiler)
20
+ 1. [Errors for unapplied extend statement](#errors-for-unapplied-extend-statement)
21
+ 2. [Upgrade some warnings to errors](#upgrade-some-warnings-to-errors)
22
+ 3. [Deprecate $at.from and $at.to](#deprecate-atfrom-and-atto)
23
+ 5. [Changes in OData/EDM](#changes-in-odataedm)
24
+ 1. [No Annotation propagation from element to artificial named type during type exposure](#no-annotation-propagation-from-element-to-artificial-named-type-during-type-exposure)
25
+ 2. [Raise Spec violation warnings to error](#raise-spec-violation-warnings-to-error)
26
+ 3. [Restore propagation in vocabularies](#restore-propagation-in-vocabularies)
27
+ 6. [Changes in to.sql()](#changes-in-tosql)
28
+ 1. [Localized entities and `@cds.persistence.exists`](#localized-entities-and-cdspersistenceexists)
29
+ 2. [Changes for dialect sqlite](#changes-for-dialect-sqlite)
30
+ 3. [Fewer localized views](#fewer-localized-views)
31
+
32
+ <!-- toc: end -->
33
+
34
+ ## Preamble
35
+
36
+ Major versions are used to clean up things that could potentially break existing user code.
37
+ Such changes always have a reason, and we don't introduce them "just for the sake of it".
38
+
39
+
40
+ ## General
41
+
42
+ ### Increase Required Node.js Version to 18
43
+
44
+ Node.js 16 is EOL, hence we will require Node 18 starting with cds-compiler v5.
45
+
46
+
47
+ ### `CompilationError` no longer contains all messages as stringified text
48
+
49
+ It's duplicate: We were storing both the messages as an array in `err.messages` as
50
+ well as their stringified version in the error's message.
51
+
52
+ Because test frameworks such as mocha and jest to not call `toString()` on
53
+ an unhandled `CompilationError` and instead use `e.stack` directly, there is
54
+ no proper message about _what_ the root cause of the exception was.
55
+ To mitigate that, we still serialize the first error in the message.
56
+
57
+
58
+ ### Deprecate HDBCDS backend
59
+
60
+ Only relevant for HANA on-prem (or "old" HaaS), as HANA CDS is not available on HANA Cloud.
61
+
62
+ In the early days of CAP, the only possibility to generate the DB schema was via
63
+ the hdbcds backend (i.e. generating HANA CDS files).
64
+
65
+ Since cds-compiler 1.5 the DB backend could alternatively be generated via hdbtable/hdbview,
66
+ while for new projects the default still was hdbcds.
67
+ With cds 7, the default was switched to hdbtable,
68
+ see [Release Notes June 2023](https://cap.cloud.sap/docs/releases/archive/2023/jun23#deploy-format-hdbtable)
69
+
70
+ For regular CAP projects on HANA, there now is no need to use the hdbcds backend any longer.
71
+ They should migrate to hdbtable. We are going to deprecate the hdbcds backend in compiler V5.
72
+
73
+ Time table:
74
+ * V5
75
+ - Document as deprecated
76
+ - No new features in hdbcds backend
77
+ - Only _critical_ bugfixes
78
+ - Using the hdbcds backend leads to warning message (can be down-graded to info)
79
+ * V6
80
+ - Using the hdbcds backend leads to error message (can be down-graded to warning)
81
+ * V7
82
+ - Remove code
83
+
84
+ When is hdbcds still needed?
85
+ * If custom code makes use of the HANA CDS metadata in the HANA catalog
86
+ * XSA to CAP migration currently requires deployment via hdbcds as an intermediate step.
87
+ Should no longer be necessary with HANA 2 SPS08 (RTC 20.11.2024)
88
+
89
+
90
+ ### Remove deprecated API functions `preparedCsnToEdmx` and `preparedCsnToEdm`
91
+
92
+ These two API functions have been deprecated since "SNAPI" was introduced.
93
+ `to.edm[x]` can now be used to achieve the same: If the CSN was OData preprocessed,
94
+ then it doesn't need to be preprocessed again.
95
+
96
+
97
+ ## Changes in CDL and CSN parser
98
+
99
+ ### Syntax restriction for nested inlines
100
+
101
+ For nested inline, forbid space between `.` and `{`.
102
+
103
+ Example:
104
+ ```cds
105
+ entity E {
106
+ a : Integer;
107
+ e : Association to E;
108
+ }
109
+ entity V1 as select from E {
110
+ e. {a}
111
+ // ^
112
+ }
113
+ ```
114
+
115
+ In v4: warning `syntax-unexpected-space`
116
+ In v5: configurable error `syntax-invalid-space`
117
+
118
+ Remark: As of v5.0.0, nested expand/inline were still documented as beta.
119
+ So this by definition is _not_ an incompatible change ...
120
+
121
+
122
+ ### Reject nonassignable annotations
123
+
124
+ Given a projection such as:
125
+
126
+ ```cds
127
+ entity Model { struct { a : Integer; } }
128
+ entity Wildcard as projection on Model {
129
+ @inline: ( i_am_only_a_warning ) // error in v5
130
+ struct.{*},
131
+ };
132
+ ```
133
+
134
+ In v4, the annotation `@inline` is ignored and the warning `syntax-ignoring-anno` is emitted.
135
+ However, it is not an error, even though it uses an expression with a non-resolvable
136
+ identifier.
137
+
138
+ In v5, all nonassignable annotations are rejected to avoid users
139
+ assuming that the references are valid. We now emit the error `syntax-unexpected-anno`.
140
+ The Error is not configurable. Authors need to fix their model.
141
+
142
+
143
+ ### Reject annotations on Mixin definitions via CSN input
144
+
145
+ It is not possible via CDL and not specified.
146
+ Even though normal propagation rules apply (i.e. annotations at mixin definition
147
+ are propagated to the inferred element if the mixin is published), reject them in v5.
148
+
149
+
150
+ ### Reject missing space between number and keyword
151
+
152
+ The lexer accidentally allows to have __no__ space between a number token and another
153
+ token. Example:
154
+
155
+ ```cds
156
+ entity U as SELECT Numbers * -1e1a, -1.1b, -1c, -1e-1d from TestTable;
157
+ ```
158
+
159
+ This is now a hard error (`syntax-expecting-space`) in cds-compiler v5, as it makes it
160
+ impossible to ever introduce postfixes for numbers and it makes it easy to accidentally
161
+ introduce a column alias.
162
+
163
+
164
+ ## Changes in Core Compiler
165
+
166
+ ### Errors for unapplied extend statement
167
+
168
+ Consistently issue an error if a reference used in an `extend` statement
169
+ does not point to an artifact definition, i.e. is not resolvable.
170
+ Only the `annotate` statement may produce an info or warning in that situation.
171
+
172
+ A “namespace” is not an artifact definition and must result in an error.
173
+
174
+ In v5, the only exception should be `extend … with definitions { … }` without
175
+ any annotation assignments, which adds a common name prefix to all definitions in the block.
176
+
177
+ (Also remove the message `Namespaces can't be annotated` for it.)
178
+ That `extend` statement should then also not appear in the output of `parse.cdl`.
179
+
180
+ Example:
181
+
182
+ ```cds
183
+ entity A.B.C {};
184
+ @anno: true
185
+ extend A.B; // this should be an error
186
+ ```
187
+
188
+
189
+ ### Upgrade some warnings to errors
190
+
191
+ Messages are:
192
+
193
+ 1. `ref-deprecated-self-element`: for `$self.‹elem›` references in `on` conditions of `joins` (see PR #12534)
194
+ Tests in `test3/Queries/Joins/RejectNonVisible.err.cds`. Avoid cases such as:
195
+ ```cds
196
+ entity AliasAndSelf as select from A
197
+ right join
198
+ ( B join C on C.c + B.b = C.c + $self.a ) // WARNING: to.sql replaces it with A.a → invisible
199
+ on A.a = B.b;
200
+
201
+ entity A { key a: Integer; }
202
+ entity B { key b: Integer; }
203
+ entity C { key c: Integer; }
204
+ ```
205
+ It's too easy to accidentally use elements that aren't available.
206
+ 2. `def-expected-structured`: for unstructured events
207
+ ```cds
208
+ event E : Integer;
209
+ ```
210
+ 3. `type-missing-enum-value`: for non-string enums that don't have explicit values
211
+ ```cds
212
+ entity Books {
213
+ category: Integer enum {
214
+ Fiction;
215
+ Action;
216
+ };
217
+ };
218
+ ```
219
+ 4. `name-deprecated-$self`: if user has defined an artifact `$self`; required for binding parameter
220
+ ```cds
221
+ entity $self {
222
+ key id : Integer;
223
+ }
224
+ ```
225
+ Elements named `$self` are still allowed.
226
+
227
+ All these messages are configurable.
228
+
229
+
230
+ ### Deprecate $at.from and $at.to
231
+
232
+ When starting with "temporal" we at first introduced the session variables `$at.from` and `$at.to`.
233
+ In April 2023 we "discovered" that these are wrong names and introduced `$valid.from` and `$valid.to`
234
+ as replacements.
235
+
236
+ In v5, issue a warning that `$at.from/to` are deprecated and should be replaced by `$valid.from/to`.
237
+ Replace `$at.from/to` by `$valid.from/to` in capire.
238
+
239
+ _Note:_ Java RT doesn't yet support `$valid`, they plan to do so with their v3 release.
240
+ Node RT apparently supports neither `$valid` nor `$at`.
241
+
242
+ Fix: use `$valid.from` and `$valid.to` instead.
243
+
244
+ ## Changes in OData/EDM
245
+
246
+ ### No Annotation propagation from element to artificial named type during type exposure
247
+
248
+ Current behavior:
249
+ For inline structured elements an artificial named type is created in **structured** EDMX.
250
+ Annotations for the structured element are copied/propagated to that type.
251
+
252
+ Example:
253
+ ```cds
254
+ service MyService {
255
+ entity E {
256
+ key id : Integer;
257
+ @Common.Label: 'Dingens'
258
+ struc {
259
+ x : Integer;
260
+ }
261
+ }
262
+ }
263
+ ```
264
+ ->
265
+ ```xml
266
+ <EntityType Name="E">
267
+ <Key> <PropertyRef Name="id"/> </Key>
268
+ <Property Name="id" Type="Edm.Int32" Nullable="false"/>
269
+ <Property Name="struc" Type="MyService.E_struc"/>
270
+ </EntityType>
271
+ <ComplexType Name="E_struc">
272
+ <Property Name="x" Type="Edm.Int32"/>
273
+ </ComplexType>
274
+ <Annotations Target="MyService.E/struc"> <!-- annotating the element -->
275
+ <Annotation Term="Common.Label" String="Dingens"/>
276
+ </Annotations>
277
+ <Annotations Target="MyService.E_struc"> <!-- annotating the type - will vanish -->
278
+ <Annotation Term="Common.Label" String="Dingens"/>
279
+ </Annotations>
280
+ ```
281
+
282
+ In most cases, this annotation propagation is not desired, as annotations
283
+ that are applicable to elements most likely are _not_ applicable to Complex Types.
284
+ If the value of the annotation is a path expression, the result may even be
285
+ an unresolvable path.
286
+
287
+ In V5, this kind of annotation propagation will no longer happen. If a type with
288
+ an annotation is needed in the result, users have to explicitly define a corresponding
289
+ named type in CDS.
290
+
291
+
292
+ ### Raise Spec violation warnings to error
293
+
294
+ Today, most spec violations are warnings (except for the pathological type missing situation).
295
+ Two of them are now reported as errors.
296
+
297
+ Note: Issue errors only when generating OData EDM(x) APIs. For EDM Json as input to the OpenAPI generator,
298
+ spec violations are still reported as warnings (with new option `edm4OpenApi`).
299
+
300
+ #### List of messages
301
+
302
+ 1. `odata-spec-violation-param`: "Expected parameter to be typed with either scalar or structured type for OData ‘2.0’"
303
+ v2 only - action/function must have scalar or structured type
304
+ ```cds
305
+ service S {
306
+ action foo(p: E);
307
+ entity E { key id : Integer; };
308
+ }
309
+ ```
310
+
311
+ 2. `odata-spec-violation-no-key`: "Expected entity to have a primary key"
312
+ Entity must have key
313
+ ```cds
314
+ service S {
315
+ entity Authors {
316
+ a : Integer;
317
+ };
318
+ }
319
+ ```
320
+ Implemented with `v5preview`. Only message that lead to errors in Node runtime if ignored.
321
+
322
+ Messages can be downgraded to warnings in `package.json` like this:
323
+ ```
324
+ {
325
+ "cds": {
326
+ "cdsc": {
327
+ "severities": {
328
+ "odata-spec-violation-property-name": "Warning"
329
+ }
330
+ }
331
+ }
332
+ }
333
+ ```
334
+
335
+
336
+ ### Restore propagation in vocabularies
337
+
338
+ In cds-compiler version 1, annotation definitions were part of
339
+ `csn.definitions` and annotations were propagated into annotation
340
+ definitions.
341
+
342
+ Since cds-compiler v2, annotation definitions were forgotten.
343
+ No propagation was performed.
344
+
345
+ Example:
346
+ ```cds
347
+ @anno
348
+ type T {
349
+ id: UUID;
350
+ }
351
+
352
+ annotation E {
353
+ elem: T;
354
+ };
355
+ ```
356
+
357
+ In v5, propagation is restored.
358
+
359
+
360
+ ## Changes in to.sql()
361
+
362
+ ### Localized entities and `@cds.persistence.exists`
363
+
364
+ Old behavior: for an entity with `@cds.persistence.exists`
365
+ * no table is generated for `E`
366
+ * no table is generated for `E.texts`
367
+ * no localized convenience view `localized_E` is generated (this one would join `E` and `E.texts`)
368
+ * localized convenience views for views/projections on top of E _are_ generated
369
+
370
+ Example:
371
+ ```cds
372
+ @cds.persistence.exists
373
+ entity E {
374
+ key id : Integer;
375
+ name : localized String(10);
376
+ }
377
+ entity P as projection on E;
378
+ ```
379
+ ->
380
+ ```sql
381
+ CREATE VIEW P AS SELECT
382
+ E_0.id,
383
+ E_0.name
384
+ FROM E AS E_0;
385
+
386
+ CREATE VIEW localized_P AS SELECT
387
+ E_0.id,
388
+ E_0.name
389
+ FROM localized_E AS E_0;
390
+ ```
391
+
392
+ When adding the annotation `@cds.persistence.exists`, the user is expected to provide
393
+ tables `E` and `E_texts`, and in v4 also the view `localized_E`.
394
+
395
+ Because this behavior is not fully consistent with the idea of the
396
+ localized convenience views being an "implementation detail" that the user
397
+ should not be aware of, the view `localized_E` _is_ generated by the compiler v5.
398
+
399
+ Already today the compiler can be forced to create the convenience view by
400
+ ```
401
+ annotate localized.E with @cds.persistence.exists: false;
402
+ ```
403
+
404
+ The old behavior can be restored by
405
+ ```cds
406
+ annotate localized.E with @cds.persistence.exists: true;
407
+ ```
408
+
409
+ Note: This "rolls back" part of an incompatible change in V3
410
+ where we probably didn't thoroughly consider this particular topic.
411
+
412
+
413
+ ### Changes for dialect sqlite
414
+
415
+ With CAP 8, the default database adapter for SQLite in the node runtime will be `@cap-js/sqlite`.
416
+ Thus we should also adapt the dialect `sqlite` in the compiler to use the "new" session
417
+ variables by default. Before, they had to be switched on explicitly via configuration
418
+ `betterSqliteSessionVariables`.
419
+
420
+ For projects still using the old SQLite DB adapter, the umbrella will modify the generated
421
+ CSN and replace the `session_context` functions with the respective old values, e.g.
422
+ ```
423
+ session_context( '$user.locale' ) -> 'en'
424
+ session_context( '$valid.from' ) -> strftime('%Y-%m-%dT%H:%M:%S.000Z', 'now')
425
+ ```
426
+
427
+ Temporarily (until final release of v5) the compiler will provide the old behavior if
428
+ config variable `betterSqliteSessionVariables` is explicitly set to `false`.
429
+
430
+
431
+ ### Fewer localized views
432
+
433
+ In v5, transitive localized views are no longer generated by default.
434
+
435
+ The old behavior is still needed for old HANA and SQLite DB drivers on Node RT. It can be
436
+ obtained by explicitly setting `fewerLocalizedViews` to `false`.