@sap/cds-compiler 2.15.8 → 3.1.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 (127) hide show
  1. package/CHANGELOG.md +102 -1590
  2. package/bin/.eslintrc.json +2 -1
  3. package/bin/cdsc.js +61 -46
  4. package/doc/API.md +11 -0
  5. package/doc/CHANGELOG_ARCHIVE.md +1592 -0
  6. package/doc/CHANGELOG_BETA.md +26 -5
  7. package/doc/CHANGELOG_DEPRECATED.md +55 -1
  8. package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
  9. package/doc/Versioning.md +20 -1
  10. package/lib/api/.eslintrc.json +2 -2
  11. package/lib/api/main.js +282 -156
  12. package/lib/api/options.js +17 -88
  13. package/lib/api/validate.js +6 -10
  14. package/lib/base/keywords.js +280 -110
  15. package/lib/base/message-registry.js +85 -25
  16. package/lib/base/messages.js +119 -89
  17. package/lib/base/model.js +46 -2
  18. package/lib/base/optionProcessorHelper.js +53 -21
  19. package/lib/checks/actionsFunctions.js +15 -12
  20. package/lib/checks/annotationsOData.js +1 -1
  21. package/lib/checks/cdsPersistence.js +1 -0
  22. package/lib/checks/elements.js +6 -6
  23. package/lib/checks/invalidTarget.js +1 -1
  24. package/lib/checks/nonexpandableStructured.js +1 -1
  25. package/lib/checks/queryNoDbArtifacts.js +2 -1
  26. package/lib/checks/selectItems.js +101 -15
  27. package/lib/checks/types.js +7 -8
  28. package/lib/checks/utils.js +2 -2
  29. package/lib/checks/validator.js +3 -3
  30. package/lib/compiler/assert-consistency.js +78 -21
  31. package/lib/compiler/base.js +6 -4
  32. package/lib/compiler/builtins.js +177 -10
  33. package/lib/compiler/checks.js +1 -1
  34. package/lib/compiler/define.js +28 -23
  35. package/lib/compiler/extend.js +75 -18
  36. package/lib/compiler/finalize-parse-cdl.js +25 -18
  37. package/lib/compiler/index.js +27 -11
  38. package/lib/compiler/moduleLayers.js +7 -0
  39. package/lib/compiler/populate.js +26 -39
  40. package/lib/compiler/propagator.js +12 -7
  41. package/lib/compiler/resolve.js +207 -236
  42. package/lib/compiler/shared.js +100 -93
  43. package/lib/compiler/tweak-assocs.js +13 -20
  44. package/lib/compiler/utils.js +20 -6
  45. package/lib/edm/annotations/preprocessAnnotations.js +12 -13
  46. package/lib/edm/csn2edm.js +35 -37
  47. package/lib/edm/edm.js +22 -13
  48. package/lib/edm/edmAnnoPreprocessor.js +349 -0
  49. package/lib/edm/edmInboundChecks.js +85 -0
  50. package/lib/edm/edmPreprocessor.js +338 -689
  51. package/lib/edm/edmUtils.js +97 -67
  52. package/lib/gen/Dictionary.json +29 -9
  53. package/lib/gen/language.checksum +1 -1
  54. package/lib/gen/language.interp +8 -31
  55. package/lib/gen/language.tokens +105 -114
  56. package/lib/gen/languageLexer.interp +1 -34
  57. package/lib/gen/languageLexer.js +892 -1007
  58. package/lib/gen/languageLexer.tokens +95 -106
  59. package/lib/gen/languageParser.js +20629 -22474
  60. package/lib/inspect/.eslintrc.json +4 -0
  61. package/lib/inspect/index.js +14 -0
  62. package/lib/inspect/inspectModelStatistics.js +81 -0
  63. package/lib/inspect/inspectPropagation.js +189 -0
  64. package/lib/inspect/inspectUtils.js +44 -0
  65. package/lib/json/from-csn.js +74 -69
  66. package/lib/json/to-csn.js +17 -14
  67. package/lib/language/antlrParser.js +2 -2
  68. package/lib/language/docCommentParser.js +61 -38
  69. package/lib/language/errorStrategy.js +52 -40
  70. package/lib/language/genericAntlrParser.js +424 -292
  71. package/lib/language/language.g4 +604 -687
  72. package/lib/language/multiLineStringParser.js +14 -42
  73. package/lib/language/textUtils.js +44 -0
  74. package/lib/main.d.ts +28 -42
  75. package/lib/main.js +104 -81
  76. package/lib/model/api.js +1 -1
  77. package/lib/model/csnRefs.js +57 -30
  78. package/lib/model/csnUtils.js +189 -287
  79. package/lib/model/revealInternalProperties.js +32 -10
  80. package/lib/model/sortViews.js +32 -31
  81. package/lib/modelCompare/compare.js +3 -0
  82. package/lib/optionProcessor.js +91 -57
  83. package/lib/render/.eslintrc.json +1 -1
  84. package/lib/render/DuplicateChecker.js +4 -7
  85. package/lib/render/manageConstraints.js +70 -2
  86. package/lib/render/toCdl.js +387 -367
  87. package/lib/render/toHdbcds.js +20 -16
  88. package/lib/render/toRename.js +44 -22
  89. package/lib/render/toSql.js +81 -59
  90. package/lib/render/utils/common.js +16 -3
  91. package/lib/render/utils/sql.js +20 -19
  92. package/lib/sql-identifier.js +6 -0
  93. package/lib/transform/db/.eslintrc.json +3 -2
  94. package/lib/transform/db/associations.js +43 -35
  95. package/lib/transform/db/cdsPersistence.js +5 -16
  96. package/lib/transform/db/constraints.js +1 -1
  97. package/lib/transform/db/expansion.js +7 -6
  98. package/lib/transform/db/flattening.js +16 -18
  99. package/lib/transform/db/transformExists.js +7 -5
  100. package/lib/transform/db/views.js +3 -3
  101. package/lib/transform/draft/.eslintrc.json +2 -2
  102. package/lib/transform/draft/db.js +6 -6
  103. package/lib/transform/draft/odata.js +6 -7
  104. package/lib/transform/forHanaNew.js +30 -24
  105. package/lib/transform/forOdataNew.js +14 -16
  106. package/lib/transform/localized.js +35 -25
  107. package/lib/transform/odata/toFinalBaseType.js +10 -10
  108. package/lib/transform/odata/typesExposure.js +17 -8
  109. package/lib/transform/odata/utils.js +1 -38
  110. package/lib/transform/transformUtilsNew.js +63 -77
  111. package/lib/transform/translateAssocsToJoins.js +2 -2
  112. package/lib/transform/universalCsn/.eslintrc.json +2 -2
  113. package/lib/transform/universalCsn/coreComputed.js +11 -6
  114. package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
  115. package/lib/utils/file.js +31 -21
  116. package/lib/utils/moduleResolve.js +0 -1
  117. package/lib/utils/timetrace.js +20 -21
  118. package/package.json +34 -4
  119. package/share/messages/syntax-expected-integer.md +9 -8
  120. package/doc/ApiMigration.md +0 -237
  121. package/doc/CommandLineMigration.md +0 -58
  122. package/doc/ErrorMessages.md +0 -175
  123. package/doc/FioriAnnotations.md +0 -94
  124. package/doc/ODataTransformation.md +0 -273
  125. package/lib/backends.js +0 -529
  126. package/lib/checks/unknownMagic.js +0 -41
  127. package/lib/fix_antlr4-8_warning.js +0 -56
