@sap/cds-compiler 4.0.0 → 4.1.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 +115 -5
- package/bin/cdsc.js +12 -12
- package/doc/CHANGELOG_BETA.md +11 -0
- package/lib/api/main.js +60 -12
- package/lib/api/validate.js +1 -1
- package/lib/base/location.js +6 -7
- package/lib/base/message-registry.js +84 -38
- package/lib/base/messages.js +11 -10
- package/lib/base/model.js +6 -2
- package/lib/checks/defaultValues.js +6 -6
- package/lib/checks/foreignKeys.js +0 -5
- package/lib/checks/onConditions.js +17 -12
- package/lib/checks/queryNoDbArtifacts.js +132 -72
- package/lib/checks/sql-snippets.js +15 -4
- package/lib/checks/types.js +3 -3
- package/lib/checks/utils.js +1 -1
- package/lib/compiler/assert-consistency.js +44 -16
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +7 -8
- package/lib/compiler/checks.js +274 -197
- package/lib/compiler/classes.js +62 -0
- package/lib/compiler/cycle-detector.js +3 -3
- package/lib/compiler/define.js +63 -50
- package/lib/compiler/extend.js +38 -20
- package/lib/compiler/finalize-parse-cdl.js +2 -1
- package/lib/compiler/generate.js +0 -8
- package/lib/compiler/index.js +9 -7
- package/lib/compiler/kick-start.js +2 -0
- package/lib/compiler/populate.js +139 -110
- package/lib/compiler/propagator.js +4 -3
- package/lib/compiler/resolve.js +157 -126
- package/lib/compiler/shared.js +706 -404
- package/lib/compiler/tweak-assocs.js +21 -10
- package/lib/compiler/utils.js +228 -36
- package/lib/edm/annotations/genericTranslation.js +30 -2
- package/lib/edm/edm.js +4 -1
- package/lib/edm/edmPreprocessor.js +12 -5
- package/lib/edm/edmUtils.js +2 -4
- 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 +3987 -3963
- package/lib/json/from-csn.js +43 -47
- package/lib/json/to-csn.js +11 -11
- package/lib/language/antlrParser.js +2 -1
- package/lib/language/genericAntlrParser.js +52 -43
- package/lib/language/language.g4 +59 -59
- package/lib/language/multiLineStringParser.js +2 -0
- package/lib/main.d.ts +5 -0
- package/lib/model/csnRefs.js +37 -19
- package/lib/model/csnUtils.js +20 -16
- package/lib/model/revealInternalProperties.js +29 -21
- package/lib/model/sortViews.js +4 -2
- package/lib/modelCompare/compare.js +112 -39
- package/lib/modelCompare/utils/filter.js +54 -24
- package/lib/optionProcessor.js +6 -6
- package/lib/render/manageConstraints.js +20 -17
- package/lib/render/toCdl.js +34 -20
- package/lib/render/toHdbcds.js +2 -2
- package/lib/render/toRename.js +4 -9
- package/lib/render/toSql.js +77 -26
- package/lib/render/utils/common.js +3 -3
- package/lib/render/utils/unique.js +52 -0
- package/lib/transform/db/applyTransformations.js +61 -20
- package/lib/transform/db/assertUnique.js +7 -8
- package/lib/transform/db/associations.js +2 -2
- package/lib/transform/db/cdsPersistence.js +8 -8
- package/lib/transform/db/expansion.js +17 -21
- package/lib/transform/db/flattening.js +23 -23
- 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} +56 -42
- package/lib/transform/forRelationalDB.js +69 -75
- package/lib/transform/localized.js +6 -5
- package/lib/transform/odata/toFinalBaseType.js +3 -3
- package/lib/transform/{transformUtilsNew.js → transformUtils.js} +4 -101
- package/lib/transform/translateAssocsToJoins.js +14 -28
- package/package.json +1 -1
- 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/lib/language/language.g4
CHANGED
|
@@ -216,7 +216,7 @@ usingProxy[ outer, proxy ]
|
|
|
216
216
|
)
|
|
217
217
|
;
|
|
218
218
|
|
|
219
|
-
artifactDefOrExtend[ outer, defOnly = false ] locals[ art =
|
|
219
|
+
artifactDefOrExtend[ outer, defOnly = false ] locals[ art = new parser.XsnArtifact() ] // cannot use `parent` as parameter name!
|
|
220
220
|
@after{ /* #ATN 1 */ }
|
|
221
221
|
:
|
|
222
222
|
{ $art.location = this.startLocation(); this.docComment( $art ); }
|
|
@@ -285,13 +285,13 @@ optionalSemi
|
|
|
285
285
|
|
|
286
286
|
// Annotation def and main definitions ------------------------------------------
|
|
287
287
|
|
|
288
|
-
annotationDef[ art, outer ] locals[ name =
|
|
288
|
+
annotationDef[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
289
289
|
@after { this.attachLocation( $art ); }
|
|
290
290
|
:
|
|
291
291
|
annotation=ANNOTATION simplePath[ $name, 'AnnoDef' ]
|
|
292
292
|
{ if ($outer.kind !== 'source') { // this is a syntax restriction to avoid confusion
|
|
293
293
|
this.error( 'syntax-unexpected-vocabulary', $annotation, { '#': $outer.kind } );
|
|
294
|
-
$art =
|
|
294
|
+
$art = new this.XsnArtifact(); }
|
|
295
295
|
else {
|
|
296
296
|
if (!$outer.vocabularies) $outer.vocabularies = Object.create(null);
|
|
297
297
|
this.addDef( $art, $outer, 'vocabularies', 'annotation', $name );
|
|
@@ -301,7 +301,7 @@ annotationDef[ art, outer ] locals[ name = {} ]
|
|
|
301
301
|
typeSpecSemi[ $art ] // also 'includes'...
|
|
302
302
|
;
|
|
303
303
|
|
|
304
|
-
serviceDef[ art, outer, defOnly = false ] locals[ name =
|
|
304
|
+
serviceDef[ art, outer, defOnly = false ] locals[ name = new parser.XsnName(); ]
|
|
305
305
|
@after { this.attachLocation( $art ); }
|
|
306
306
|
:
|
|
307
307
|
SERVICE simplePath[ $name, 'Service' ]
|
|
@@ -309,7 +309,7 @@ serviceDef[ art, outer, defOnly = false ] locals[ name = {} ]
|
|
|
309
309
|
optArtifactsBlock[ $art, defOnly ]
|
|
310
310
|
;
|
|
311
311
|
|
|
312
|
-
contextDef[ art, outer, defOnly = false ] locals[ name =
|
|
312
|
+
contextDef[ art, outer, defOnly = false ] locals[ name = new parser.XsnName(); ]
|
|
313
313
|
@after { this.attachLocation( $art ); }
|
|
314
314
|
:
|
|
315
315
|
CONTEXT simplePath[ $name, 'Context' ]
|
|
@@ -317,7 +317,7 @@ contextDef[ art, outer, defOnly = false ] locals[ name = {} ]
|
|
|
317
317
|
optArtifactsBlock[ $art, defOnly ]
|
|
318
318
|
;
|
|
319
319
|
|
|
320
|
-
eventDef[ art, outer ] locals[ name =
|
|
320
|
+
eventDef[ art, outer ] locals[ name = new parser.XsnName(); ]
|
|
321
321
|
@after { /* #ATN 1 */ this.attachLocation( $art ); }
|
|
322
322
|
:
|
|
323
323
|
EVENT simplePath[ $name, 'Event' ]
|
|
@@ -353,7 +353,7 @@ eventDef[ art, outer ] locals[ name = {} ]
|
|
|
353
353
|
)
|
|
354
354
|
;
|
|
355
355
|
|
|
356
|
-
viewDef[ art, outer ] locals[ name =
|
|
356
|
+
viewDef[ art, outer ] locals[ name = new parser.XsnName(); ]
|
|
357
357
|
@after { this.attachLocation( $art ); }
|
|
358
358
|
:
|
|
359
359
|
v=VIEW simplePath[ $name, 'Entity' ]
|
|
@@ -376,7 +376,7 @@ viewDef[ art, outer ] locals[ name = {} ]
|
|
|
376
376
|
requiredSemi
|
|
377
377
|
;
|
|
378
378
|
|
|
379
|
-
entityDef[ art, outer ] locals[ name =
|
|
379
|
+
entityDef[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
380
380
|
@after { this.attachLocation( $art ); }
|
|
381
381
|
:
|
|
382
382
|
ENTITY simplePath[ $name, 'Entity' ]
|
|
@@ -424,7 +424,7 @@ entityDef[ art, outer ] locals[ name = {} ]
|
|
|
424
424
|
)
|
|
425
425
|
;
|
|
426
426
|
|
|
427
|
-
aspectDef[ art, outer ] locals[ name =
|
|
427
|
+
aspectDef[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
428
428
|
@after { this.attachLocation( $art ); }
|
|
429
429
|
:
|
|
430
430
|
( ASPECT | ( abs=ABSTRACT | HideAlternatives ) ent=ENTITY )
|
|
@@ -453,12 +453,11 @@ aspectDef[ art, outer ] locals[ name = {} ]
|
|
|
453
453
|
)?
|
|
454
454
|
optionalSemi
|
|
455
455
|
| // `aspect MyAspect;`, e.g. for annotation aspects.
|
|
456
|
-
{ this.aspectWithoutElements( $art ); }
|
|
457
456
|
requiredSemi
|
|
458
457
|
)
|
|
459
458
|
;
|
|
460
459
|
|
|
461
|
-
typeDef[ art, outer ] locals[ name =
|
|
460
|
+
typeDef[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
462
461
|
@after { this.attachLocation( $art ); }
|
|
463
462
|
:
|
|
464
463
|
TYPE simplePath[ $name, 'Type' ]
|
|
@@ -468,7 +467,7 @@ typeDef[ art, outer ] locals[ name = {} ]
|
|
|
468
467
|
typeSpecSemi[ $art ]
|
|
469
468
|
;
|
|
470
469
|
|
|
471
|
-
actionFunctionMainDef[ art, outer ] locals[ name =
|
|
470
|
+
actionFunctionMainDef[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
472
471
|
@after { this.attachLocation( $art ); }
|
|
473
472
|
:
|
|
474
473
|
ACTION simplePath[ $name, 'Action' ]
|
|
@@ -488,7 +487,7 @@ actionFunctionMainDef[ art, outer ] locals[ name = {} ]
|
|
|
488
487
|
|
|
489
488
|
// Member definitions: actions, elements, enums, parameters: --------------------
|
|
490
489
|
|
|
491
|
-
actionFunctionDef[ outer ] locals[ art =
|
|
490
|
+
actionFunctionDef[ outer ] locals[ art = new parser.XsnArtifact() ]
|
|
492
491
|
@after { this.attachLocation( $art ); }
|
|
493
492
|
:
|
|
494
493
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
@@ -510,7 +509,7 @@ actionFunctionDef[ outer ] locals[ art = {} ]
|
|
|
510
509
|
)
|
|
511
510
|
;
|
|
512
511
|
|
|
513
|
-
parameterDef[ outer ] locals[ art =
|
|
512
|
+
parameterDef[ outer ] locals[ art = new parser.XsnArtifact() ]
|
|
514
513
|
@after { this.attachLocation( $art ); }
|
|
515
514
|
:
|
|
516
515
|
{ this.meltKeywordToIdentifier();; this.docComment( $art ); }
|
|
@@ -546,7 +545,7 @@ parameterListDef[ art ]
|
|
|
546
545
|
')' { this.finalizeDictOrArray( $art.params ); }
|
|
547
546
|
;
|
|
548
547
|
|
|
549
|
-
enumSymbolDef[ outer ] locals[ art =
|
|
548
|
+
enumSymbolDef[ outer ] locals[ art = new parser.XsnArtifact() ]
|
|
550
549
|
@after { this.attachLocation( $art ); }
|
|
551
550
|
:
|
|
552
551
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
@@ -570,14 +569,14 @@ enumSymbolDef[ outer ] locals[ art = {} ]
|
|
|
570
569
|
requiredSemi
|
|
571
570
|
;
|
|
572
571
|
|
|
573
|
-
elementDef[ outer ] locals[ $art =
|
|
572
|
+
elementDef[ outer ] locals[ $art = new parser.XsnArtifact() ]
|
|
574
573
|
:
|
|
575
574
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
576
575
|
annotationAssignment_ll1[ $art ]*
|
|
577
|
-
elementDefInner[ $art, $outer
|
|
576
|
+
elementDefInner[ $art, $outer ]
|
|
578
577
|
;
|
|
579
578
|
|
|
580
|
-
elementDefInner[ art, outer,
|
|
579
|
+
elementDefInner[ art, outer, explicitElement = false ]
|
|
581
580
|
@after{ this.attachLocation( $art ); }
|
|
582
581
|
:
|
|
583
582
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
@@ -592,7 +591,7 @@ elementDefInner[ art, outer, mightBeEnum ]
|
|
|
592
591
|
}
|
|
593
592
|
)?
|
|
594
593
|
{ this.setLocalToken( 'ELEMENT', 'ELEMENT', /^[;:{@=}]$/ ); }
|
|
595
|
-
( ELEMENT { $
|
|
594
|
+
( ELEMENT { $explicitElement = true; } )? // auto-recognizable at other places
|
|
596
595
|
name=ident['Element']
|
|
597
596
|
{ this.addDef( $art, $outer, 'elements', 'element', $name.id );
|
|
598
597
|
this.docComment( $art ); }
|
|
@@ -605,7 +604,7 @@ elementDefInner[ art, outer, mightBeEnum ]
|
|
|
605
604
|
)
|
|
606
605
|
|
|
|
607
606
|
':'
|
|
608
|
-
elementType[ $art
|
|
607
|
+
elementType[ $art ]
|
|
609
608
|
|
|
|
610
609
|
eq='=' e=expression // SQL has syntax variant using AS - we DO NOT
|
|
611
610
|
stored=STORED?
|
|
@@ -613,10 +612,8 @@ elementDefInner[ art, outer, mightBeEnum ]
|
|
|
613
612
|
// this.setIntroLocation( eq ); -- future
|
|
614
613
|
if ($stored)
|
|
615
614
|
$art.value.stored = this.valueWithTokenLocation( true, $stored );
|
|
616
|
-
if ($
|
|
617
|
-
|
|
618
|
-
!$virtual && !$key && !$masked && !$art.elements && !$art.type)
|
|
619
|
-
$art['$'+'syntax'] = 'enum';
|
|
615
|
+
if ($explicitElement)
|
|
616
|
+
$art['$'+'syntax'] = 'element';
|
|
620
617
|
}
|
|
621
618
|
{ this.docComment( $art ); }
|
|
622
619
|
annotationAssignment_ll1[ $art ]* // for enum symbol def via EXTEND
|
|
@@ -750,7 +747,7 @@ defaultValue[ art ] locals[ elem, elements = {} ]
|
|
|
750
747
|
|
|
751
748
|
// Extend and annotate ----------------------------------------------------------
|
|
752
749
|
|
|
753
|
-
extendArtifact[ art, outer ] locals[ name =
|
|
750
|
+
extendArtifact[ art, outer ] locals[ name = new parser.XsnName(), elemName = new parser.XsnName() ]
|
|
754
751
|
@after{ /* #ATN 1 */ this.attachLocation( $art ); }
|
|
755
752
|
:
|
|
756
753
|
simplePath[ $name, 'Extend' ]
|
|
@@ -771,7 +768,7 @@ extendArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
|
771
768
|
(
|
|
772
769
|
// all the alternatives from `extendWithOptElementsOrType` --------------
|
|
773
770
|
'{' { $art.elements = this.createDict(); }
|
|
774
|
-
elementDefOrExtend[ $art
|
|
771
|
+
elementDefOrExtend[ $art ]*
|
|
775
772
|
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
776
773
|
{ this.checkExtensionDict( $art.elements ); }
|
|
777
774
|
optionalSemi
|
|
@@ -779,7 +776,7 @@ extendArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
|
779
776
|
requiredSemi
|
|
780
777
|
|
|
|
781
778
|
ELEMENTS { $art.elements = this.createDict(); } '{'
|
|
782
|
-
elementDefOrExtend[ $art ]*
|
|
779
|
+
elementDefOrExtend[ $art, true ]*
|
|
783
780
|
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
784
781
|
{ this.checkExtensionDict( $art.elements ); }
|
|
785
782
|
optionalSemi
|
|
@@ -823,7 +820,7 @@ extendArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
|
823
820
|
)
|
|
824
821
|
;
|
|
825
822
|
|
|
826
|
-
extendService[ art, outer ] locals[ name =
|
|
823
|
+
extendService[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
827
824
|
@after { this.attachLocation( $art ); }
|
|
828
825
|
:
|
|
829
826
|
SERVICE { $art.expectedKind = this.valueWithTokenLocation(); }
|
|
@@ -833,7 +830,7 @@ extendService[ art, outer ] locals[ name = {} ]
|
|
|
833
830
|
optArtifactsBlock[ art, 'service' ]
|
|
834
831
|
;
|
|
835
832
|
|
|
836
|
-
extendContext[ art, outer ] locals[ name =
|
|
833
|
+
extendContext[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
837
834
|
@after { this.attachLocation( $art ); }
|
|
838
835
|
:
|
|
839
836
|
CONTEXT { $art.expectedKind = this.valueWithTokenLocation(); }
|
|
@@ -843,7 +840,7 @@ extendContext[ art, outer ] locals[ name = {} ]
|
|
|
843
840
|
optArtifactsBlock[ art, 'context' ]
|
|
844
841
|
;
|
|
845
842
|
|
|
846
|
-
extendEntityOrAspect[ art, outer ] locals[ name =
|
|
843
|
+
extendEntityOrAspect[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
847
844
|
@after { /* #ATN 1 */ this.attachLocation( $art ); }
|
|
848
845
|
:
|
|
849
846
|
(ASPECT | ENTITY) { $art.expectedKind = this.valueWithTokenLocation(); }
|
|
@@ -888,7 +885,7 @@ extendForEntity[ art ]
|
|
|
888
885
|
requiredSemi
|
|
889
886
|
;
|
|
890
887
|
|
|
891
|
-
extendProjection[ art, outer ] locals[ name =
|
|
888
|
+
extendProjection[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
892
889
|
@after { this.attachLocation( $art ); }
|
|
893
890
|
:
|
|
894
891
|
PROJECTION { $art.expectedKind = this.valueWithTokenLocation( 'entity' ); }
|
|
@@ -924,7 +921,7 @@ extendProjection[ art, outer ] locals[ name = {} ]
|
|
|
924
921
|
)
|
|
925
922
|
;
|
|
926
923
|
|
|
927
|
-
extendType[ art, outer ] locals[ name =
|
|
924
|
+
extendType[ art, outer ] locals[ name = new parser.XsnName() ]
|
|
928
925
|
@after { this.attachLocation( $art ); }
|
|
929
926
|
:
|
|
930
927
|
TYPE { $art.expectedKind = this.valueWithTokenLocation(); }
|
|
@@ -940,7 +937,7 @@ extendType[ art, outer ] locals[ name = {} ]
|
|
|
940
937
|
annotationAssignment_ll1[ $art ]*
|
|
941
938
|
(
|
|
942
939
|
'{' { $art.elements = this.createDict(); }
|
|
943
|
-
elementDefOrExtend[ $art
|
|
940
|
+
elementDefOrExtend[ $art ]*
|
|
944
941
|
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
945
942
|
{ this.checkExtensionDict( $art.elements ); }
|
|
946
943
|
optionalSemi
|
|
@@ -965,13 +962,13 @@ extendWithOptElementsOrType[ art ]
|
|
|
965
962
|
annotationAssignment_ll1[ $art ]*
|
|
966
963
|
(
|
|
967
964
|
'{' { $art.elements = this.createDict(); }
|
|
968
|
-
elementDefOrExtend[ $art
|
|
965
|
+
elementDefOrExtend[ $art ]*
|
|
969
966
|
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
970
967
|
{ this.checkExtensionDict( $art.elements ); }
|
|
971
968
|
optionalSemi
|
|
972
969
|
|
|
|
973
970
|
ELEMENTS { $art.elements = this.createDict(); } '{'
|
|
974
|
-
elementDefOrExtend[ $art ]*
|
|
971
|
+
elementDefOrExtend[ $art, true ]*
|
|
975
972
|
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
976
973
|
{ this.checkExtensionDict( $art.elements ); }
|
|
977
974
|
optionalSemi
|
|
@@ -995,7 +992,7 @@ extendWithOptElementsNoWith[ art ]
|
|
|
995
992
|
annotationAssignment_ll1[ $art ]*
|
|
996
993
|
(
|
|
997
994
|
'{' { $art.elements = this.createDict(); }
|
|
998
|
-
elementDefOrExtend[ $art
|
|
995
|
+
elementDefOrExtend[ $art ]*
|
|
999
996
|
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
1000
997
|
{ this.checkExtensionDict( $art.elements ); }
|
|
1001
998
|
optionalSemi
|
|
@@ -1006,7 +1003,7 @@ extendWithOptElementsNoWith[ art ]
|
|
|
1006
1003
|
|
|
1007
1004
|
// For `extend … with elements` or `extend entity … with`, `extend aspect … with`,
|
|
1008
1005
|
// i.e. definitions in { … } are never enums
|
|
1009
|
-
elementDefOrExtend[ outer,
|
|
1006
|
+
elementDefOrExtend[ outer, explicitElement = false ] locals[ art = new parser.XsnArtifact() ]
|
|
1010
1007
|
@after { /* #ATN 1 */ } // if ($art) this.attachLocation( $art ); }
|
|
1011
1008
|
:
|
|
1012
1009
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
@@ -1016,7 +1013,7 @@ elementDefOrExtend[ outer, mightBeEnum = false ] locals[ art = {} ]
|
|
|
1016
1013
|
EXTEND
|
|
1017
1014
|
extendElement[ $art, $outer ]
|
|
1018
1015
|
|
|
|
1019
|
-
elementDefInner[ $art, $outer, $
|
|
1016
|
+
elementDefInner[ $art, $outer, $explicitElement ]
|
|
1020
1017
|
)
|
|
1021
1018
|
;
|
|
1022
1019
|
|
|
@@ -1030,7 +1027,7 @@ extendElement[ art, outer ]
|
|
|
1030
1027
|
extendWithOptElementsOrType[ $art, $art ]
|
|
1031
1028
|
;
|
|
1032
1029
|
|
|
1033
|
-
annotateArtifact[ art, outer ] locals[ name =
|
|
1030
|
+
annotateArtifact[ art, outer ] locals[ name = new parser.XsnName(), elemName = new parser.XsnName() ]
|
|
1034
1031
|
@after { this.attachLocation( $art ); }
|
|
1035
1032
|
:
|
|
1036
1033
|
simplePath[ $name, 'Annotate' ]
|
|
@@ -1090,7 +1087,7 @@ annotateArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
|
1090
1087
|
)
|
|
1091
1088
|
;
|
|
1092
1089
|
|
|
1093
|
-
annotateElement[ outer ] locals[ art =
|
|
1090
|
+
annotateElement[ outer ] locals[ art = new parser.XsnArtifact() ]
|
|
1094
1091
|
@after{ this.attachLocation( $art ); }
|
|
1095
1092
|
:
|
|
1096
1093
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
@@ -1110,7 +1107,7 @@ annotateElement[ outer ] locals[ art = {} ]
|
|
|
1110
1107
|
)
|
|
1111
1108
|
;
|
|
1112
1109
|
|
|
1113
|
-
annotateAction [ outer ] locals [ art =
|
|
1110
|
+
annotateAction [ outer ] locals [ art = new parser.XsnArtifact() ]
|
|
1114
1111
|
@after{ this.attachLocation( $art ); }
|
|
1115
1112
|
:
|
|
1116
1113
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
@@ -1138,7 +1135,7 @@ annotateAction [ outer ] locals [ art = {} ]
|
|
|
1138
1135
|
annotateReturns[ art ]
|
|
1139
1136
|
@after{ this.attachLocation( $art.returns ); }
|
|
1140
1137
|
:
|
|
1141
|
-
ret=RETURNS { $art.returns =
|
|
1138
|
+
ret=RETURNS { $art.returns = new this.XsnArtifact();; $art.returns.kind = 'annotate'; }
|
|
1142
1139
|
{ this.docComment( $art.returns ); }
|
|
1143
1140
|
annotationAssignment_ll1[ $art.returns ]*
|
|
1144
1141
|
( '{' { $art.returns.elements = this.createDict(); }
|
|
@@ -1150,7 +1147,7 @@ annotateReturns[ art ]
|
|
|
1150
1147
|
)
|
|
1151
1148
|
;
|
|
1152
1149
|
|
|
1153
|
-
annotateParam [ outer ] locals [ art =
|
|
1150
|
+
annotateParam [ outer ] locals [ art = new parser.XsnArtifact() ]
|
|
1154
1151
|
@after{ this.attachLocation( $art ); }
|
|
1155
1152
|
:
|
|
1156
1153
|
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
@@ -1424,9 +1421,12 @@ typeAssociationCont[ art ]
|
|
|
1424
1421
|
)*
|
|
1425
1422
|
)?
|
|
1426
1423
|
'}' { this.finalizeDictOrArray( $art.foreignKeys ); }
|
|
1424
|
+
defaultAndNullability[ $art ]?
|
|
1427
1425
|
|
|
|
1428
1426
|
ON cond=condition
|
|
1429
1427
|
{ $art.on=$cond.cond; }
|
|
1428
|
+
|
|
|
1429
|
+
defaultAndNullability[ $art ]
|
|
1430
1430
|
)
|
|
1431
1431
|
;
|
|
1432
1432
|
|
|
@@ -1442,12 +1442,12 @@ typeAssociationElementCont[ art ] // including Composition
|
|
|
1442
1442
|
)*
|
|
1443
1443
|
)?
|
|
1444
1444
|
'}' { this.finalizeDictOrArray( $art.foreignKeys ); }
|
|
1445
|
-
|
|
1445
|
+
defaultAndNullability[ $art ]?
|
|
1446
1446
|
|
|
|
1447
1447
|
ON cond=condition
|
|
1448
1448
|
{ $art.on=$cond.cond; }
|
|
1449
1449
|
|
|
|
1450
|
-
|
|
1450
|
+
defaultAndNullability[ $art ]
|
|
1451
1451
|
)?
|
|
1452
1452
|
{ this.docComment( $art ); }
|
|
1453
1453
|
annotationAssignment_ll1[ $art ]*
|
|
@@ -1515,7 +1515,7 @@ nullability[ art ]
|
|
|
1515
1515
|
| n1=NULL
|
|
1516
1516
|
;
|
|
1517
1517
|
|
|
1518
|
-
foreignKey[ outer ] locals[ art =
|
|
1518
|
+
foreignKey[ outer ] locals[ art = new parser.XsnArtifact(), elem = {} ]
|
|
1519
1519
|
@after { this.attachLocation($art); }
|
|
1520
1520
|
:
|
|
1521
1521
|
simplePath[ $elem, 'ref' ] { $art.targetElement = $elem; }
|
|
@@ -1784,7 +1784,7 @@ tableTerm returns [ table ]
|
|
|
1784
1784
|
}
|
|
1785
1785
|
':' fromPath[ $table, 'ref']
|
|
1786
1786
|
)?
|
|
1787
|
-
( AS n1=ident['FromAlias'] { $table.name = $n1.id }
|
|
1787
|
+
( AS n1=ident['FromAlias'] { $table.name = $n1.id; }
|
|
1788
1788
|
| n2=identNoKeyword['FromAlias'] { $table.name = this.fragileAlias( $n2.id ); }
|
|
1789
1789
|
// if we would use rule `ident`, we would either had to make all JOIN
|
|
1790
1790
|
// kinds reserved or introduce ATN
|
|
@@ -1823,7 +1823,7 @@ fromPath[ qp, idkind ] returns[ dotAfterFilter = null ]
|
|
|
1823
1823
|
if (!$qp.scope) $qp.scope = $qp.path.length;
|
|
1824
1824
|
} }
|
|
1825
1825
|
'.' id=ident[$idkind] { this.pushIdent( $qp.path, $id.id ); }
|
|
1826
|
-
( fromArguments[ $id.id ] cardinalityAndFilter[ $id.id ]?
|
|
1826
|
+
( fromArguments[ $id.id ] cardinalityAndFilter[ $id.id ]?
|
|
1827
1827
|
{ if (!$dotAfterFilter) $dotAfterFilter = false; }
|
|
1828
1828
|
| cardinalityAndFilter[ $id.id ]
|
|
1829
1829
|
{ if (!$dotAfterFilter) $dotAfterFilter = false; }
|
|
@@ -1887,7 +1887,7 @@ selectItemDef[ outer ] locals[ art ]
|
|
|
1887
1887
|
star='*'
|
|
1888
1888
|
{ $outer.push( this.valueWithTokenLocation( '*', $star ) ); }
|
|
1889
1889
|
|
|
|
1890
|
-
{ $art =
|
|
1890
|
+
{ $art = new this.XsnArtifact();; this.docComment( $art ); }
|
|
1891
1891
|
annotationAssignment_atn[ $art ]*
|
|
1892
1892
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1893
1893
|
{ this.setLocalToken( 'VIRTUAL', 'VIRTUAL', /^([,.:\[@]|as)$/i ) ; } // not '{'
|
|
@@ -1904,7 +1904,7 @@ selectItemDefBody[ art, outer ] locals[ assoc ]
|
|
|
1904
1904
|
e=expression { $art.value = $e.expr; }
|
|
1905
1905
|
// we cannot use 'condition' instead, as long as we allow aliases without
|
|
1906
1906
|
// AS (using rule 'ident' instead of 'identNoKeyword') -> ambiguities
|
|
1907
|
-
( as=AS n1=ident['Item'] { $art.name = $n1.id }
|
|
1907
|
+
( as=AS n1=ident['Item'] { $art.name = $n1.id; }
|
|
1908
1908
|
| n2=ident['Item'] { $art.name = this.fragileAlias( $n2.id, true ); }
|
|
1909
1909
|
| { this.classifyImplicitName( 'Item', $e.expr ); }
|
|
1910
1910
|
)
|
|
@@ -1929,7 +1929,7 @@ selectItemDefBody[ art, outer ] locals[ assoc ]
|
|
|
1929
1929
|
|
|
|
1930
1930
|
selectItemInlineList[ $art, 'expand' ]
|
|
1931
1931
|
excludingClause[ $art ]?
|
|
1932
|
-
AS n1=ident['Item'] { $art.name = $n1.id }
|
|
1932
|
+
AS n1=ident['Item'] { $art.name = $n1.id; }
|
|
1933
1933
|
)
|
|
1934
1934
|
{ this.docComment( $art ); }
|
|
1935
1935
|
annotationAssignment_fix[ $art ]*
|
|
@@ -1995,7 +1995,7 @@ selectItemInlineDef[ outer ] locals[ art ]
|
|
|
1995
1995
|
star='*'
|
|
1996
1996
|
{ $outer.push( this.valueWithTokenLocation( '*', $star ) ); }
|
|
1997
1997
|
|
|
|
1998
|
-
{ $art =
|
|
1998
|
+
{ $art = new this.XsnArtifact();; this.docComment( $art ); }
|
|
1999
1999
|
annotationAssignment_atn[ $art ]*
|
|
2000
2000
|
selectItemDefBody[ $art, $outer ]
|
|
2001
2001
|
;
|
|
@@ -2312,7 +2312,7 @@ expressionTerm returns [ expr ] locals [ args = [] ]
|
|
|
2312
2312
|
)
|
|
2313
2313
|
;
|
|
2314
2314
|
|
|
2315
|
-
specialFunction returns [ ret = {} ] locals[ art =
|
|
2315
|
+
specialFunction returns [ ret = {} ] locals[ art = new parser.XsnArtifact() ]
|
|
2316
2316
|
:
|
|
2317
2317
|
ca=CAST '(' // see createArray() in action
|
|
2318
2318
|
{
|
|
@@ -2663,7 +2663,7 @@ annotationAssignment_fix[ art ] locals[ assignment ]
|
|
|
2663
2663
|
(
|
|
2664
2664
|
annotationAssignment_paren[ $art ]
|
|
2665
2665
|
|
|
|
2666
|
-
{ $assignment = { name:
|
|
2666
|
+
{ $assignment = { name: new this.XsnName() }; }
|
|
2667
2667
|
annotationPath[ $assignment.name, 'anno' ]
|
|
2668
2668
|
( '#' annotationPathVariant[ $assignment.name ] )?
|
|
2669
2669
|
{ this.warnIfColonFollows( $assignment ); }
|
|
@@ -2681,7 +2681,7 @@ annotationAssignment_ll1[ art ] locals[ assignment ]
|
|
|
2681
2681
|
(
|
|
2682
2682
|
annotationAssignment_paren[ $art ]
|
|
2683
2683
|
|
|
|
2684
|
-
{ $assignment = { name:
|
|
2684
|
+
{ $assignment = { name: new this.XsnName() }; }
|
|
2685
2685
|
annotationPath[ $assignment.name, 'anno' ]
|
|
2686
2686
|
( '#' annotationPathVariant[ $assignment.name ] )?
|
|
2687
2687
|
(
|
|
@@ -2703,7 +2703,7 @@ annotationAssignment_atn[ art ] locals[ assignment ]
|
|
|
2703
2703
|
(
|
|
2704
2704
|
annotationAssignment_paren[ $art ]
|
|
2705
2705
|
|
|
|
2706
|
-
{ $assignment = { name:
|
|
2706
|
+
{ $assignment = { name: new this.XsnName() }; }
|
|
2707
2707
|
annotationPath[ $assignment.name, 'anno' ]
|
|
2708
2708
|
// '#' is in the follow set of this rule, as it is used in rule "selectItemDef"
|
|
2709
2709
|
// before an "expression" which can start with a '#' for an enum value
|
|
@@ -2749,7 +2749,7 @@ annotationAssignment_paren[ art ]
|
|
|
2749
2749
|
')'
|
|
2750
2750
|
;
|
|
2751
2751
|
|
|
2752
|
-
annotationAssignment_1[ art ] locals[ assignment = { name:
|
|
2752
|
+
annotationAssignment_1[ art ] locals[ assignment = { name: new parser.XsnName() } ]
|
|
2753
2753
|
@after { this.assignAnnotation( $art, $assignment ); }
|
|
2754
2754
|
:
|
|
2755
2755
|
annotationPath[ $assignment.name, 'anno' ]
|
|
@@ -2865,7 +2865,7 @@ annoValueBase[ assignment ] locals [ seenEllipsis = false ]
|
|
|
2865
2865
|
')'
|
|
2866
2866
|
;
|
|
2867
2867
|
|
|
2868
|
-
flattenedValue[ assignment ] locals[ val = { name:
|
|
2868
|
+
flattenedValue[ assignment ] locals[ val = { name: new parser.XsnName() } ]
|
|
2869
2869
|
:
|
|
2870
2870
|
at='@'? annotationPath[ $val.name, 'name', $at ]
|
|
2871
2871
|
( '#' annotationPathVariant[ $val.name ] )?
|
|
@@ -2876,7 +2876,7 @@ flattenedValue[ assignment ] locals[ val = { name: {} } ]
|
|
|
2876
2876
|
{ $assignment['$'+'flatten'].push( $val ); }
|
|
2877
2877
|
;
|
|
2878
2878
|
|
|
2879
|
-
namedValue[ struct ] locals[ val = { name:
|
|
2879
|
+
namedValue[ struct ] locals[ val = { name: new parser.XsnName() } ]
|
|
2880
2880
|
:
|
|
2881
2881
|
at='@'? annotationPath[ $val.name, 'name', $at ]
|
|
2882
2882
|
( ':' { this.meltKeywordToIdentifier(true); }
|
|
@@ -6,6 +6,7 @@ const {
|
|
|
6
6
|
cdlNewLineRegEx,
|
|
7
7
|
} = require('./textUtils');
|
|
8
8
|
const { CompilerAssertion } = require('../base/error');
|
|
9
|
+
const { CsnLocation } = require('../compiler/classes');
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Strips and counts the indentation from the given string.
|
|
@@ -462,6 +463,7 @@ class MultiLineStringParser {
|
|
|
462
463
|
*/
|
|
463
464
|
_locationForCharacters(i, width) {
|
|
464
465
|
return {
|
|
466
|
+
__proto__: CsnLocation.prototype,
|
|
465
467
|
file: this.parser.filename,
|
|
466
468
|
line: this.token.line + this._lineInString,
|
|
467
469
|
endLine: this.token.line + this._lineInString,
|
package/lib/main.d.ts
CHANGED
|
@@ -466,6 +466,11 @@ declare namespace compiler {
|
|
|
466
466
|
*/
|
|
467
467
|
export class CompilationError extends Error {
|
|
468
468
|
constructor(messages: CompileMessage[], model?: any, text?: string, ...args: any[]);
|
|
469
|
+
/**
|
|
470
|
+
* String to identify this class. Can be used instead of relying on `instanceof`.
|
|
471
|
+
* @since v4.0.0
|
|
472
|
+
*/
|
|
473
|
+
code = 'ERR_CDS_COMPILATION_FAILURE';
|
|
469
474
|
messages: CompileMessage[];
|
|
470
475
|
toString(): string;
|
|
471
476
|
/**
|
package/lib/model/csnRefs.js
CHANGED
|
@@ -49,14 +49,14 @@
|
|
|
49
49
|
// inspectRef() - to enable caching.
|
|
50
50
|
//
|
|
51
51
|
// If any of these conditions are not given, our functions usually simply
|
|
52
|
-
//
|
|
52
|
+
// throw an exception (which might even be a plain TypeError), but it might
|
|
53
53
|
// also just return any value. CSN processors can provide user-friendly error
|
|
54
54
|
// messages by calling the Core Compiler in case of exceptions. For details,
|
|
55
55
|
// see internalDoc/CoreCompiler.md#use-of-the-core-compiler-for-csn-processors.
|
|
56
56
|
|
|
57
57
|
// During a transformation, care must be taken to adhere to these conditions.
|
|
58
58
|
// E.g. a structure flattening function cannot create an element `s_x` and
|
|
59
|
-
// delete `s` and then still
|
|
59
|
+
// delete `s` and then still expect inspectRef() to be able to resolve a
|
|
60
60
|
// reference `['s', 'x']`.
|
|
61
61
|
|
|
62
62
|
// There are currently 3 (SQL) backend issues for which we provide a workaround:
|
|
@@ -205,15 +205,14 @@ const artifactProperties = [ 'elements', 'columns', 'keys', 'mixin', 'enum',
|
|
|
205
205
|
// - lexical: false | Function - determines where to look first for “lexical names”
|
|
206
206
|
// - dynamic: String - describes the dynamic environment (if in query)
|
|
207
207
|
// - assoc: String, with dynamic: 'global' - what to do with assoc steps
|
|
208
|
-
// * 'static': visit elements of anonymous aspect if not last ref item
|
|
209
208
|
// * 'target': always follow target, including last ref item
|
|
210
|
-
// * other (& not provided) = follow target if not last ref item
|
|
209
|
+
// * other (& not provided) = follow target (targetAspect if no target) if not last ref item
|
|
211
210
|
const referenceSemantics = {
|
|
212
211
|
$init: { $initOnly: true },
|
|
213
|
-
type: { lexical: false, dynamic: 'global'
|
|
214
|
-
includes: { lexical: false, dynamic: 'global'
|
|
215
|
-
target: { lexical: false, dynamic: 'global'
|
|
216
|
-
targetAspect: { lexical: false, dynamic: 'global'
|
|
212
|
+
type: { lexical: false, dynamic: 'global' },
|
|
213
|
+
includes: { lexical: false, dynamic: 'global' },
|
|
214
|
+
target: { lexical: false, dynamic: 'global' },
|
|
215
|
+
targetAspect: { lexical: false, dynamic: 'global' },
|
|
217
216
|
from: { lexical: false, dynamic: 'global', assoc: 'target' },
|
|
218
217
|
keys: { lexical: false, dynamic: 'target' },
|
|
219
218
|
keys_origin: { lexical: false, dynamic: 'target' },
|
|
@@ -265,6 +264,9 @@ function csnRefs( csn, universalReady ) {
|
|
|
265
264
|
queryOrMain,
|
|
266
265
|
getColumn: elem => getCache( elem, '_column' ),
|
|
267
266
|
getElement: col => getCache( col, '_element' ),
|
|
267
|
+
/** Returns the column's name; either explicit, implicit or internal one. */
|
|
268
|
+
getColumnName: col => getCache( col, '$as' ),
|
|
269
|
+
$getQueries: def => getCache( def, '$queries' ), // unstable API
|
|
268
270
|
initDefinition,
|
|
269
271
|
dropDefinitionCache,
|
|
270
272
|
targetAspect,
|
|
@@ -314,7 +316,7 @@ function csnRefs( csn, universalReady ) {
|
|
|
314
316
|
env = effectiveType( env.items );
|
|
315
317
|
if (env.elements) // shortcut
|
|
316
318
|
return env;
|
|
317
|
-
const target = (staticAssoc ? targetAspect( env ) : env.target);
|
|
319
|
+
const target = (staticAssoc ? targetAspect( env ) : env.target || env.targetAspect);
|
|
318
320
|
if (typeof target !== 'string')
|
|
319
321
|
return target || env;
|
|
320
322
|
const def = csn.definitions[target];
|
|
@@ -352,7 +354,7 @@ function csnRefs( csn, universalReady ) {
|
|
|
352
354
|
|
|
353
355
|
function fromArtifactRef( ref ) {
|
|
354
356
|
// do not cache while there is second param
|
|
355
|
-
const art = artifactFromRef( ref
|
|
357
|
+
const art = artifactFromRef( ref );
|
|
356
358
|
if (art)
|
|
357
359
|
return art;
|
|
358
360
|
throw new ModelError( `Unknown artifact reference: ${ typeof ref !== 'string' ? JSON.stringify(ref.ref) : ref }` );
|
|
@@ -363,7 +365,7 @@ function csnRefs( csn, universalReady ) {
|
|
|
363
365
|
let art = csn.definitions[pathId( head )];
|
|
364
366
|
initDefinition( art );
|
|
365
367
|
for (const elem of tail) {
|
|
366
|
-
const env = navigationEnv( art
|
|
368
|
+
const env = navigationEnv( art );
|
|
367
369
|
art = env.elements[pathId( elem )];
|
|
368
370
|
}
|
|
369
371
|
return art;
|
|
@@ -758,7 +760,7 @@ function csnRefs( csn, universalReady ) {
|
|
|
758
760
|
qcache.elements = elements;
|
|
759
761
|
const { columns } = qcache._select;
|
|
760
762
|
if (elements && columns)
|
|
761
|
-
columns.map(
|
|
763
|
+
columns.map( (col, colIndex) => initColumnElement( col, colIndex, qcache ) );
|
|
762
764
|
else if (columns && !elements)
|
|
763
765
|
throw new ModelError( `Query elements not available: ${ Object.keys( (index ? qcache._select : main) ).join('+') }`);
|
|
764
766
|
} );
|
|
@@ -784,16 +786,19 @@ function csnRefs( csn, universalReady ) {
|
|
|
784
786
|
: { $aliases: Object.create(null), $next: pcache.$next };
|
|
785
787
|
}
|
|
786
788
|
|
|
787
|
-
function initColumnElement( col, parentElementOrQueryCache ) {
|
|
789
|
+
function initColumnElement( col, colIndex, parentElementOrQueryCache ) {
|
|
788
790
|
if (col === '*')
|
|
789
791
|
return;
|
|
790
792
|
if (col.inline) {
|
|
791
|
-
col.inline.map( c => initColumnElement( c, parentElementOrQueryCache ) );
|
|
793
|
+
col.inline.map( c => initColumnElement( c, null, parentElementOrQueryCache ) );
|
|
792
794
|
return;
|
|
793
795
|
}
|
|
794
796
|
setCache( col, '_parent', // not set for query (has property _select)
|
|
795
797
|
!parentElementOrQueryCache._select && parentElementOrQueryCache );
|
|
796
|
-
|
|
798
|
+
let as = columnAlias( col );
|
|
799
|
+
if (!as && colIndex !== null)
|
|
800
|
+
as = `$_column_${ colIndex + 1 }`;
|
|
801
|
+
setCache( col, '$as', as );
|
|
797
802
|
let type = parentElementOrQueryCache;
|
|
798
803
|
while (type.items)
|
|
799
804
|
type = type.items;
|
|
@@ -801,7 +806,7 @@ function csnRefs( csn, universalReady ) {
|
|
|
801
806
|
if (elem) // TODO to.sql: something is strange if this is not set
|
|
802
807
|
setCache( elem, '_column', col );
|
|
803
808
|
if (col.expand)
|
|
804
|
-
col.expand.map( c => initColumnElement( c, elem ) );
|
|
809
|
+
col.expand.map( c => initColumnElement( c, null, elem ) );
|
|
805
810
|
}
|
|
806
811
|
|
|
807
812
|
// property name convention in cache:
|
|
@@ -843,10 +848,11 @@ function csnRefs( csn, universalReady ) {
|
|
|
843
848
|
}
|
|
844
849
|
}
|
|
845
850
|
|
|
846
|
-
// Return value of a query SELECT for the query node, or the main artifact,
|
|
847
|
-
// i.e. a value with an `elements` property.
|
|
848
|
-
// TODO: only used in forRelationalDB - move somewhere else
|
|
849
851
|
/**
|
|
852
|
+
* Return value of a query SELECT for the query node, or the main artifact,
|
|
853
|
+
* i.e. a value with an `elements` property.
|
|
854
|
+
* TODO: only used in forRelationalDB - move somewhere else
|
|
855
|
+
*
|
|
850
856
|
* @param {object} query node (object with SET or SELECT property)
|
|
851
857
|
* @param {object} main definition
|
|
852
858
|
*/
|
|
@@ -1122,6 +1128,17 @@ function isSelectQuery( query ) {
|
|
|
1122
1128
|
return true;
|
|
1123
1129
|
}
|
|
1124
1130
|
|
|
1131
|
+
/**
|
|
1132
|
+
* Alias is either explicit or implicit from reference or function without arguments.
|
|
1133
|
+
* If the column is an expression without explicit alias, `false` is returned.
|
|
1134
|
+
* Use csnRefs.getColumnName() instead.
|
|
1135
|
+
*
|
|
1136
|
+
* @returns {string|false}
|
|
1137
|
+
*/
|
|
1138
|
+
function columnAlias( col ) {
|
|
1139
|
+
return col.as || (!col.args && col.func) || (col.ref && implicitAs( col.ref ));
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1125
1142
|
module.exports = {
|
|
1126
1143
|
csnRefs,
|
|
1127
1144
|
traverseQuery,
|
|
@@ -1129,4 +1146,5 @@ module.exports = {
|
|
|
1129
1146
|
implicitAs,
|
|
1130
1147
|
analyseCsnPath,
|
|
1131
1148
|
pathId,
|
|
1149
|
+
columnAlias,
|
|
1132
1150
|
};
|