@sap/cds-compiler 5.7.4 → 5.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/CHANGELOG.md +60 -2
  2. package/bin/cdsse.js +13 -1
  3. package/doc/CHANGELOG_BETA.md +7 -0
  4. package/lib/api/options.js +2 -1
  5. package/lib/api/validate.js +9 -0
  6. package/lib/base/message-registry.js +55 -20
  7. package/lib/base/messages.js +5 -2
  8. package/lib/base/model.js +4 -1
  9. package/lib/checks/assocOutsideService.js +40 -0
  10. package/lib/checks/featureFlags.js +4 -1
  11. package/lib/checks/types.js +7 -4
  12. package/lib/checks/validator.js +3 -0
  13. package/lib/compiler/assert-consistency.js +11 -5
  14. package/lib/compiler/checks.js +79 -17
  15. package/lib/compiler/define.js +57 -3
  16. package/lib/compiler/extend.js +1 -2
  17. package/lib/compiler/generate.js +1 -1
  18. package/lib/compiler/populate.js +17 -6
  19. package/lib/compiler/propagator.js +1 -1
  20. package/lib/compiler/resolve.js +181 -150
  21. package/lib/compiler/shared.js +276 -22
  22. package/lib/compiler/tweak-assocs.js +15 -4
  23. package/lib/compiler/xpr-rewrite.js +76 -50
  24. package/lib/edm/annotations/edmJson.js +1 -1
  25. package/lib/edm/annotations/genericTranslation.js +2 -2
  26. package/lib/edm/csn2edm.js +2 -2
  27. package/lib/edm/edmPreprocessor.js +15 -9
  28. package/lib/edm/edmUtils.js +12 -5
  29. package/lib/gen/CdlGrammar.checksum +1 -0
  30. package/lib/gen/CdlParser.js +2234 -2233
  31. package/lib/gen/Dictionary.json +55 -8
  32. package/lib/json/from-csn.js +37 -17
  33. package/lib/json/to-csn.js +4 -0
  34. package/lib/language/genericAntlrParser.js +7 -0
  35. package/lib/main.d.ts +5 -0
  36. package/lib/model/cloneCsn.js +1 -0
  37. package/lib/model/csnRefs.js +1 -0
  38. package/lib/model/csnUtils.js +0 -5
  39. package/lib/modelCompare/utils/filter.js +2 -2
  40. package/lib/optionProcessor.js +2 -0
  41. package/lib/parsers/AstBuildingParser.js +47 -17
  42. package/lib/parsers/CdlGrammar.g4 +10 -12
  43. package/lib/parsers/XprTree.js +206 -0
  44. package/lib/render/toCdl.js +61 -89
  45. package/lib/render/toSql.js +59 -29
  46. package/lib/render/utils/standardDatabaseFunctions.js +252 -15
  47. package/lib/transform/addTenantFields.js +9 -3
  48. package/lib/transform/db/assocsToQueries/transformExists.js +3 -0
  49. package/lib/transform/db/assocsToQueries/utils.js +10 -3
  50. package/lib/transform/db/expansion.js +3 -1
  51. package/lib/transform/db/flattening.js +7 -3
  52. package/lib/transform/db/killAnnotations.js +1 -0
  53. package/lib/transform/db/processSqlServices.js +70 -17
  54. package/lib/transform/draft/db.js +8 -3
  55. package/lib/transform/draft/odata.js +27 -4
  56. package/lib/transform/effective/main.js +37 -10
  57. package/lib/transform/effective/misc.js +4 -9
  58. package/lib/transform/effective/service.js +34 -0
  59. package/lib/transform/effective/types.js +28 -17
  60. package/lib/transform/forOdata.js +36 -10
  61. package/lib/transform/forRelationalDB.js +30 -18
  62. package/lib/transform/odata/adaptAnnotationRefs.js +37 -21
  63. package/lib/transform/odata/createForeignKeys.js +121 -117
  64. package/lib/transform/odata/flattening.js +12 -9
  65. package/lib/transform/transformUtils.js +58 -25
  66. package/lib/transform/translateAssocsToJoins.js +10 -6
  67. package/lib/transform/universalCsn/coreComputed.js +5 -1
  68. package/package.json +1 -1
  69. package/share/messages/message-explanations.json +1 -0
  70. package/share/messages/rewrite-not-supported.md +5 -0
  71. package/share/messages/rewrite-undefined-key.md +94 -0
@@ -163,7 +163,7 @@ function xpr2edmJson( carrier, anno, location, options, messageFunctions ) {
163
163
  });
164
164
  }
165
165
  }
166
- const edmTypeName = edmUtils.mapCdsToEdmType(csnType, messageFunctions, options.isV2(), false, location);
166
+ const edmTypeName = edmUtils.mapCdsToEdmType(csnType, messageFunctions, options, false, location);
167
167
  const typeFunc = { func: 'Type', args: [ { val: edmTypeName } ] };