@@ -210,8 +210,11 @@ const referenceSemantics = {
210
210
  ref_where: { lexical: justDollar , dynamic: 'ref-target'}, // ...using baseEnv
211
211
  on: { lexical: justDollar, dynamic: 'query' }, // assoc defs, redirected to
212
212
  // there are also 'on_join' and 'on_mixin' with default semantics
213
- orderBy: { lexical: query => query, dynamic: 'query' },
214
- orderBy_set: { lexical: query => query.$next, dynamic: 'query' }, // to outer SELECT (from UNION)
213
+ orderBy_ref: { lexical: query => query, dynamic: 'query' },
214
+ orderBy_expr: { lexical: query => query, dynamic: 'source' }, // ref in ORDER BY expression
215
+ orderBy_set_ref: { lexical: query => query.$next, dynamic: 'query' }, // to outer SELECT (from UNION)
216
+ // refs in ORDER BY expr in UNION not really allowed - only with table alias (of outer queries) or $self
217
+ orderBy_set_expr: { lexical: query => query.$next, dynamic: false },
215
218
  // default: { lexical: query => query, dynamic: 'source' }
216
219
  }
217
220
 
@@ -327,7 +330,7 @@ function csnRefs( csn, universalReady ) {
327
330
  // Backend bug workaround, TODO: delete next 2 lines
328
331
  if (notFound !== undefined)
329
332
  return notFound;
330
- throw new ModelError( 'Undefined reference' );
333
+ throw new ModelError( `Unknown artifact reference: ${typeof ref !== 'string' ? JSON.stringify(ref.ref) : ref}` );
331
334
  }
332
335
 
333
336
  function artifactPathRef( ref ) {
@@ -551,37 +554,39 @@ function csnRefs( csn, universalReady ) {
551
554
  }
552
555
  }
553
556
  // now the dynamic environment: ------------------------------------------
