@sap/cds-compiler 4.0.2 → 4.2.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.
- package/CHANGELOG.md +200 -5
- package/bin/cdsc.js +18 -15
- package/doc/CHANGELOG_BETA.md +16 -0
- package/doc/CHANGELOG_DEPRECATED.md +15 -0
- package/lib/api/main.js +33 -13
- package/lib/api/options.js +2 -2
- package/lib/api/validate.js +25 -25
- package/lib/base/location.js +6 -7
- package/lib/base/message-registry.js +123 -42
- package/lib/base/messages.js +18 -10
- package/lib/base/model.js +43 -10
- package/lib/checks/defaultValues.js +6 -6
- package/lib/checks/elements.js +11 -10
- package/lib/checks/foreignKeys.js +0 -5
- package/lib/checks/manyNavigations.js +33 -0
- package/lib/checks/onConditions.js +22 -14
- package/lib/checks/queryNoDbArtifacts.js +132 -73
- package/lib/checks/selectItems.js +4 -55
- package/lib/checks/sql-snippets.js +15 -4
- package/lib/checks/types.js +3 -3
- package/lib/checks/utils.js +4 -3
- package/lib/checks/validator.js +3 -1
- package/lib/compiler/.eslintrc.json +2 -1
- package/lib/compiler/assert-consistency.js +71 -40
- package/lib/compiler/base.js +7 -2
- package/lib/compiler/builtins.js +40 -41
- package/lib/compiler/checks.js +415 -367
- package/lib/compiler/classes.js +62 -0
- package/lib/compiler/cycle-detector.js +9 -9
- package/lib/compiler/define.js +124 -90
- package/lib/compiler/extend.js +115 -88
- package/lib/compiler/finalize-parse-cdl.js +26 -25
- package/lib/compiler/generate.js +57 -49
- package/lib/compiler/index.js +56 -56
- package/lib/compiler/kick-start.js +10 -7
- package/lib/compiler/moduleLayers.js +1 -1
- package/lib/compiler/populate.js +180 -144
- package/lib/compiler/propagator.js +10 -9
- package/lib/compiler/resolve.js +321 -246
- package/lib/compiler/shared.js +812 -433
- package/lib/compiler/tweak-assocs.js +114 -50
- package/lib/compiler/utils.js +241 -46
- package/lib/edm/.eslintrc.json +40 -1
- package/lib/edm/annotations/genericTranslation.js +721 -707
- package/lib/edm/annotations/preprocessAnnotations.js +88 -77
- package/lib/edm/csn2edm.js +389 -378
- package/lib/edm/edm.js +679 -770
- package/lib/edm/edmAnnoPreprocessor.js +132 -146
- package/lib/edm/edmInboundChecks.js +29 -27
- package/lib/edm/edmPreprocessor.js +689 -648
- package/lib/edm/edmUtils.js +279 -300
- package/lib/gen/Dictionary.json +34 -10
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +1 -1
- package/lib/gen/languageParser.js +2857 -2856
- package/lib/json/from-csn.js +77 -51
- package/lib/json/to-csn.js +15 -15
- package/lib/language/antlrParser.js +2 -1
- package/lib/language/genericAntlrParser.js +52 -43
- package/lib/language/language.g4 +61 -64
- package/lib/language/multiLineStringParser.js +2 -0
- package/lib/main.d.ts +65 -0
- package/lib/model/csnRefs.js +37 -19
- package/lib/model/csnUtils.js +51 -18
- package/lib/model/revealInternalProperties.js +30 -22
- package/lib/modelCompare/compare.js +149 -41
- package/lib/modelCompare/utils/filter.js +55 -25
- package/lib/optionProcessor.js +21 -9
- package/lib/render/manageConstraints.js +20 -17
- package/lib/render/toCdl.js +63 -23
- package/lib/render/toHdbcds.js +2 -2
- package/lib/render/toRename.js +4 -9
- package/lib/render/toSql.js +82 -35
- package/lib/render/utils/common.js +11 -9
- package/lib/render/utils/unique.js +52 -0
- package/lib/transform/db/applyTransformations.js +62 -21
- package/lib/transform/db/assertUnique.js +7 -8
- package/lib/transform/db/associations.js +2 -2
- package/lib/transform/db/cdsPersistence.js +9 -9
- package/lib/transform/db/constraints.js +47 -17
- package/lib/transform/db/expansion.js +138 -68
- package/lib/transform/db/flattening.js +98 -30
- package/lib/transform/db/rewriteCalculatedElements.js +20 -14
- package/lib/transform/db/temporal.js +1 -1
- package/lib/transform/db/transformExists.js +8 -7
- package/lib/transform/db/views.js +73 -33
- package/lib/transform/draft/db.js +11 -9
- package/lib/transform/draft/odata.js +1 -1
- package/lib/transform/{forOdataNew.js → forOdata.js} +10 -7
- package/lib/transform/forRelationalDB.js +148 -136
- package/lib/transform/localized.js +92 -54
- package/lib/transform/odata/toFinalBaseType.js +3 -3
- package/lib/transform/{transformUtilsNew.js → transformUtils.js} +13 -111
- package/lib/transform/translateAssocsToJoins.js +14 -28
- package/lib/utils/file.js +7 -7
- package/lib/utils/moduleResolve.js +210 -121
- package/lib/utils/objectUtils.js +1 -1
- package/package.json +5 -5
- package/share/messages/check-proper-type-of.md +1 -1
- package/share/messages/{check-proper-type.md → def-missing-type.md} +3 -5
- package/share/messages/message-explanations.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,155 @@
|
|
|
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 4.2.2 - 2023-08-31
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- to.sql|hdi.migration: Fix bug that caused a migration to be rendered for the HANA CDS types that were removed from the CSN
|
|
15
|
+
|
|
16
|
+
## Version 4.2.0 - 2023-08-29
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Compiler:
|
|
21
|
+
+ Option `moduleLookupDirectories: [ 'strings' ]` can be used to specify additional module lookup
|
|
22
|
+
directories, similar to `node_modules/`.
|
|
23
|
+
+ LIMIT and OFFSET clauses can now contain expressions, including parameter references.
|
|
24
|
+
- to.edm(x):
|
|
25
|
+
+ Detect spec violation `scale` > `precision`.
|
|
26
|
+
- to.sql/for.odata:
|
|
27
|
+
+ With the new option `fewerLocalizedViews: true|false`, an entity/view will not get a localized convenience
|
|
28
|
+
view, if it only has associations to localized entities/views. Only if there is actually a localized
|
|
29
|
+
element (e.g. new localized element or reference to one), will it get a convenience view.
|
|
30
|
+
- to.sql
|
|
31
|
+
+ In a localized scenario, create foreign key constraints for the generated `.texts` entities.
|
|
32
|
+
+ Casting `null` to a structure such as `null as field : StructT` is now supported. For each leaf element,
|
|
33
|
+
an additional `null as field_name` column is added.
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
- Compiler:
|
|
38
|
+
+ Selecting fields of structures or associations (without filters) are now candidates for ON-condition
|
|
39
|
+
rewrites: It is no longer necessary to select the struct/association directly.
|
|
40
|
+
+ Consistently handle the case when type elements are defined to be a `key`:
|
|
41
|
+
the `key` property is not only preserved with `includes`, but also in other cases.
|
|
42
|
+
Use option `deprecated.noKeyPropagationWithExpansions` to switch to the v3 behavior.
|
|
43
|
+
+ When including aspects or entities into structured type definitions,
|
|
44
|
+
do not add actions to the type.
|
|
45
|
+
+ An `annotate` statement in the `extensions` section of a CSN now consistently uses the
|
|
46
|
+
`elements` property even if the `annotate` is intended to be used for an enum symbol.
|
|
47
|
+
Before v4.2, the compiler has used the `enum` property in a CSN of flavor `xtended`
|
|
48
|
+
(`gensrc`) if it was certain that it was to be applied to an enum symbol.
|
|
49
|
+
- to.cdl: If a definition has an `actions` property, an `actions {…}` block is now always rendered,
|
|
50
|
+
and is not ignored if empty.
|
|
51
|
+
- to.sql:
|
|
52
|
+
+ For SQL dialect "sqlite", `cds.DateTime` is now rendered as `DATETIME_TEXT` instead of `TIMESTAMP_TEXT`.
|
|
53
|
+
+ Casting a literal (except `null`) to a structure now yields a proper error.
|
|
54
|
+
+ `.texts` entities annotated with `@cds.persistence.skip` (without their original entity having that annotation)
|
|
55
|
+
lead to deployment issues later. It is now an error.
|
|
56
|
+
|
|
57
|
+
### Fixed
|
|
58
|
+
|
|
59
|
+
- Compiler:
|
|
60
|
+
+ Reject invalid reference in the `on` of `join`s already while compiling,
|
|
61
|
+
not just when calling the (SQL) backend.
|
|
62
|
+
+ Correct the calculation of annotation assignments on the return structure of actions
|
|
63
|
+
when both `annotate … with {…}` and `annotate … with returns {…}` had been used
|
|
64
|
+
on the same structure element. Ensure that it works when non-applied, too.
|
|
65
|
+
+ Do not remove or invent `actions` properties with zero actions or functions in it.
|
|
66
|
+
+ Correct auto-redirection of direct cycle associations: if the source and target of a
|
|
67
|
+
model association are the same entity, and the main artifact of the service association
|
|
68
|
+
based on the model association is a suitable auto-redirection target, then use it
|
|
69
|
+
as new target, independently from the value of `@cds.redirection.target`.
|
|
70
|
+
- to.cdl: Indirectly structured types (`type T: Struct;`) with `includes` (`extend T with T2;`), are now properly rendered.
|
|
71
|
+
- to.sql/hdi/hdbcds:
|
|
72
|
+
+ Views on views with parameters did not have localized convenience views based on
|
|
73
|
+
other localized views (missing `localized.` prefix in FROM clause)
|
|
74
|
+
+ Run less checks on entities marked with `@cds.persistence.exists`
|
|
75
|
+
+ Correctly render SELECT items where the column name conflicts with a table alias
|
|
76
|
+
- to.sql: Casting expressions to a structured type yields a proper error instead of strange compiler error.
|
|
77
|
+
- to.edm(x):
|
|
78
|
+
+ Don't expand `@mandatory` if element has an annotation with prefix `@Common.FieldControl.`.
|
|
79
|
+
+ Fix a bug when referencing nested many structures, especially referring to a managed association via
|
|
80
|
+
`$self` comparison.
|
|
81
|
+
+ Improve handling of non-collection annotation values for collection-like vocabulary types.
|
|
82
|
+
+ Don't render `Scale: variable` for `cds.Decimal(scale:0)`.
|
|
83
|
+
- to.sql|hdi.migration:
|
|
84
|
+
+ Fixed a bug that caused rendering of `ALTER` statements to abort early and not render some statements.
|
|
85
|
+
+ CSN output now only contains real `cds` builtins, no early remapping to HANA CDS types or similar.
|
|
86
|
+
- to.sql.migration: Don't drop-create views marked with `@cds.persistence.exists`
|
|
87
|
+
|
|
88
|
+
### Removed
|
|
89
|
+
|
|
90
|
+
## Version 4.1.2 - 2023-07-31
|
|
91
|
+
|
|
92
|
+
### Fixed
|
|
93
|
+
|
|
94
|
+
- to.hdi.migration: Changes in constraints are not rendered as part of the .hdbmigrationtable file,
|
|
95
|
+
as they belong in other HDI artifacts
|
|
96
|
+
|
|
97
|
+
## Version 4.1.0 - 2023-07-28
|
|
98
|
+
|
|
99
|
+
### Added
|
|
100
|
+
|
|
101
|
+
- Calculated elements "on-read" can now reference localized elements.
|
|
102
|
+
- Aliases for columns inside sub-queries are now optional, also for expressions.
|
|
103
|
+
- for.odata/to.hdi/to.sql: Specified default value on a managed association is forwarded to a foreign key
|
|
104
|
+
if association has exactly one foreign key.
|
|
105
|
+
- CDL: Annotation-only aspects having no `elements` and `actions` can now be defined with
|
|
106
|
+
the CDL syntax `@Anno… aspect Name;`. They cannot be extended with elements or actions
|
|
107
|
+
in order to ensure that they can always be used to extend non-structures.
|
|
108
|
+
To allow the former but not the latter, use `@Anno… aspect Name {…};`.
|
|
109
|
+
- to.sql: Support session variables for h2
|
|
110
|
+
|
|
111
|
+
### Changed
|
|
112
|
+
|
|
113
|
+
- api: Function `isInReservedNamespace(name)` handles name `cds` as being in a reserved namespace as well.
|
|
114
|
+
- `CompilationError.messages` are now sorted severity aware. Errors are listed first.
|
|
115
|
+
- Compiler:
|
|
116
|
+
+ Improve the calculation of semantic code completion candidates.
|
|
117
|
+
+ Some checks, like those for valid `on` conditions of associations,
|
|
118
|
+
are now already done with `compile` and not just the backends.
|
|
119
|
+
+ SQL `cast()`s must always have a `type` property
|
|
120
|
+
+ Type properties such as `precision` or `length` must be accompanied by a type (possibly inferred).
|
|
121
|
+
- for.odata/to.hdi/to.sql: No longer reject unmanaged associations as foreign keys of a managed association.
|
|
122
|
+
Instead, ignore such references during ON-condition rewriting and foreign key generation. Referring to
|
|
123
|
+
unmanaged associations is incompatible with SAP HANA CDS naming mode 'hdbcds'.
|
|
124
|
+
- to.sql: Rework session variables for postgres.
|
|
125
|
+
- Update OData vocabularies: 'Common', 'HTML5', 'PersonalData', 'UI'.
|
|
126
|
+
|
|
127
|
+
### Fixed
|
|
128
|
+
|
|
129
|
+
- Compiler:
|
|
130
|
+
+ ensure that annotations of elements in anonymous aspects of managed compositions
|
|
131
|
+
are not lost.
|
|
132
|
+
+ issue error for definitions like `entity Self as projection on Base { $self.* };`
|
|
133
|
+
instead of simply concluding that the projection has zero elements.
|
|
134
|
+
+ do not report a invalid cyclic dependency if associations between two entities
|
|
135
|
+
are valid cycles.
|
|
136
|
+
+ Element type references can again follow associations (removed v4.0 incompatibility).
|
|
137
|
+
- to.sql:
|
|
138
|
+
+ `$self` references inside a nested projection using `$self` was incorrectly resolved.
|
|
139
|
+
+ associations to entities marked with `@cds.persistence.skip` were not properly
|
|
140
|
+
checked inside nested projections.
|
|
141
|
+
+ Select items casting `null` to an arrayed type work again, e.g. `null as ManyType`.
|
|
142
|
+
- to.sql/hdi/hdbcds: Raise a nice error message for `@sql.append` on managed associations/compositions,
|
|
143
|
+
as we do for structured error messages.
|
|
144
|
+
- to.cdl: Annotations with multiple qualifiers (`#`) are now rendered correctly.
|
|
145
|
+
- to.edm(x): Revert change introduced with [3.9.0](#version-390---2023-04-20)
|
|
146
|
+
"Correct referential constraint calculation for `[0..1]` backlink associations".
|
|
147
|
+
- for.odata: Process shortcut annotations sequence independent.
|
|
148
|
+
- to.sql.migration:
|
|
149
|
+
+ Respect unique and referential constraints for delta calculation.
|
|
150
|
+
+ Added a configurable error for primary key additions, as those will lead to errors if the table
|
|
151
|
+
contains data. This could lead to inconsistent states if
|
|
152
|
+
some deployments succeed and others fail, so by default it is an error.
|
|
153
|
+
|
|
154
|
+
### Removed
|
|
155
|
+
|
|
156
|
+
- Compiler:
|
|
157
|
+
+ forbid wildcards in projection extensions: `extend … with columns { * )`.
|
|
158
|
+
+ forbid column references such as `$user.*`, `$user.{id}` and `$user {id}`.
|
|
10
159
|
|
|
11
160
|
## Version 4.0.2 - 2023-06-22
|
|
12
161
|
|
|
@@ -77,8 +226,6 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
77
226
|
+ Table alias and mixin names can no longer start with `$`. Choose a different name. With this change
|
|
78
227
|
we avoid unexpected name resolution effects in combination with built-in `$`-variables.
|
|
79
228
|
+ 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
229
|
+ Message ID `duplicate-autoexposed` was changed to `def-duplicate-autoexposed`.
|
|
83
230
|
- Update OData vocabularies 'Common', 'UI'.
|
|
84
231
|
- to.sql:
|
|
@@ -96,7 +243,12 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
96
243
|
+ `parseCdl` CSN did not include correct `...` entries for annotations containing `... up to`
|
|
97
244
|
+ Type references inside calculated elements were not always correctly resolved.
|
|
98
245
|
+ `USING` empty files were incorrectly marked as "not found".
|
|
246
|
+
+ Correct the handling of `$self` references in nested projections and filters in queries.
|
|
99
247
|
+ If an association was inside `items`, e.g. via type chains, the compiler crashes instead of emitting proper errors.
|
|
248
|
+
+ References in the user-provided `on` conditions of associations with a to be
|
|
249
|
+
auto-redirected model entity as target were not always resolved correctly.
|
|
250
|
+
Complain in error situations.
|
|
251
|
+
+ Make extend code robust against prototype-polluted JS classes.
|
|
100
252
|
- Localized convenience views for projections (not views) did not have references rewritten.
|
|
101
253
|
This only affects CSN, the SQL result was correct.
|
|
102
254
|
- Calculated elements in composition-of-aspect lost their `value` when generating composition targets.
|
|
@@ -116,9 +268,52 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
116
268
|
- NodeJs 14 is no longer supported.
|
|
117
269
|
- `CompileMessage` no longer has property `location`, which was deprecated in v2.1.0, but `$location`,
|
|
118
270
|
which is supported since v2.1.0
|
|
119
|
-
-
|
|
120
|
-
|
|
121
|
-
|
|
271
|
+
- compiler:
|
|
272
|
+
+ It is no longer possible to write `type of $self.‹elem›` to refer to the element `‹Def›.‹elem›`
|
|
273
|
+
where `‹Def›` is the main artifact where the type expression is embedded in. Replace by `type of <Def>:‹elem›`.
|
|
274
|
+
+ Element type references can no longer follow associations, i.e. `E:assoc.id` is not allowed
|
|
275
|
+
(v4.0 only, re-introduced with v4.1).
|
|
276
|
+
+ "Smart type references" such as `Entity.myElement` instead of `Entity:myElement`
|
|
277
|
+
are removed, because since - `Entity.myElement` could also be a definition,
|
|
278
|
+
creating ambiguities. This did not work always, anyway.
|
|
279
|
+
|
|
280
|
+
## Version 3.9.10 - 2023-08-25
|
|
281
|
+
|
|
282
|
+
### Fixed
|
|
283
|
+
|
|
284
|
+
- to.edm(x): Error reporting for incorrect handling of "Collection()" has been improved.
|
|
285
|
+
- to.sql/hdi/hdbcds: Views on views with parameters did not have localized convenience views based on
|
|
286
|
+
other localized views (missing `localized.` prefix in FROM clause)
|
|
287
|
+
- to.sql: Casting expressions to a structured type yields a proper error instead of strange compiler error.
|
|
288
|
+
- to.sql.migration: Don't drop-create views marked with `@cds.persistence.exists` or `@cds.persistence.skip`
|
|
289
|
+
|
|
290
|
+
## Version 3.9.8 - 2023-08-03
|
|
291
|
+
|
|
292
|
+
### Fixed
|
|
293
|
+
|
|
294
|
+
- to.edm(x):
|
|
295
|
+
+ Don't expand `@mandatory` if element has an annotation with prefix `@Common.FieldControl.`.
|
|
296
|
+
+ Fix a bug when referencing nested many structures, especially referring to a managed association via
|
|
297
|
+
`$self` comparison.
|
|
298
|
+
- to.sql/hdi/hdbcds: Detect navigation into arrayed structures and raise helpful errors instead of running into internal errors.
|
|
299
|
+
|
|
300
|
+
## Version 3.9.6 - 2023-07-27
|
|
301
|
+
|
|
302
|
+
### Fixed
|
|
303
|
+
|
|
304
|
+
- to.edm(x): Revert change introduced with [3.9.0](#version-390---2023-04-20)
|
|
305
|
+
"Correct referential constraint calculation for `[0..1]` backlink associations".
|
|
306
|
+
- for.odata: Process shortcut annotations sequence independent.
|
|
307
|
+
|
|
308
|
+
## Version 3.9.4 - 2023-06-07
|
|
309
|
+
|
|
310
|
+
### Fixed
|
|
311
|
+
|
|
312
|
+
- compiler: `USING` empty files were incorrectly marked as "not found".
|
|
313
|
+
- Localized convenience views for projections (not views) did not have references rewritten.
|
|
314
|
+
This only affects CSN, the SQL result was correct.
|
|
315
|
+
- to.edm(x): Render correct EntitySetPath and annotation target path for actions/functions
|
|
316
|
+
with explicit binding parameter.
|
|
122
317
|
|
|
123
318
|
## Version 3.9.2 - 2023-04-27
|
|
124
319
|
|
package/bin/cdsc.js
CHANGED
|
@@ -162,7 +162,7 @@ function cdsc_main() {
|
|
|
162
162
|
validateDirectBackendOption(cmdLine.command, cmdLine.options, cmdLine.args);
|
|
163
163
|
|
|
164
164
|
// If set through CLI (and not options file), `beta` is a string and needs processing.
|
|
165
|
-
if (
|
|
165
|
+
if (typeof cmdLine.options.beta === 'string') {
|
|
166
166
|
const features = cmdLine.options.beta.split(',');
|
|
167
167
|
cmdLine.options.beta = {};
|
|
168
168
|
features.forEach((val) => {
|
|
@@ -191,14 +191,17 @@ function cdsc_main() {
|
|
|
191
191
|
console.error( `Running ‘${cmdLine.command}’ with test-mode shuffle ${cmdLine.options.testMode} …` );
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
-
// If set through CLI (and not options file), `deprecated`
|
|
195
|
-
|
|
194
|
+
// If set through CLI (and not options file), `deprecated` and `moduleLookupDirectories`
|
|
195
|
+
// are strings and needs processing.
|
|
196
|
+
if (typeof cmdLine.options.deprecated === 'string') {
|
|
196
197
|
const features = cmdLine.options.deprecated.split(',');
|
|
197
198
|
cmdLine.options.deprecated = {};
|
|
198
199
|
features.forEach((val) => {
|
|
199
200
|
cmdLine.options.deprecated[val] = true;
|
|
200
201
|
});
|
|
201
202
|
}
|
|
203
|
+
if (typeof cmdLine.options.moduleLookupDirectories === 'string')
|
|
204
|
+
cmdLine.options.moduleLookupDirectories = cmdLine.options.moduleLookupDirectories.split(',');
|
|
202
205
|
|
|
203
206
|
parseSeverityOptions(cmdLine);
|
|
204
207
|
|
|
@@ -499,29 +502,29 @@ function executeCommandLine( command, options, args ) {
|
|
|
499
502
|
|
|
500
503
|
sortMessages(messages);
|
|
501
504
|
|
|
505
|
+
const msgConfig = {
|
|
506
|
+
normalizeFilename,
|
|
507
|
+
noMessageId: !!options.noMessageId,
|
|
508
|
+
hintExplanation: true,
|
|
509
|
+
color: options.color,
|
|
510
|
+
module: options.testMode && 'compile', // TODO: use module name
|
|
511
|
+
sourceMap: fileCache,
|
|
512
|
+
cwd: '',
|
|
513
|
+
};
|
|
514
|
+
|
|
502
515
|
if (options.internalMsg) {
|
|
503
516
|
messages.map(msg => util.inspect( msg, { depth: null, maxArrayLength: null } ) )
|
|
504
517
|
.forEach(msg => log(msg));
|
|
505
518
|
}
|
|
506
519
|
else if (options.noMessageContext) {
|
|
507
520
|
messages.filter(msg => (messageLevels[msg.severity] <= options.warning))
|
|
508
|
-
.forEach(msg => log(main.messageString(msg,
|
|
521
|
+
.forEach(msg => log(main.messageString( msg, msgConfig )));
|
|
509
522
|
}
|
|
510
523
|
else {
|
|
511
524
|
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
|
-
|
|
522
525
|
messages.filter(msg => messageLevels[msg.severity] <= options.warning).forEach((msg) => {
|
|
523
526
|
hasAtLeastOneExplanation = hasAtLeastOneExplanation || main.hasMessageExplanation(msg.messageId);
|
|
524
|
-
log(main.messageStringMultiline(msg,
|
|
527
|
+
log(main.messageStringMultiline(msg, msgConfig));
|
|
525
528
|
log(); // newline
|
|
526
529
|
});
|
|
527
530
|
if (!options.noMessageId && hasAtLeastOneExplanation)
|
package/doc/CHANGELOG_BETA.md
CHANGED
|
@@ -8,6 +8,17 @@ 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.1.0 - 2023-07-28
|
|
12
|
+
|
|
13
|
+
### Added `associationDefault`
|
|
14
|
+
|
|
15
|
+
With this beta flag enabled, managed associations with exactly one foreign key can now
|
|
16
|
+
have a default value.
|
|
17
|
+
|
|
18
|
+
### Removed `aspectWithoutElements`
|
|
19
|
+
|
|
20
|
+
Aspects without elements can now be defined without beta flag, e.g. `aspect A;`.
|
|
21
|
+
|
|
11
22
|
## Version 4.0.0 - 2023-06-06
|
|
12
23
|
|
|
13
24
|
### Removed `v4preview`
|
|
@@ -62,6 +73,11 @@ Now enabled per default.
|
|
|
62
73
|
|
|
63
74
|
## Version 3.7.0 - 2023-02-22
|
|
64
75
|
|
|
76
|
+
### Added `annotationExpressions`
|
|
77
|
+
|
|
78
|
+
This option allows to use expressions as annotation values, e.g.
|
|
79
|
+
`@anno: (1+2)`.
|
|
80
|
+
|
|
65
81
|
### Added `calculatedElements`
|
|
66
82
|
|
|
67
83
|
Allows to define calculated elements in entities and aspects. When used in views, they
|
|
@@ -11,6 +11,21 @@ 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.2.0 - 2023-08-29
|
|
15
|
+
|
|
16
|
+
### Added `noKeyPropagationWithExpansions`
|
|
17
|
+
|
|
18
|
+
When this option is set, element `id` in types `Orig` and `I` are keys,
|
|
19
|
+
but `id` in `D` is not.
|
|
20
|
+
|
|
21
|
+
```cds
|
|
22
|
+
type Orig { key id: Integer };
|
|
23
|
+
type I: Orig {};
|
|
24
|
+
type D: Orig;
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
When this option is not set, element `id` in all three types are keys.
|
|
28
|
+
|
|
14
29
|
## Version 4.0.0 - 2023-06-06
|
|
15
30
|
|
|
16
31
|
### Added `downgradableErrors`
|
package/lib/api/main.js
CHANGED
|
@@ -8,7 +8,7 @@ const location = lazyload('../base/location');
|
|
|
8
8
|
const messages = lazyload('../base/messages');
|
|
9
9
|
const compiler = lazyload('../compiler/index');
|
|
10
10
|
const toCsn = lazyload('../json/to-csn');
|
|
11
|
-
const forOdataNew = lazyload('../transform/
|
|
11
|
+
const forOdataNew = lazyload('../transform/forOdata.js');
|
|
12
12
|
const toSql = lazyload('../render/toSql');
|
|
13
13
|
const toCdl = require('../render/toCdl');
|
|
14
14
|
const modelCompare = lazyload('../modelCompare/compare');
|
|
@@ -95,14 +95,14 @@ function checkPreTransformedCsn( csn, options, relevantOptionNames, warnAboutMis
|
|
|
95
95
|
|
|
96
96
|
for (const name of relevantOptionNames ) {
|
|
97
97
|
if (options[name] !== csn.meta.options?.[name]) {
|
|
98
|
-
error('
|
|
98
|
+
error('api-invalid-option-preprocessed', null, { prop: name, value: options[name], othervalue: csn.meta.options[name] },
|
|
99
99
|
'Expected pre-processed CSN to have option $(PROP) set to $(VALUE). Found: $(OTHERVALUE)');
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
for (const name of warnAboutMismatch ) {
|
|
104
104
|
if (options[name] !== csn.meta.options[name]) {
|
|
105
|
-
warning('
|
|
105
|
+
warning('api-mismatched-option-preprocessed', null, { prop: name, value: options[name], othervalue: csn.meta.options[name] },
|
|
106
106
|
'Expected pre-processed CSN to have option $(PROP) set to $(VALUE). Found: $(OTHERVALUE)');
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -242,8 +242,10 @@ function sql( csn, options = {} ) {
|
|
|
242
242
|
const sqls = toSql.toSqlDdl(transformedCsn, internalOptions);
|
|
243
243
|
|
|
244
244
|
const result = sortViews({ csn: transformedCsn, sql: sqls.sql });
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
return [
|
|
246
|
+
...result.map(obj => obj.sql).filter(create => create),
|
|
247
|
+
...Object.values(sqls.constraints || {}),
|
|
248
|
+
];
|
|
247
249
|
}
|
|
248
250
|
|
|
249
251
|
/**
|
|
@@ -359,7 +361,9 @@ function remapName( key, csn, filter = () => true ) {
|
|
|
359
361
|
function sqlMigration( csn, options, beforeImage ) {
|
|
360
362
|
traceApi("Options passed into 'to.sql.migration'", options);
|
|
361
363
|
const internalOptions = prepareOptions.to.sql(options);
|
|
362
|
-
const {
|
|
364
|
+
const {
|
|
365
|
+
error, warning, info, throwWithError, message,
|
|
366
|
+
} = messages.makeMessageFunction(csn, internalOptions, 'to.sql.migration');
|
|
363
367
|
|
|
364
368
|
// Prepare after-image.
|
|
365
369
|
const afterImage = internalOptions.filterCsn
|
|
@@ -369,8 +373,12 @@ function sqlMigration( csn, options, beforeImage ) {
|
|
|
369
373
|
const diffFilterObj = diffFilter[internalOptions.sqlDialect];
|
|
370
374
|
|
|
371
375
|
if (diffFilterObj) {
|
|
372
|
-
diff.extensions.
|
|
373
|
-
|
|
376
|
+
diff.extensions = diff.extensions.filter(ex => diffFilterObj.extension(ex, {
|
|
377
|
+
error, warning, info, throwWithError, message,
|
|
378
|
+
}));
|
|
379
|
+
diff.migrations.forEach(migration => diffFilterObj.migration(migration, {
|
|
380
|
+
error, warning, info, throwWithError, message,
|
|
381
|
+
}));
|
|
374
382
|
Object.entries(diff.deletions).forEach(entry => diffFilterObj.deletion(entry, error));
|
|
375
383
|
}
|
|
376
384
|
|
|
@@ -392,8 +400,7 @@ function sqlMigration( csn, options, beforeImage ) {
|
|
|
392
400
|
const beforeArtifact = beforeImage.definitions[artifactName];
|
|
393
401
|
const diffArtifact = diff.definitions[artifactName];
|
|
394
402
|
// TODO: exists, abstract? isPersistedOnDb?
|
|
395
|
-
if (diffArtifact && diffArtifact['@cds.persistence.name'] &&
|
|
396
|
-
(diffArtifact.query || diffArtifact.projection) &&
|
|
403
|
+
if (diffArtifact && diffArtifact['@cds.persistence.name'] && csnUtils.isPersistedAsView(diffArtifact) &&
|
|
397
404
|
(diffArtifact[modelCompare.isChanged] === true || // we know it changed because we compared two views
|
|
398
405
|
diffArtifact[modelCompare.isChanged] === undefined)) { // if it was removed in the after, then we don't have the flag
|
|
399
406
|
drops.creates[artifactName] = `DROP VIEW ${ identifierUtils.renderArtifactName(artifactName) };`;
|
|
@@ -401,6 +408,7 @@ function sqlMigration( csn, options, beforeImage ) {
|
|
|
401
408
|
else if (diffArtifact &&
|
|
402
409
|
diffArtifact['@cds.persistence.skip'] !== true &&
|
|
403
410
|
diffArtifact.kind === beforeArtifact.kind && // detect action -> entity
|
|
411
|
+
csnUtils.isPersistedAsTable(diffArtifact) === csnUtils.isPersistedAsTable(beforeArtifact) && // detect removal of @cds.persistence.exists
|
|
404
412
|
csnUtils.isPersistedAsView(diffArtifact) === csnUtils.isPersistedAsView(beforeArtifact) // detect view -> entity
|
|
405
413
|
) { // don't render again, but need info for primary key extension
|
|
406
414
|
diffArtifact['@cds.persistence.skip'] = true;
|
|
@@ -443,8 +451,10 @@ function sqlMigration( csn, options, beforeImage ) {
|
|
|
443
451
|
|
|
444
452
|
internalOptions.beta.sqlExtensions = true;
|
|
445
453
|
|
|
446
|
-
|
|
447
|
-
|
|
454
|
+
const {
|
|
455
|
+
// eslint-disable-next-line no-unused-vars
|
|
456
|
+
deletions, constraintDeletions, migrations, constraints, ...hdbkinds
|
|
457
|
+
} = toSql.toSqlDdl(diff, internalOptions);
|
|
448
458
|
|
|
449
459
|
cleanup.forEach(fn => fn());
|
|
450
460
|
// TODO: Handle `ADD CONSTRAINT` etc!
|
|
@@ -473,6 +483,12 @@ function sqlMigration( csn, options, beforeImage ) {
|
|
|
473
483
|
createAndAlterSqls.push(...migrations[name].map(m => m.sql));
|
|
474
484
|
}
|
|
475
485
|
|
|
486
|
+
if (constraints)
|
|
487
|
+
Object.values(constraints).forEach(constraint => createAndAlterSqls.push(constraint));
|
|
488
|
+
|
|
489
|
+
if (constraintDeletions)
|
|
490
|
+
Object.values(constraintDeletions).forEach(constraint => dropSqls.push(constraint));
|
|
491
|
+
|
|
476
492
|
// We need to drop the things without dependants first - so inversely sorted
|
|
477
493
|
dropSqls.reverse();
|
|
478
494
|
|
|
@@ -510,7 +526,11 @@ function hdiMigration( csn, options, beforeImage ) {
|
|
|
510
526
|
|
|
511
527
|
internalOptions.beta.sqlExtensions = true;
|
|
512
528
|
|
|
513
|
-
|
|
529
|
+
// Ignore constraint drops - that is handled by .hdbconstraint et. al.
|
|
530
|
+
const {
|
|
531
|
+
// eslint-disable-next-line no-unused-vars
|
|
532
|
+
deletions, migrations, constraintDeletions, ...hdbkinds
|
|
533
|
+
} = toSql.toSqlDdl(diff, internalOptions);
|
|
514
534
|
|
|
515
535
|
return {
|
|
516
536
|
afterImage,
|
package/lib/api/options.js
CHANGED
|
@@ -30,6 +30,7 @@ const publicOptionsNewAPI = [
|
|
|
30
30
|
'pre2134ReferentialConstraintNames',
|
|
31
31
|
'generatedByComment',
|
|
32
32
|
'betterSqliteSessionVariables',
|
|
33
|
+
'fewerLocalizedViews',
|
|
33
34
|
// ODATA
|
|
34
35
|
'odataOpenapiHints',
|
|
35
36
|
'odataVersion',
|
|
@@ -52,7 +53,6 @@ const privateOptions = [
|
|
|
52
53
|
// Not callable via cdsc, keep private for now until we are sure that we want this
|
|
53
54
|
'filterCsn',
|
|
54
55
|
'lintMode',
|
|
55
|
-
'fuzzyCsnError',
|
|
56
56
|
'traceFs',
|
|
57
57
|
'traceParser',
|
|
58
58
|
'traceParserAmb',
|
|
@@ -66,7 +66,7 @@ const privateOptions = [
|
|
|
66
66
|
'noRecompile',
|
|
67
67
|
'internalMsg',
|
|
68
68
|
'disableHanaComments', // in case of issues with hana comment rendering
|
|
69
|
-
'localizedWithoutCoalesce', // deprecated version of 'localizedLanguageFallback', TODO(
|
|
69
|
+
'localizedWithoutCoalesce', // deprecated version of 'localizedLanguageFallback', TODO(v5): Remove option
|
|
70
70
|
];
|
|
71
71
|
|
|
72
72
|
const overallOptions = publicOptionsNewAPI.concat(privateOptions);
|
package/lib/api/validate.js
CHANGED
|
@@ -115,7 +115,7 @@ const validators = {
|
|
|
115
115
|
found: val => `type ${ typeof val }`,
|
|
116
116
|
},
|
|
117
117
|
testMode: {
|
|
118
|
-
validate: val => typeof val === 'boolean' || typeof val === 'number',
|
|
118
|
+
validate: val => typeof val === 'boolean' || typeof val === 'number' || val === '$noAssertConsistency',
|
|
119
119
|
expected: () => 'type boolean|number',
|
|
120
120
|
found: val => `type ${ typeof val }`,
|
|
121
121
|
},
|
|
@@ -130,26 +130,28 @@ const validators = {
|
|
|
130
130
|
assertIntegrityType: generateStringValidator([ 'DB', 'RT' ]),
|
|
131
131
|
};
|
|
132
132
|
|
|
133
|
+
// Note: if `validate()` returns true, it means the option is _invalid_!
|
|
133
134
|
const allCombinationValidators = {
|
|
134
|
-
'valid-structured': {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
},
|
|
146
|
-
'beta-no-test': {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
getParameters: () => {},
|
|
150
|
-
getMessage: () => 'Option "beta" was used. This option should not be used in productive scenarios!',
|
|
135
|
+
'valid-structured': (options, message) => {
|
|
136
|
+
if (options.odataVersion === 'v2' && options.odataFormat === 'structured')
|
|
137
|
+
message.error('api-invalid-combination', null, { '#': 'valid-structured' });
|
|
138
|
+
},
|
|
139
|
+
'sql-dialect-and-naming': (options, message) => {
|
|
140
|
+
if (options.sqlDialect && options.sqlMapping && options.sqlDialect !== 'hana' && [ 'quoted', 'hdbcds' ].includes(options.sqlMapping))
|
|
141
|
+
message.error('api-invalid-combination', null, { '#': 'sql-dialect-and-naming', name: options.sqlDialect, prop: options.sqlMapping });
|
|
142
|
+
},
|
|
143
|
+
'sql-dialect-and-localized': (options, message) => {
|
|
144
|
+
if (options.fewerLocalizedViews && options.sqlDialect === 'hana')
|
|
145
|
+
message.error('api-invalid-combination', null, { '#': 'sql-dialect-and-localized', option: 'fewerLocalizedViews', value: 'hana' });
|
|
146
|
+
},
|
|
147
|
+
'beta-no-test': (options, message) => {
|
|
148
|
+
if (options.beta && !options.testMode)
|
|
149
|
+
message.warning('api-unexpected-combination', null, { '#': 'beta-no-test', option: 'beta' });
|
|
151
150
|
},
|
|
152
151
|
};
|
|
152
|
+
|
|
153
|
+
const alwaysRunValidators = [ 'beta-no-test', 'sql-dialect-and-localized' ];
|
|
154
|
+
|
|
153
155
|
/* eslint-disable jsdoc/no-undefined-types */
|
|
154
156
|
/**
|
|
155
157
|
* Run the validations for each option.
|
|
@@ -172,11 +174,12 @@ function validate( options, moduleName, customValidators = {}, combinationValida
|
|
|
172
174
|
const validator = customValidators[optionName] || validators[optionName] || booleanValidator;
|
|
173
175
|
|
|
174
176
|
if (!validator.validate(optionValue)) {
|
|
175
|
-
error('invalid-option', null, {
|
|
177
|
+
error('api-invalid-option', null, {
|
|
178
|
+
'#': 'value',
|
|
176
179
|
prop: optionName,
|
|
177
180
|
value: validator.expected(optionValue),
|
|
178
181
|
othervalue: validator.found(optionValue),
|
|
179
|
-
}
|
|
182
|
+
});
|
|
180
183
|
}
|
|
181
184
|
});
|
|
182
185
|
throwWithAnyError();
|
|
@@ -184,11 +187,8 @@ function validate( options, moduleName, customValidators = {}, combinationValida
|
|
|
184
187
|
|
|
185
188
|
const message = makeMessageFunction(null, options, moduleName);
|
|
186
189
|
|
|
187
|
-
for (const combinationValidatorName of combinationValidators.concat(
|
|
188
|
-
|
|
189
|
-
if (combinationValidator.validate(options))
|
|
190
|
-
message[combinationValidator.severity]('invalid-option-combination', null, combinationValidator.getParameters(options), combinationValidator.getMessage(options));
|
|
191
|
-
}
|
|
190
|
+
for (const combinationValidatorName of combinationValidators.concat(alwaysRunValidators))
|
|
191
|
+
allCombinationValidators[combinationValidatorName](options, message);
|
|
192
192
|
|
|
193
193
|
message.throwWithAnyError();
|
|
194
194
|
}
|
package/lib/base/location.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// but not semantic locations (which are message-specific),
|
|
5
5
|
|
|
6
6
|
const { copyPropIfExist } = require('../utils/objectUtils');
|
|
7
|
+
const { CsnLocation } = require('../compiler/classes');
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Create a location with properties `file`, `line` and `col` from argument
|
|
@@ -41,6 +42,7 @@ function combinedLocation( start, end ) {
|
|
|
41
42
|
*/
|
|
42
43
|
function emptyLocation( filename ) {
|
|
43
44
|
return {
|
|
45
|
+
__proto__: CsnLocation.prototype,
|
|
44
46
|
file: filename,
|
|
45
47
|
line: 1,
|
|
46
48
|
col: 1,
|
|
@@ -60,9 +62,12 @@ function emptyLocation( filename ) {
|
|
|
60
62
|
*/
|
|
61
63
|
function emptyWeakLocation( filename ) {
|
|
62
64
|
return {
|
|
65
|
+
__proto__: CsnLocation.prototype,
|
|
63
66
|
file: filename,
|
|
64
67
|
line: 1,
|
|
65
68
|
col: 1,
|
|
69
|
+
endLine: undefined,
|
|
70
|
+
endCol: undefined,
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
73
|
|
|
@@ -140,13 +145,7 @@ function dictLocation( dict, extraLocation ) {
|
|
|
140
145
|
const lineB = (b.endLine || b.line);
|
|
141
146
|
return (lineA > lineB || (lineA === lineB && (a.endCol || a.col) > (b.endCol || b.col)) ? a : b);
|
|
142
147
|
});
|
|
143
|
-
return
|
|
144
|
-
file: min.file,
|
|
145
|
-
line: min.line,
|
|
146
|
-
col: min.col,
|
|
147
|
-
endLine: max.endLine,
|
|
148
|
-
endCol: max.endCol,
|
|
149
|
-
};
|
|
148
|
+
return new CsnLocation( min.file, min.line, min.col, max.endLine, max.endCol );
|
|
150
149
|
}
|
|
151
150
|
|
|
152
151
|
function _objLocations( obj ) {
|