168
168
  const castFunc = { func: '$Cast', args: [ typeFunc, castExpr[1] ] };
169
169
 
@@ -367,7 +367,7 @@ function csn2annotationEdm( reqDefs, reqDefsUtils, csnVocabularies, serviceName,
367
367
 
368
368
  function mapType( p ) {
369
369
  if (isBuiltinType(p.type)) {
370
- return edmUtils.mapCdsToEdmType(p, messageFunctions, false /* is only called for v4 */);
370
+ return edmUtils.mapCdsToEdmType(p, messageFunctions, options /* is only called for v4 */);
371
371
  }
372
372
  else if (options.whatsMySchemaName) {
373
373
  const schemaName = options.whatsMySchemaName(p._edmType || p.type);
@@ -1774,7 +1774,7 @@ function mergeOdataVocabularies( options, message ) {
1774
1774
  defOk = false;
1775
1775
  }
1776
1776
  else if (name === 'Alias' && !edmUtils.isODataSimpleIdentifier(def[name])) {
1777
- message('odata-spec-violation-id', null, { id: name, value: def[name], '#': 'vocrefalias' });
1777
+ message('odata-spec-violation-id', null, { id: name, value: def[name], '#': 'vocRefAlias' });
1778
1778
  defOk = false;
1779
1779
  }
1780
1780
  });
@@ -544,7 +544,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
544
544
  // FIXME: Rewrite signalIllegalIdentifier function to be more flexible
545
545
  message('odata-spec-violation-id', pLoc,
546
546
  {
547
- prop: p._edmAttributes.Name[0], id: p._edmAttributes.Name, version: '2.0', '#': 'v2firstchar',
547
+ prop: p._edmAttributes.Name[0], id: p._edmAttributes.Name, version: '2.0', '#': 'v2firstChar',
548
548
  });
549
549
  }
550
550
  });
@@ -969,7 +969,7 @@ function csn2edmAll( _csn, _options, serviceNames, messageFunctions ) {
969
969
  message('odata-spec-violation-returns', returnsLoc, { kind: action.kind, version: '2.0' });
970
970
  }
