@sap/cds-compiler 3.1.2 → 3.3.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 +80 -3
- package/bin/cdsc.js +1 -1
- package/doc/CHANGELOG_BETA.md +18 -0
- package/lib/api/main.js +8 -13
- package/lib/base/error.js +2 -2
- package/lib/base/keywords.js +2 -24
- package/lib/base/message-registry.js +43 -14
- package/lib/base/messages.js +20 -10
- package/lib/base/model.js +1 -1
- package/lib/checks/actionsFunctions.js +1 -1
- package/lib/checks/annotationsOData.js +2 -2
- package/lib/checks/arrayOfs.js +15 -7
- package/lib/checks/cdsPersistence.js +1 -1
- package/lib/checks/checkForTypes.js +48 -0
- package/lib/checks/defaultValues.js +2 -2
- package/lib/checks/elements.js +81 -6
- package/lib/checks/foreignKeys.js +12 -13
- package/lib/checks/invalidTarget.js +10 -11
- package/lib/checks/managedInType.js +21 -15
- package/lib/checks/nullableKeys.js +1 -1
- package/lib/checks/onConditions.js +9 -9
- package/lib/checks/parameters.js +21 -0
- package/lib/checks/selectItems.js +1 -1
- package/lib/checks/types.js +2 -2
- package/lib/checks/utils.js +17 -7
- package/lib/checks/validator.js +26 -14
- package/lib/compiler/assert-consistency.js +13 -6
- package/lib/compiler/builtins.js +8 -0
- package/lib/compiler/checks.js +40 -33
- package/lib/compiler/define.js +50 -44
- package/lib/compiler/extend.js +303 -37
- package/lib/compiler/kick-start.js +2 -35
- package/lib/compiler/populate.js +83 -62
- package/lib/compiler/propagator.js +1 -1
- package/lib/compiler/resolve.js +61 -104
- package/lib/compiler/shared.js +16 -6
- package/lib/compiler/tweak-assocs.js +25 -12
- package/lib/compiler/utils.js +2 -2
- package/lib/edm/annotations/genericTranslation.js +3 -3
- package/lib/edm/csn2edm.js +10 -10
- package/lib/edm/edm.js +17 -9
- package/lib/edm/edmPreprocessor.js +53 -30
- package/lib/edm/edmUtils.js +7 -2
- package/lib/gen/Dictionary.json +14 -0
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +3 -2
- package/lib/gen/languageParser.js +4205 -4100
- package/lib/inspect/inspectModelStatistics.js +1 -1
- package/lib/inspect/inspectPropagation.js +23 -9
- package/lib/json/csnVersion.js +1 -1
- package/lib/json/from-csn.js +26 -19
- package/lib/json/to-csn.js +47 -5
- package/lib/language/antlrParser.js +1 -1
- package/lib/language/genericAntlrParser.js +29 -13
- package/lib/language/language.g4 +28 -8
- package/lib/main.d.ts +3 -6
- package/lib/model/.eslintrc.json +13 -0
- package/lib/model/api.js +4 -2
- package/lib/model/csnRefs.js +74 -47
- package/lib/model/csnUtils.js +236 -218
- package/lib/model/enrichCsn.js +41 -31
- package/lib/model/revealInternalProperties.js +61 -57
- package/lib/model/sortViews.js +31 -31
- package/lib/modelCompare/compare.js +6 -6
- package/lib/optionProcessor.js +5 -0
- package/lib/render/manageConstraints.js +2 -2
- package/lib/render/toCdl.js +31 -44
- package/lib/render/toHdbcds.js +7 -5
- package/lib/render/toRename.js +4 -4
- package/lib/render/toSql.js +11 -5
- package/lib/render/utils/common.js +20 -9
- package/lib/render/utils/sql.js +5 -5
- package/lib/transform/db/applyTransformations.js +32 -3
- package/lib/transform/db/expansion.js +81 -37
- package/lib/transform/db/flattening.js +1 -1
- package/lib/transform/db/temporal.js +1 -1
- package/lib/transform/db/transformExists.js +1 -1
- package/lib/transform/forOdataNew.js +10 -7
- package/lib/transform/{forHanaNew.js → forRelationalDB.js} +7 -7
- package/lib/transform/localized.js +28 -19
- package/lib/transform/odata/toFinalBaseType.js +8 -11
- package/lib/transform/odata/typesExposure.js +1 -1
- package/lib/transform/transformUtilsNew.js +101 -39
- package/lib/transform/translateAssocsToJoins.js +5 -4
- package/lib/utils/moduleResolve.js +5 -5
- package/lib/utils/objectUtils.js +3 -3
- package/package.json +2 -2
- package/share/messages/anno-duplicate-unrelated-layer.md +6 -6
- package/share/messages/check-proper-type-of.md +4 -4
- package/share/messages/check-proper-type.md +2 -2
- package/share/messages/duplicate-autoexposed.md +4 -4
- package/share/messages/extend-repeated-intralayer.md +4 -5
- package/share/messages/extend-unrelated-layer.md +4 -4
- package/share/messages/message-explanations.json +3 -1
- package/share/messages/redirected-to-ambiguous.md +7 -6
- package/share/messages/redirected-to-complex.md +63 -0
- package/share/messages/redirected-to-unrelated.md +6 -5
- package/share/messages/rewrite-not-supported.md +4 -4
- package/share/messages/syntax-expected-integer.md +3 -3
- package/share/messages/wildcard-excluding-one.md +37 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,81 @@
|
|
|
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.3.2 - 2022-09-30
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- to.edm(x): Set `Scale` (V4) or `@sap:variable-scale` (V2) attributes correctly when overwriting `cds.Decimal`
|
|
15
|
+
with `@odata.Scale`.
|
|
16
|
+
- to.sql: For dialect `postgres`, add braces around `$now`, `$at.from` and `$at.to`.
|
|
17
|
+
|
|
18
|
+
## Version 3.3.0 - 2022-09-29
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- Nested projections can be used without `beta` option:
|
|
23
|
+
+ Support `expand`: columns can look like `assoc_or_struct_or_tabalias { col_expression1, … }`,
|
|
24
|
+
`longer.ref as name { *, … } excluding { … }`, `{ col_expression1 as sub1, … } as name`, etc.
|
|
25
|
+
+ Support `inline`: columns can look like `assoc_or_struct_or_tabalias.{ col_expression1, … }`,
|
|
26
|
+
`longer.ref[filter = condition].{ *, … } excluding { … }`, `assoc_or_struct_or_tabalias.*`, etc.
|
|
27
|
+
- to.sql/hdi/hdbcds/edm(x)/for.odata: Allow to structure comparison against `is [not] null`.
|
|
28
|
+
- to.sql: Support dialect `postgres` - generates SQL intended for PostgreSQL. Not supported are `cds.hana` data types and views with parameters.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
|
|
32
|
+
- A valid redirection target does not depend on parameters anymore. This
|
|
33
|
+
change could induce a redirection error, which could easily solved by assigning
|
|
34
|
+
`@cds.redirection.target: false` to the entity with “non-matching” parameters.
|
|
35
|
+
- Properly issue an error when projecting associations with parameter
|
|
36
|
+
references in the `on` condition. Before this change, the compiler dumped
|
|
37
|
+
when projecting such an association in a view on top.
|
|
38
|
+
- Update OData vocabularies 'Capabilities', 'Common', 'UI'.
|
|
39
|
+
- to.cdl:
|
|
40
|
+
+ Extensions are now always put into property `model` of `to.cdl()`s result.
|
|
41
|
+
+ Actions on views and projections are now rendered as part of the definition, instead of an extension.
|
|
42
|
+
- to.edm(x): `@Capabilities` 'pull up' supports all counterpart properties of `@Capabilities.NavigationPropertyRestriction`
|
|
43
|
+
except for properties `NavigationProperty` and `Navigability`.
|
|
44
|
+
- to.hdi: Updated list of `keywords` which must be quoted in naming mode `plain`.
|
|
45
|
+
- to.sql/hdi/hdbcds/edm(x)/for.odata: Reject structure comparison with operators `<,>,<=,>=`. Message id `expr-unexpected-operator`
|
|
46
|
+
is downgradable to a warning.
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- Do not issue a warning anymore when adding elements via multiple `extend` statements in the same file.
|
|
51
|
+
- An info message for annotating builtins through `extend` statements is now reported, similar to `annotate`.
|
|
52
|
+
- Fix auto-redirection for target of new assoc in query entity
|
|
53
|
+
- for.odata: `@readonly/insertonly/mandatory: false` are not expanded.
|
|
54
|
+
|
|
55
|
+
## Version 3.2.0 - 2022-08-30
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- New Integer types with these mappings:
|
|
60
|
+
|
|
61
|
+
| CDS | OData | SQL | HANA CDS |
|
|
62
|
+
| --------- | --------- | -------- | ------------- |
|
|
63
|
+
| cds.UInt8 | Edm.Byte | TINYINT | hana.TINYINT |
|
|
64
|
+
| cds.Int16 | Edm.Int16 | SMALLINT | hana.SMALLINT |
|
|
65
|
+
| cds.Int32 | Edm.Int32 | INTEGER | cds.Integer |
|
|
66
|
+
| cds.Int64 | Edm.Int64 | BIGINT | cds.Integer64 |
|
|
67
|
+
|
|
68
|
+
- Properties of type definitions and types of direct elements can now be extended,
|
|
69
|
+
e.g. `extend T with (length: 10);`
|
|
70
|
+
|
|
71
|
+
- CDL parser: support SQL function `substr_regexpr` with its special argument syntax.
|
|
72
|
+
|
|
73
|
+
### Fixed
|
|
74
|
+
|
|
75
|
+
- An internal dump could have occurred in certain situations
|
|
76
|
+
for models with cyclic type definitions.
|
|
77
|
+
- Annotations on inferred enum elements of views were lost during recompilation.
|
|
78
|
+
- to.cdl: Annotations on enum value in query elements were lost.
|
|
79
|
+
- for.odata: Allow dynamic shortcut annotation values (`$edmJson`).
|
|
80
|
+
- to.edm(x):
|
|
81
|
+
+ Don't overwrite annotations of input model.
|
|
82
|
+
+ Ignore `null` values in `$edmJson` strings.
|
|
83
|
+
- to.hdi.migration: Don't interpret bound action changes as element changes.
|
|
84
|
+
|
|
10
85
|
## Version 3.1.2 - 2022-08-19
|
|
11
86
|
|
|
12
87
|
### Fixed
|
|
@@ -25,8 +100,8 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
25
100
|
`extend SomeEntity with FirstInclude, SecondInclude;`
|
|
26
101
|
- Aspects can now have actions and functions, similar to entities. Aspects can be extended by actions as well.
|
|
27
102
|
- `cdsc`:
|
|
28
|
-
|
|
29
|
-
|
|
103
|
+
+ `toCsn` now supports `--with-locations` which adds a `$location` property to artifacts
|
|
104
|
+
+ `toHana`/`toSql` now supports `--disable-hana-comments`, which disables rendering of doc-comments for HANA.
|
|
30
105
|
- to.hdi/sql/hdbcds: Support FK-access in `ORDER BY` and `GROUP BY`
|
|
31
106
|
- to.hdi.migration: Detect an implicit change from `not null` to `null` and render corresponding `ALTER`
|
|
32
107
|
|
|
@@ -51,8 +126,10 @@ The compiler behavior concerning `beta` features can change at any time without
|
|
|
51
126
|
- compiler:
|
|
52
127
|
+ `cast(elem as EnumType)` crashed the compiler.
|
|
53
128
|
+ Annotations on sub-elements in query entities were lost during re-compilation.
|
|
54
|
-
+ An association's cardinality was lost for associations published in projections.
|
|
129
|
+
+ An association's cardinality was lost for new associations published in projections.
|
|
55
130
|
+ Annotations on indirect action parameters were lost in CSN flavor `gensrc`.
|
|
131
|
+
+ Re-allow `annotate` statements referring to the same element twice,
|
|
132
|
+
even if there are annotation assignments for sub elements.
|
|
56
133
|
+ If a file's content starts with `{` and if neither file extension is known nor
|
|
57
134
|
`fallbackParser` is set, assume the source is CSN.
|
|
58
135
|
- all backends: references in `order by` _expressions_ are correctly resolved.
|
package/bin/cdsc.js
CHANGED
|
@@ -409,7 +409,7 @@ function executeCommandLine(command, options, args) {
|
|
|
409
409
|
}
|
|
410
410
|
else {
|
|
411
411
|
const sqlResult = main.to.sql(csn, options);
|
|
412
|
-
writeToFileOrDisplay(options.out, 'model.sql', sqlResult.join('\n'), true);
|
|
412
|
+
writeToFileOrDisplay(options.out, 'model.sql', sqlResult.join('\n\n'), true);
|
|
413
413
|
}
|
|
414
414
|
return model;
|
|
415
415
|
}
|
package/doc/CHANGELOG_BETA.md
CHANGED
|
@@ -8,6 +8,24 @@ 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 3.3.0 - 2022-09-29
|
|
12
|
+
|
|
13
|
+
### Removed `nestedProjections`
|
|
14
|
+
|
|
15
|
+
- This is now the default - see CHANGELOG entry for 3.3.0.
|
|
16
|
+
|
|
17
|
+
### Fixed `nestedProjections`
|
|
18
|
+
|
|
19
|
+
- Issue an error for an unexpected `as ‹alias›` for references with `inline`;
|
|
20
|
+
people likely have confused `inline` with `expand`.
|
|
21
|
+
- Resolving references in the user-provided `on` condition of projected or newly-defined
|
|
22
|
+
associations inside `expand` and `inline` now works correctly.
|
|
23
|
+
- Correct `key` propagation for references with `expand` or `inline`.
|
|
24
|
+
- If an element is projected with sibling `expand`, the original data structure is usually
|
|
25
|
+
_not preserved_ (why use an `expand` if it is?). Therefore, the compiler cannot auto-rewrite
|
|
26
|
+
the `on` condition of unmanaged associations if such an element is referred to in the original
|
|
27
|
+
`on` condition. In that case, provide your own via `…: redirected to … on ‹condition›`.
|
|
28
|
+
|
|
11
29
|
## Version 3.1.0 - 2022-08-04
|
|
12
30
|
|
|
13
31
|
### Added `optionalActionFunctionParameters`
|
package/lib/api/main.js
CHANGED
|
@@ -15,7 +15,7 @@ const modelCompare = lazyload('../modelCompare/compare');
|
|
|
15
15
|
const sortViews = lazyload('../model/sortViews');
|
|
16
16
|
const csnUtils = lazyload('../model/csnUtils');
|
|
17
17
|
const timetrace = lazyload('../utils/timetrace');
|
|
18
|
-
const
|
|
18
|
+
const forRelationalDB = lazyload('../transform/forRelationalDB');
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Return the artifact name for use for the hdbresult object
|
|
@@ -93,12 +93,12 @@ function checkPreTransformedCsn(csn, options, relevantOptionNames, warnAboutMism
|
|
|
93
93
|
|
|
94
94
|
for (const name of relevantOptionNames ) {
|
|
95
95
|
if (options[name] !== csn.meta.options[name])
|
|
96
|
-
error('wrong-pretransformed-csn', null, `Expected pre-processed CSN to have option "${ name }" set to "${ options[name] }". Found: "${ csn.meta.options[name] }"`);
|
|
96
|
+
error('wrong-pretransformed-csn', null, {}, `Expected pre-processed CSN to have option "${ name }" set to "${ options[name] }". Found: "${ csn.meta.options[name] }"`);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
for (const name of warnAboutMismatch ) {
|
|
100
100
|
if (options[name] !== csn.meta.options[name])
|
|
101
|
-
warning('options-mismatch-pretransformed-csn', null, `Expected pre-processed CSN to have option "${ name }" set to "${ options[name] }". Found: "${ csn.meta.options[name] }"`);
|
|
101
|
+
warning('options-mismatch-pretransformed-csn', null, {}, `Expected pre-processed CSN to have option "${ name }" set to "${ options[name] }". Found: "${ csn.meta.options[name] }"`);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
throwWithAnyError();
|
|
@@ -147,7 +147,7 @@ function odata(csn, options = {}) {
|
|
|
147
147
|
*
|
|
148
148
|
* @param {object} csn CSN to process
|
|
149
149
|
* @param {object} [externalOptions={}] Options
|
|
150
|
-
* @returns {object} { model: string,
|
|
150
|
+
* @returns {object} { model: string, namespace: string }
|
|
151
151
|
*/
|
|
152
152
|
function cdl(csn, externalOptions = {}) {
|
|
153
153
|
const internalOptions = prepareOptions.to.cdl(externalOptions);
|
|
@@ -165,7 +165,7 @@ function cdl(csn, externalOptions = {}) {
|
|
|
165
165
|
function forSql(csn, options = {}) {
|
|
166
166
|
const internalOptions = prepareOptions.to.sql(options);
|
|
167
167
|
internalOptions.transformation = 'sql';
|
|
168
|
-
const transformedCsn =
|
|
168
|
+
const transformedCsn = forRelationalDB.transformForRelationalDBWithCsn(csn, internalOptions, 'to.sql');
|
|
169
169
|
|
|
170
170
|
return internalOptions.testMode ? toCsn.sortCsn(transformedCsn, internalOptions) : transformedCsn;
|
|
171
171
|
}
|
|
@@ -180,7 +180,7 @@ function forSql(csn, options = {}) {
|
|
|
180
180
|
function forHdi(csn, options = {}) {
|
|
181
181
|
const internalOptions = prepareOptions.to.hdi(options);
|
|
182
182
|
internalOptions.transformation = 'sql';
|
|
183
|
-
const transformedCsn =
|
|
183
|
+
const transformedCsn = forRelationalDB.transformForRelationalDBWithCsn(csn, internalOptions, 'to.hdi');
|
|
184
184
|
|
|
185
185
|
return internalOptions.testMode ? toCsn.sortCsn(transformedCsn, internalOptions) : transformedCsn;
|
|
186
186
|
}
|
|
@@ -196,7 +196,7 @@ function forHdbcds(csn, options = {}) {
|
|
|
196
196
|
const internalOptions = prepareOptions.to.hdbcds(options);
|
|
197
197
|
internalOptions.transformation = 'hdbcds';
|
|
198
198
|
|
|
199
|
-
const hanaCsn =
|
|
199
|
+
const hanaCsn = forRelationalDB.transformForRelationalDBWithCsn(csn, internalOptions, 'to.hdbcds');
|
|
200
200
|
|
|
201
201
|
return internalOptions.testMode ? toCsn.sortCsn(hanaCsn, internalOptions) : hanaCsn;
|
|
202
202
|
}
|
|
@@ -212,11 +212,6 @@ function sql(csn, options = {}) {
|
|
|
212
212
|
const internalOptions = prepareOptions.to.sql(options);
|
|
213
213
|
internalOptions.transformation = 'sql';
|
|
214
214
|
|
|
215
|
-
const { error } = messages.makeMessageFunction(csn, internalOptions, 'for.odata');
|
|
216
|
-
|
|
217
|
-
if (internalOptions.sqlDialect === 'postgres' && !baseModel.isBetaEnabled(internalOptions, 'postgres'))
|
|
218
|
-
error(null, null, 'sqlDialect: \'postgres\' is only supported with beta-flag \'postgres\'');
|
|
219
|
-
|
|
220
215
|
// we need the CSN for view sorting
|
|
221
216
|
const transformedCsn = forSql(csn, options);
|
|
222
217
|
const sqls = toSql.toSqlDdl(transformedCsn, internalOptions);
|
|
@@ -514,7 +509,7 @@ function edmall(csn, options = {}) {
|
|
|
514
509
|
const { error } = messages.makeMessageFunction(csn, internalOptions, 'for.odata');
|
|
515
510
|
|
|
516
511
|
if (internalOptions.odataVersion === 'v2')
|
|
517
|
-
error(null, null, 'OData JSON output is not available for OData V2');
|
|
512
|
+
error(null, null, {}, 'OData JSON output is not available for OData V2');
|
|
518
513
|
|
|
519
514
|
const result = {};
|
|
520
515
|
let oDataCsn = csn;
|
package/lib/base/error.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
class CompilerAssertion extends Error {
|
|
8
8
|
constructor(message) {
|
|
9
|
-
super(message);
|
|
9
|
+
super(`cds-compiler assertion failed: ${message}`);
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -16,7 +16,7 @@ class CompilerAssertion extends Error {
|
|
|
16
16
|
*/
|
|
17
17
|
class ModelError extends Error {
|
|
18
18
|
constructor(message) {
|
|
19
|
-
super(message);
|
|
19
|
+
super(`cds-compiler model error: ${message}`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
package/lib/base/keywords.js
CHANGED
|
@@ -188,10 +188,7 @@ module.exports = {
|
|
|
188
188
|
'WITHOUT'
|
|
189
189
|
],
|
|
190
190
|
// SAP HANA keywords, used for smart quoting in to-hdi.plain
|
|
191
|
-
//
|
|
192
|
-
// Better use keywords in ptime/query/parser/syntax/qp_keyword.cc minus those
|
|
193
|
-
// in rule unreserved_keyword_column (=…_common - 'CONSTRAINT') in
|
|
194
|
-
// ptime/query/parser/syntax/qp_gram.y of the HANA sources.
|
|
191
|
+
// See './scripts/keywords/hana/generateSqlKeywords.js'
|
|
195
192
|
hana: [
|
|
196
193
|
'ABAPITAB',
|
|
197
194
|
'ABAPSTRUCT',
|
|
@@ -215,12 +212,10 @@ module.exports = {
|
|
|
215
212
|
'ADD_MONTHS',
|
|
216
213
|
'ADD_SECONDS',
|
|
217
214
|
'ADD_YEARS',
|
|
218
|
-
'ADJACENCY',
|
|
219
215
|
'ADOPT',
|
|
220
216
|
'ALL',
|
|
221
217
|
'ALPHANUM',
|
|
222
218
|
'ALTER',
|
|
223
|
-
'ANALYTIC',
|
|
224
219
|
'ANY',
|
|
225
220
|
'APPLY_FILTER',
|
|
226
221
|
'ARRAY',
|
|
@@ -397,7 +392,6 @@ module.exports = {
|
|
|
397
392
|
'DISTANCE',
|
|
398
393
|
'DISTINCT',
|
|
399
394
|
'DOUBLE',
|
|
400
|
-
'DW_OPTIMIZED',
|
|
401
395
|
'ELSE',
|
|
402
396
|
'ELSEIF',
|
|
403
397
|
'EMPTY',
|
|
@@ -411,12 +405,9 @@ module.exports = {
|
|
|
411
405
|
'FALSE',
|
|
412
406
|
'FILTER',
|
|
413
407
|
'FIRST_VALUE',
|
|
414
|
-
'FLATTEN',
|
|
415
408
|
'FLOAT',
|
|
416
409
|
'FLOOR',
|
|
417
410
|
'FOR',
|
|
418
|
-
'FORCE_FIRST_PASSWORD_CHANGE',
|
|
419
|
-
'FREESTYLESEARCHATTRIBUTE',
|
|
420
411
|
'FROM',
|
|
421
412
|
'FULL',
|
|
422
413
|
'GET_NUM_SERVERS',
|
|
@@ -515,7 +506,6 @@ module.exports = {
|
|
|
515
506
|
'NUMBER',
|
|
516
507
|
'NUMERIC',
|
|
517
508
|
'NVARCHAR',
|
|
518
|
-
'OBJECT',
|
|
519
509
|
'OCCURRENCES_REGEXPR',
|
|
520
510
|
'OF',
|
|
521
511
|
'OLYMP',
|
|
@@ -640,16 +630,11 @@ module.exports = {
|
|
|
640
630
|
'SYSTEM_TIME',
|
|
641
631
|
'SYSUUID',
|
|
642
632
|
'TABLE',
|
|
643
|
-
'TABLES',
|
|
644
633
|
'TABLESAMPLE',
|
|
645
634
|
'TAN',
|
|
646
635
|
'TANH',
|
|
647
|
-
'TARGET',
|
|
648
|
-
'TEMPORARY',
|
|
649
636
|
'TEXT',
|
|
650
637
|
'TEXT_FILTER',
|
|
651
|
-
'THEN',
|
|
652
|
-
'THREAD',
|
|
653
638
|
'TIME',
|
|
654
639
|
'TIMELINE',
|
|
655
640
|
'TIMESTAMP',
|
|
@@ -662,11 +647,8 @@ module.exports = {
|
|
|
662
647
|
'TM_GET_RELEVANT_DOCUMENTS',
|
|
663
648
|
'TM_GET_RELEVANT_TERMS',
|
|
664
649
|
'TM_GET_SUGGESTED_TERMS',
|
|
665
|
-
'
|
|
666
|
-
'TOOLOPTION',
|
|
650
|
+
'TO',
|
|
667
651
|
'TOP',
|
|
668
|
-
'TOPK',
|
|
669
|
-
'TOTAL',
|
|
670
652
|
'TO_BIGINT',
|
|
671
653
|
'TO_BINARY',
|
|
672
654
|
'TO_BLOB',
|
|
@@ -694,11 +676,7 @@ module.exports = {
|
|
|
694
676
|
'TO_VARBINARY',
|
|
695
677
|
'TO_VARCHAR',
|
|
696
678
|
'TRACE',
|
|
697
|
-
'TRACEPROFILE',
|
|
698
|
-
'TRACES',
|
|
699
679
|
'TRAILING',
|
|
700
|
-
'TRANSACTION',
|
|
701
|
-
'TREE',
|
|
702
680
|
'TRIGGER_UPDATE_COLUMN',
|
|
703
681
|
'TRIM',
|
|
704
682
|
'TRUE',
|
|
@@ -97,6 +97,9 @@ const centralMessages = {
|
|
|
97
97
|
'extend-repeated-intralayer': { severity: 'Warning' },
|
|
98
98
|
'extend-unrelated-layer': { severity: 'Warning' },
|
|
99
99
|
|
|
100
|
+
'ext-duplicate-extend-type': { severity: 'Error' },
|
|
101
|
+
'ext-duplicate-extend-type-unrelated-layer': { severity: 'Error', configurableFor: true },
|
|
102
|
+
|
|
100
103
|
'param-default': { severity: 'Error', configurableFor: 'deprecated' }, // not supported yet
|
|
101
104
|
|
|
102
105
|
'query-undefined-element': { severity: 'Error' },
|
|
@@ -115,7 +118,8 @@ const centralMessages = {
|
|
|
115
118
|
'ref-undefined-var': { severity: 'Error' },
|
|
116
119
|
'ref-undefined-element': { severity: 'Error' },
|
|
117
120
|
'ref-unknown-var': { severity: 'Info', errorFor: [ 'to.hdbcds', 'to.sql', 'to.hdi', 'to.rename' ] },
|
|
118
|
-
'ref-obsolete-parameters': { severity: 'Error', configurableFor: true },
|
|
121
|
+
'ref-obsolete-parameters': { severity: 'Error', configurableFor: true },
|
|
122
|
+
// does not hurt us, but makes it tedious to detect parameter refs
|
|
119
123
|
'ref-undefined-param': { severity: 'Error' },
|
|
120
124
|
'ref-rejected-on': { severity: 'Error' },
|
|
121
125
|
'ref-expected-element': { severity: 'Error' },
|
|
@@ -131,6 +135,8 @@ const centralMessages = {
|
|
|
131
135
|
'service-nested-context': { severity: 'Error', configurableFor: true }, // does not hurt compile, TODO
|
|
132
136
|
'service-nested-service': { severity: 'Error', configurableFor: 'deprecated' }, // not supported yet
|
|
133
137
|
|
|
138
|
+
'expr-unexpected-operator': { severity: 'Error', configurableFor: true },
|
|
139
|
+
|
|
134
140
|
// 'syntax-duplicate-annotate' came late with v3 - make it configurable as
|
|
135
141
|
// fallback, but then parse.cdl is not supposed to work correctly (it can
|
|
136
142
|
// then either issue an error or produce a CSN missing some annotations):
|
|
@@ -162,9 +168,18 @@ const centralMessages = {
|
|
|
162
168
|
'unexpected-keys-for-composition': { severity: 'Error' }, // TODO: more than 30 chars
|
|
163
169
|
'unmanaged-as-key': { severity: 'Error', configurableFor: 'deprecated' }, // is confusing
|
|
164
170
|
'composition-as-key': { severity: 'Error', configurableFor: 'deprecated' }, // is confusing and not supported
|
|
165
|
-
|
|
171
|
+
// Published! Used in @sap/cds-odata-v2-adapter-proxy; if renamed, add to oldMessageIds
|
|
172
|
+
'odata-spec-violation-array': { severity: 'Warning' }, // more than 30 chars
|
|
173
|
+
// Published! Used in @sap/cds-odata-v2-adapter-proxy; if renamed, add to oldMessageIds
|
|
174
|
+
'odata-spec-violation-assoc': { severity: 'Warning' }, // more than 30 chars
|
|
175
|
+
// Published! Used in @sap/cds-odata-v2-adapter-proxy; if renamed, add to oldMessageIds
|
|
166
176
|
'odata-spec-violation-constraints': { severity: 'Info' }, // more than 30 chars
|
|
167
177
|
'odata-spec-violation-id': { severity: 'Error', configurableFor: true },
|
|
178
|
+
'odata-spec-violation-namespace': { severity: 'Warning' }, // more than 30 chars
|
|
179
|
+
// Published! Used in @sap/cds-odata-v2-adapter-proxy; if renamed, add to oldMessageIds
|
|
180
|
+
'odata-spec-violation-param': { severity: 'Warning' }, // more than 30 chars
|
|
181
|
+
// Published! Used in @sap/cds-odata-v2-adapter-proxy; if renamed, add to oldMessageIds
|
|
182
|
+
'odata-spec-violation-returns': { severity: 'Warning' }, // more than 30 chars
|
|
168
183
|
'odata-spec-violation-type': { severity: 'Error', configurableFor: true },
|
|
169
184
|
'odata-spec-violation-type-unknown': { severity: 'Warning' },
|
|
170
185
|
'odata-spec-violation-no-key': { severity: 'Warning' },
|
|
@@ -180,15 +195,6 @@ const centralMessages = {
|
|
|
180
195
|
// The keys will be added to `oldNames` of the new message, which is used for reclassification.
|
|
181
196
|
const oldMessageIds = createDict({
|
|
182
197
|
'old-anno-duplicate': 'anno-duplicate', // Example
|
|
183
|
-
|
|
184
|
-
// These IDs are used by large stakeholders. If we change them, we should
|
|
185
|
-
// be backward-compatible.
|
|
186
|
-
// 'redirected-to-complex': 'TODO',
|
|
187
|
-
// 'wildcard-excluding-one': 'TODO',
|
|
188
|
-
// 'wildcard-excluding-many': 'TODO',
|
|
189
|
-
// 'assoc-outside-service': 'TODO',
|
|
190
|
-
// 'redirected-to-same': 'TODO',
|
|
191
|
-
// 'query-navigate-many': 'TODO',
|
|
192
198
|
});
|
|
193
199
|
|
|
194
200
|
// Set up the old-to-new message ID mapping in the message registry.
|
|
@@ -209,6 +215,8 @@ for (const oldName in oldMessageIds) {
|
|
|
209
215
|
// For messageIds, where no text has been provided via code (central def)
|
|
210
216
|
const centralMessageTexts = {
|
|
211
217
|
'api-invalid-option': {
|
|
218
|
+
// TODO: too many different error situations for one message id,
|
|
219
|
+
// TODO: use message parameter - do not use quotes in message texts
|
|
212
220
|
std: 'Option $(NAME) is no longer supported! Use SNAPI options instead',
|
|
213
221
|
magicVars: 'Option “magicVars” is no longer supported! Use “variableReplacements” instead. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
|
|
214
222
|
user: 'Option “variableReplacements” expects “$user” instead of “user”. See <https://cap.cloud.sap/docs/guides/databases#configuring-variables> for details',
|
|
@@ -232,7 +240,7 @@ const centralMessageTexts = {
|
|
|
232
240
|
'flatten-fkey-exists': 'Generated foreign key element $(NAME) for association $(ART) conflicts with existing element',
|
|
233
241
|
},
|
|
234
242
|
|
|
235
|
-
'syntax-anno
|
|
243
|
+
'syntax-ignoring-anno': {
|
|
236
244
|
std: 'Annotations can\'t be used at prefix references',
|
|
237
245
|
doc: 'Doc comments can\'t be used at prefix references',
|
|
238
246
|
},
|
|
@@ -403,12 +411,32 @@ const centralMessageTexts = {
|
|
|
403
411
|
'expected-entity': 'An entity, projection or view is expected here',
|
|
404
412
|
'expected-struct': 'A type, entity, aspect or event with direct elements is expected here',
|
|
405
413
|
'expected-type': 'A type or an element is expected here',
|
|
406
|
-
//
|
|
414
|
+
// TODO: text variant if the association does not start an entity
|
|
407
415
|
'expected-source': 'A query source must be an entity or an association',
|
|
408
416
|
'expected-target': 'An entity or an aspect is expected here',
|
|
409
417
|
'extend-columns': 'Artifact $(ART) can\'t be extended with columns, only projections can',
|
|
410
418
|
'extend-repeated-intralayer': 'Unstable element order due to repeated extensions in same layer',
|
|
411
419
|
|
|
420
|
+
|
|
421
|
+
'ext-duplicate-extend-type': 'Duplicate type extension for type $(TYPE)',
|
|
422
|
+
'ext-duplicate-extend-type-unrelated-layer': 'Duplicate type extension for type $(TYPE)',
|
|
423
|
+
'ext-invalid-type-property': {
|
|
424
|
+
std: 'Property $(PROP) can only be extended',
|
|
425
|
+
'new-prop': 'Property $(PROP) can only be extended, not added',
|
|
426
|
+
// eslint-disable-next-line max-len
|
|
427
|
+
smaller: 'Property $(PROP) can only be extended, but $(LITERAL) is smaller than $(NUMBER) of type definition',
|
|
428
|
+
// eslint-disable-next-line max-len
|
|
429
|
+
'ext-smaller': 'Property $(PROP) can only be extended, but extended value $(LITERAL) is smaller than $(NUMBER) from previous type extension',
|
|
430
|
+
prop: 'Type property $(PROP) can\'t be extended',
|
|
431
|
+
scale: 'If property $(PROP) is increased, then so must $(OTHERPROP)',
|
|
432
|
+
string: 'Only numerical properties can be extended, but found string for $(PROP)',
|
|
433
|
+
},
|
|
434
|
+
'ref-expected-scalar-type': {
|
|
435
|
+
std: 'Only scalar type definitions can be extended with type properties',
|
|
436
|
+
unsupported: 'Only integer-, decimal-, binary-, and string-types can be extended but found $(PROP)',
|
|
437
|
+
inferred: 'Only direct types can be extended',
|
|
438
|
+
},
|
|
439
|
+
|
|
412
440
|
'query-unexpected-assoc-hdbcds': 'Publishing a managed association in a view is not possible for “hdbcds” naming mode',
|
|
413
441
|
'query-unexpected-structure-hdbcds': 'Publishing a structured element in a view is not possible for “hdbcds” naming mode',
|
|
414
442
|
'query-ignoring-param-nullability': {
|
|
@@ -477,9 +505,10 @@ const centralMessageTexts = {
|
|
|
477
505
|
},
|
|
478
506
|
'odata-navigation': {
|
|
479
507
|
std: 'No OData navigation property generated, target $(TARGET) is outside of service $(SERVICE)',
|
|
480
|
-
oncond: 'No OData navigation property generated for association with arbitrary ON
|
|
508
|
+
oncond: 'No OData navigation property generated for association with arbitrary ON-condition and target $(TARGET) outside of service $(SERVICE)'
|
|
481
509
|
},
|
|
482
510
|
'odata-parameter-order': 'Unexpected mandatory after optional parameter',
|
|
511
|
+
'odata-key-recursive': 'Unexpected recursive key $(NAME)',
|
|
483
512
|
}
|
|
484
513
|
|
|
485
514
|
/**
|
package/lib/base/messages.js
CHANGED
|
@@ -136,14 +136,11 @@ class CompileMessage {
|
|
|
136
136
|
this.location = location;
|
|
137
137
|
this.$location = { ...this.location, address: undefined };
|
|
138
138
|
this.validNames = null;
|
|
139
|
-
|
|
140
|
-
this.home = home;
|
|
139
|
+
this.home = home; // semantic location, e.g. 'entity:"E"/element:"x"'
|
|
141
140
|
this.severity = severity;
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (moduleName)
|
|
146
|
-
Object.defineProperty( this, '$module', { value: moduleName, configurable: true } );
|
|
141
|
+
Object.defineProperty( this, 'messageId', { value: id } );
|
|
142
|
+
// this.messageId = id; // ids not yet finalized
|
|
143
|
+
Object.defineProperty( this, '$module', { value: moduleName, configurable: true } );
|
|
147
144
|
}
|
|
148
145
|
|
|
149
146
|
toString() { // should have no argument...
|
|
@@ -676,6 +673,7 @@ const paramsTransform = {
|
|
|
676
673
|
elemref: transformElementRef,
|
|
677
674
|
type: transformArg,
|
|
678
675
|
offending: tokenSymbol,
|
|
676
|
+
op: quote.prop,
|
|
679
677
|
expecting: transformManyWith( tokenSymbol ),
|
|
680
678
|
// msg: m => m,
|
|
681
679
|
$reviewed: ignoreTextTransform,
|
|
@@ -801,6 +799,7 @@ function messageText( texts, params, transform ) {
|
|
|
801
799
|
}
|
|
802
800
|
|
|
803
801
|
function replaceInString( text, params ) {
|
|
802
|
+
const usedParams = [ '#', '$reviewed' ];
|
|
804
803
|
let pattern = /\$\(([A-Z_]+)\)/g;
|
|
805
804
|
let parts = [];
|
|
806
805
|
let start = 0;
|
|
@@ -808,11 +807,11 @@ function replaceInString( text, params ) {
|
|
|
808
807
|
let prop = p[1].toLowerCase();
|
|
809
808
|
parts.push( text.substring( start, p.index ),
|
|
810
809
|
(prop in params ? params[prop] : p[0]) );
|
|
811
|
-
|
|
810
|
+
usedParams.push(prop);
|
|
812
811
|
start = pattern.lastIndex;
|
|
813
812
|
}
|
|
814
813
|
parts.push( text.substring( start ) );
|
|
815
|
-
let remain = (params['#']) ? [] : Object.keys( params ).filter( n =>
|
|
814
|
+
let remain = (params['#']) ? [] : Object.keys( params ).filter( n => !usedParams.includes(n) );
|
|
816
815
|
return (remain.length)
|
|
817
816
|
? parts.join('') + '; ' +
|
|
818
817
|
remain.map( n => n.toUpperCase() + ' = ' + params[n] ).join(', ')
|
|
@@ -1024,6 +1023,7 @@ function compareMessage( a, b ) {
|
|
|
1024
1023
|
c( aEnd.endLine, bEnd.endLine ) ||
|
|
1025
1024
|
c( aEnd.endCol, bEnd.endCol ) ||
|
|
1026
1025
|
c( homeSortName( a ), homeSortName( b ) ) ||
|
|
1026
|
+
// TODO: severities?
|
|
1027
1027
|
c( a.message, b.message ) );
|
|
1028
1028
|
}
|
|
1029
1029
|
else if (!aFile && !bFile)
|
|
@@ -1172,7 +1172,9 @@ function homeNameForExtend( art ) {
|
|
|
1172
1172
|
|
|
1173
1173
|
// Surrounding parent may be another extension.
|
|
1174
1174
|
const parent = art._parent;
|
|
1175
|
-
if (!parent)
|
|
1175
|
+
if (!parent && art.name.absolute)
|
|
1176
|
+
return kind + ':' + artName(removeBlock(art));
|
|
1177
|
+
else if (!parent)
|
|
1176
1178
|
return kind + ':' + quoted(absoluteName);
|
|
1177
1179
|
|
|
1178
1180
|
if (art.name.param && parent.params) {
|
|
@@ -1199,6 +1201,14 @@ function homeNameForExtend( art ) {
|
|
|
1199
1201
|
}
|
|
1200
1202
|
// This case should not happen, but just in case
|
|
1201
1203
|
return kind + ':' + artName(parent);
|
|
1204
|
+
|
|
1205
|
+
/**
|
|
1206
|
+
* Remove `select` from the 'art's name to avoid `block:1` in artName().
|
|
1207
|
+
* @TODO: Refactor homeNameForExtend (and possibly artName) to get rid of this function
|
|
1208
|
+
**/
|
|
1209
|
+
function removeBlock(obj) {
|
|
1210
|
+
return { ...obj, name: { ...obj.name, select: null } };
|
|
1211
|
+
}
|
|
1202
1212
|
}
|
|
1203
1213
|
|
|
1204
1214
|
function constructSemanticLocationFromCsnPath(csnPath, model) {
|
package/lib/base/model.js
CHANGED
|
@@ -26,8 +26,8 @@ const availableBetaFlags = {
|
|
|
26
26
|
hanaAssocRealCardinality: true,
|
|
27
27
|
mapAssocToJoinCardinality: true,
|
|
28
28
|
ignoreAssocPublishingInUnion: true,
|
|
29
|
-
nestedProjections: true,
|
|
30
29
|
enableUniversalCsn: true,
|
|
30
|
+
postgres: true,
|
|
31
31
|
// disabled by --beta-mode
|
|
32
32
|
nestedServices: false,
|
|
33
33
|
odataOpenType: true,
|
|
@@ -22,7 +22,7 @@ function checkActionOrFunction(art, artName, prop, path) {
|
|
|
22
22
|
|
|
23
23
|
const serviceName = this.csnUtils.getServiceName(artName);
|
|
24
24
|
if (!serviceName)
|
|
25
|
-
this.warning(null, path, `Functions and actions must be declared in a service`);
|
|
25
|
+
this.warning(null, path, {}, `Functions and actions must be declared in a service`);
|
|
26
26
|
|
|
27
27
|
if (art.kind === 'entity') {
|
|
28
28
|
for (const [ actName, act ] of Object.entries(art.actions)) {
|
|
@@ -36,7 +36,7 @@ function checkCoreMediaTypeAllowence(member) {
|
|
|
36
36
|
*/
|
|
37
37
|
function checkAnalytics(member) {
|
|
38
38
|
if (member['@Analytics.Measure'] && !member['@Aggregation.default']) {
|
|
39
|
-
this.info(null, member.$path,
|
|
39
|
+
this.info(null, member.$path, {},
|
|
40
40
|
'Annotation “@Analytics.Measure” expects “@Aggregation.default” to be assigned for the same element as well');
|
|
41
41
|
}
|
|
42
42
|
}
|
|
@@ -63,7 +63,7 @@ function checkReadOnlyAndInsertOnly(artifact, artifactName) {
|
|
|
63
63
|
if (!this.csnUtils.getServiceName(artifactName))
|
|
64
64
|
return;
|
|
65
65
|
if (artifact.kind === 'entity' && artifact['@readonly'] && artifact['@insertonly'])
|
|
66
|
-
this.warning(null, artifact.$path, 'Annotations “@readonly” and “@insertonly” can\'t be assigned in combination');
|
|
66
|
+
this.warning(null, artifact.$path, {}, 'Annotations “@readonly” and “@insertonly” can\'t be assigned in combination');
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
module.exports = {
|
package/lib/checks/arrayOfs.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { setProp } = require('../base/model');
|
|
4
|
+
|
|
3
5
|
// Only to be used with validator.js - a correct `this` value needs to be provided!
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -24,20 +26,26 @@ function validateAssociationsInItems(member) {
|
|
|
24
26
|
if (element.on) { // Unmanaged association
|
|
25
27
|
// Unmanaged associations are always forbidden for now
|
|
26
28
|
// TODO: Check if the on-condition only references things inside of the .items
|
|
27
|
-
this.error(null, member.$path, 'Unmanaged associations in "array of" or "many" are not allowed');
|
|
29
|
+
this.error(null, member.$path, {}, 'Unmanaged associations in "array of" or "many" are not allowed');
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
}
|
|
32
34
|
};
|
|
33
35
|
if (this.artifact && ( this.artifact.kind === 'entity' || this.artifact.query ) && member && member.items && member.$path[2] === 'elements') {
|
|
34
|
-
if (member.items.type
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
if (member.items.type) {
|
|
37
|
+
const type = member.items.type.ref
|
|
38
|
+
? this.artifactRef(member.items.type)
|
|
39
|
+
: this.csn.definitions[member.items.type];
|
|
40
|
+
if (type && !type.$visited) {
|
|
41
|
+
setProp(type, '$visited', true);
|
|
42
|
+
validate(type);
|
|
43
|
+
delete type.$visited;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
40
47
|
validate(member.items);
|
|
48
|
+
}
|
|
41
49
|
}
|
|
42
50
|
}
|
|
43
51
|
|
|
@@ -17,7 +17,7 @@ function validateCdsPersistenceAnnotation(artifact, artifactName, prop, path) {
|
|
|
17
17
|
// TODO: Why not filter over persistenceAnnos, is shorter!
|
|
18
18
|
const TableUdfCv = Object.keys(artifact).filter(p => persistenceAnnos.includes(p) && artifact[p]);
|
|
19
19
|
if (TableUdfCv.length > 1)
|
|
20
|
-
this.error(null, path, `Annotations ${ TableUdfCv.join(', ') } can't be used in combination`);
|
|
20
|
+
this.error(null, path, {}, `Annotations ${ TableUdfCv.join(', ') } can't be used in combination`);
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|