554
- if (semantics.dynamic === 'target') { // ref in keys
555
- const target = assocTarget( parent, refCtx );
556
- return resolvePath( path, target.elements[head], target, 'target' );
557
- }
558
- if (baseEnv) // ref-target (filter condition), expand, inline
559
- return resolvePath( path, baseEnv.elements[head], baseEnv, semantics.dynamic );
560
- if (!query) { // outside queries - TODO: items?
561
- let art = parent.elements[head];
562
- // Ref to up_ in anonymous aspect
563
- if (!art && head === 'up_') {
564
- const up = getCache( parent, '_parent' );
565
- const target = up && typeof up.target === 'string' && csn.definitions[up.target];
566
- if (target && target.elements) {
567
- initDefinition( target );
568
- art = target.elements.up_;
557
+ if (semantics.dynamic !== false) {
558
+ if (semantics.dynamic === 'target') { // ref in keys
559
+ const target = assocTarget( parent, refCtx );
560
+ return resolvePath( path, target.elements[head], target, 'target' );
561
+ }
562
+ if (baseEnv) // ref-target (filter condition), expand, inline
563
+ return resolvePath( path, baseEnv.elements[head], baseEnv, semantics.dynamic );
564
+ if (!query) { // outside queries - TODO: items?
565
+ let art = parent.elements[head];
566
+ // Ref to up_ in anonymous aspect
567
+ if (!art && head === 'up_') {
568
+ const up = getCache( parent, '_parent' );
569
+ const target = up && typeof up.target === 'string' && csn.definitions[up.target];
570
+ if (target && target.elements) {
571
+ initDefinition( target );
572
+ art = target.elements.up_;
573
+ }
569
574
  }
575
+ return resolvePath( path, art, parent, 'parent' );
570
576
  }
571
- return resolvePath( path, art, parent, 'parent' );
572
- }
573
577
 
574
- if (semantics.dynamic === 'query')
575
- // TODO: for ON condition in expand, would need to use cached _element
576
- return resolvePath( path, qcache.elements[head], null, 'query' );
577
- for (const name in qcache.$aliases) {
578
- const alias = qcache.$aliases[name];
579
- const found = alias.elements[head];
580
- if (found)
581
- return resolvePath( path, found, alias._ref, 'source', name )
578
+ if (semantics.dynamic === 'query')
579
+ // TODO: for ON condition in expand, would need to use cached _element
580
+ return resolvePath( path, qcache.elements[head], null, 'query' );
581
+ for (const name in qcache.$aliases) {
582
+ const alias = qcache.$aliases[name];
583
+ const found = alias.elements[head];
584
+ if (found)
585
+ return resolvePath( path, found, alias._ref, 'source', name )
586
+ }
582
587
  }
583
588
  // console.log(query.SELECT,qcache,qcache.$next,main)
584
- throw new ModelError ( `Path item ${ 0 }=${ head } refers to nothing, refCtx: ${ refCtx }` );
589
+ throw new ModelError ( `Path item 0=${ head } refers to nothing, refCtx: ${ refCtx }` );
585
590
  }
586
591
 
587
592
  /**
@@ -907,6 +912,7 @@ function startCsnPath( csnPath, csn ) {
907
912
  /**
908
913
  * @param {CSN.Path} csnPath
909
914
  * @param {CSN.Model} csn
915
+ * @param {any} resolve
910
916
  */
911
917
  function analyseCsnPath( csnPath, csn, resolve ) {
912
918
  /** @type {object} */
@@ -932,6 +938,15 @@ function analyseCsnPath( csnPath, csn, resolve ) {
932
938
  parent = art;
933
939
  art = obj[prop];
934
940
  }
941
+ else if (refCtx === 'orderBy') {
942
+ const isSelect = isSelectQuery( query );
943
+ // use _query_ elements with direct refs (consider sub-optimal CSN,
944
+ // representation of the CAST function), otherwise source elements:
945
+ if (obj[prop].ref && !obj[prop].cast)
946
+ refCtx = (isSelect ? 'orderBy_ref' : 'orderBy_set_ref');
947
+ else
948
+ refCtx = (isSelect ? 'orderBy_expr' : 'orderBy_set_expr');
949
+ }
935
950
  isName = false;
936
951
  }
937
952
  else if (artifactProperties.includes( String(prop) )) {
@@ -982,7 +997,7 @@ function analyseCsnPath( csnPath, csn, resolve ) {
982
997
  refCtx = prop;
983
998
  }
984
999
  else if (prop === 'orderBy') {
985
- refCtx = (query.SET ? 'orderBy_set' : 'orderBy');
1000
+ refCtx = 'orderBy';
986
1001
  }
987
1002
  else if (prop !== 'xpr') {
988
1003
  refCtx = prop;
@@ -995,6 +1010,18 @@ function analyseCsnPath( csnPath, csn, resolve ) {
995
1010
  return resolve( obj, refCtx, main, query, parent, baseEnv );
996
1011
  }
997
1012
 
1013
+ // A SELECT which is (unnecessarily) put into parentheses, the CSN
1014
+ // representation uses SET without `op` and args of length 1:
1015
+ function isSelectQuery( query ) {
1016
+ while (query.SET) {
1017
+ const { args } = query.SET;
1018
+ if (args.length !== 1)
1019
+ return false;
1020
+ query = args[0];
1021
+ }
1022
+ return true;
1023
+ }
1024
+
998
1025
  module.exports = {
999
1026
  csnRefs,
1000
1027
  traverseQuery,