971
971
  else if (isBuiltinType(type)) {
972
- type = edmUtils.mapCdsToEdmType(returns, messageFunctions, true);
972
+ type = edmUtils.mapCdsToEdmType(returns, messageFunctions, _options);
973
973
  if (type) {
974
974
  const td = EdmPrimitiveTypeMap[type];
975
975
  if (td && !td.v2) {
@@ -888,17 +888,23 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
888
888
  // if the forward association has set a src cardinality and it deviates from the backlink target cardinality raise a warning
889
889
  // in V2 only, in V4 the source cardinality is rendered implicitly at the Type property
890
890
  if (element._constraints._partnerCsn.cardinality.src) {
891
+ const partnerCsn = element._constraints._partnerCsn;
891
892
  // eslint-disable-next-line eqeqeq
892
- const srcMult = (element._constraints._partnerCsn.cardinality.src == 1) ? '0..1' : '*';
893
+ const srcMult = (partnerCsn.cardinality.src == 1) ? '0..1' : '*';
893
894
  const newMult
894
895
  = (element.cardinality?.min == 1 && element.cardinality?.max == 1) // eslint-disable-line eqeqeq
895
-
896
- ? '1'
896
+ ? 1
897
897
  : (element.cardinality?.max === '*' || element.cardinality?.max > 1)
898
898
  ? '*'
899
899
  : '0..1';
900
- if (srcMult !== newMult)
901
- warning(null, element.$path, `Explicit source cardinality "${srcMult}" of "${element._constraints._partnerCsn._parent.name}/${element._constraints._partnerCsn.name}" conflicts with target cardinality "${newMult}"`);
900
+ if (srcMult !== newMult) {
901
+ // TODO: Message should probably list actual cardinalities and not "normalized" ones.
902
+ warning('odata-unexpected-cardinality', element.$path, {
903
+ value: srcMult,
904
+ othervalue: newMult,
905
+ name: `${partnerCsn._parent.name}/${partnerCsn.name}`,
906
+ }, 'Explicit source cardinality $(VALUE) of $(NAME) conflicts with target cardinality $(OTHERVALUE)' );
907
+ }
902
908
  }
903
909
  else {
904
910
  // .. but only if the original assoc hasn't set src yet
@@ -1691,7 +1697,7 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
1691
1697
  // check for legal scalar types, proxy exposed structured types are not resolvable in CSN
1692
1698
  // V2 allows any Edm.PrimitiveType (even Double and Binary), V4 is more specific:
1693
1699
  if (options.isV4() && type && !type.target && isBuiltinType(type.type)) {
1694
- const edmType = edmUtils.mapCdsToEdmType(type);
1700
+ const edmType = edmUtils.mapCdsToEdmType(type, messageFunctions, _options);
1695
1701
  const legalEdmTypes = {
1696
1702
  'Edm.Boolean': 1,
1697
1703
  'Edm.Byte': 1,
@@ -2173,16 +2179,16 @@ function initializeModel( csn, _options, messageFunctions, requestedServiceNames
2173
2179
  return;
2174
2180
  }
2175
2181
  else if (obj.type && isBuiltinType(obj.type) && !obj.target && !obj.targetAspect) {
2176
- const edmType = edmUtils.mapCdsToEdmType(obj, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType']);
2182
+ const edmType = edmUtils.mapCdsToEdmType(obj, messageFunctions, _options, obj['@Core.MediaType']);
2177
2183
  edmUtils.assignProp(obj, '_edmType', edmType);
2178
2184
  }
2179
2185
  else if (obj.$isCollection && (obj.items && isBuiltinType(csnUtils.getFinalTypeInfo(obj.items.type)?.type))) {
2180
- const edmType = edmUtils.mapCdsToEdmType(obj.items, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType'], obj.$path);
2186
+ const edmType = edmUtils.mapCdsToEdmType(obj.items, messageFunctions, _options, obj['@Core.MediaType'], obj.$path);
2181
2187
  edmUtils.assignProp(obj, '_edmType', edmType);
2182
2188
  }
2183
2189
  // This is the special case when we have array of array, but will not be supported in the future
2184
2190
  else if (obj.$isCollection && obj.items && obj.items.type && obj.items.items && isBuiltinType(csnUtils.getFinalTypeInfo(obj.items.items.type)?.type)) {
2185
- const edmType = edmUtils.mapCdsToEdmType(obj.items.items, messageFunctions, _options.odataVersion === 'v2', obj['@Core.MediaType']);
2191
+ const edmType = edmUtils.mapCdsToEdmType(obj.items.items, messageFunctions, _options, obj['@Core.MediaType']);
2186
2192
  edmUtils.assignProp(obj, '_edmType', edmType);
2187
2193
  }
2188
2194
  }
@@ -137,8 +137,12 @@ function resolveOnConditionAndPrepareConstraints( csn, assocCsn, messageFunction
137
137
  isBacklink = false;
138
138
  // Partnership is ambiguous
139
139
  setProp(originAssocCsn, '$noPartner', true);
140
- info(null, [ 'definitions', parentName, 'elements', assocCsn.name ],
141
- `"${originParentName}:${partnerPath.join('.')}" with target "${originAssocCsn._target.name}" is compared with $self which represents "${parentName}"`);
140
+ info('odata-unexpected-comparison', [ 'definitions', parentName, 'elements', assocCsn.name ], {
141
+ name: `${originParentName}:${partnerPath.join('.')}`,
142
+ target: originAssocCsn._target.name,
143
+ id: '$self',
144
+ alias: parentName,
145
+ }, 'Ambiguous comparison of $(NAME) with target $(TARGET) to $(ID) which represents $(ALIAS)');
142
146
  }
143
147
  if (originAssocCsn.target) {
144
148
  // Mark this association as backlink if $self appears exactly once
@@ -489,9 +493,10 @@ function getEffectiveTargetCardinality( csn ) {
489
493
  return rc;
490
494
  }
491
495
 
492
- function mapCdsToEdmType( csn, messageFunctions, isV2 = false, isMediaType = false, location = undefined ) {
496
+ function mapCdsToEdmType( csn, messageFunctions, options, isMediaType = false, location = undefined ) {
493
497
  if (location === undefined)
494
498
  location = csn.$path;
499
+ const isV2 = options.odataVersion === 'v2';
495
500
  const { error } = messageFunctions || { error: () => true };
496
501
  const cdsType = csn.type;
497
502
  if (cdsType === undefined) {
@@ -554,8 +559,10 @@ function mapCdsToEdmType( csn, messageFunctions, isV2 = false, isMediaType = fal
554
559
  */
555
560
  }[cdsType];
556
561
  if (!edmType) {
557
- error('ref-unsupported-type', location,
558
- { type: cdsType, version: (isV2 ? '2.0' : '4.0'), '#': 'odata' });
562
+ if (isEdmPropertyRendered(csn, options)) {
563
+ error('ref-unsupported-type', location,
564
+ { type: cdsType, version: (isV2 ? '2.0' : '4.0'), '#': 'odata' });
565
+ }
559
566
  // return a version compatible type to avoid later compatibility failures
560
567
  edmType = isV2 ? 'Edm.String' : 'Edm.PrimitiveType';
561
568
  }
@@ -0,0 +1 @@
1
+ f2ee15363af822d120947887515d2414