@sap/cds-compiler 2.12.0 → 2.13.6
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 +110 -15
- package/bin/cdsc.js +13 -13
- package/bin/cdsse.js +2 -2
- package/doc/CHANGELOG_BETA.md +13 -6
- package/doc/CHANGELOG_DEPRECATED.md +22 -6
- package/doc/NameResolution.md +21 -16
- package/lib/api/main.js +28 -63
- package/lib/api/options.js +3 -3
- package/lib/api/validate.js +0 -5
- package/lib/backends.js +15 -23
- package/lib/base/dictionaries.js +0 -8
- package/lib/base/error.js +26 -0
- package/lib/base/keywords.js +7 -17
- package/lib/base/location.js +9 -4
- package/lib/base/message-registry.js +25 -4
- package/lib/base/messages.js +16 -26
- package/lib/base/model.js +2 -63
- package/lib/base/optionProcessorHelper.js +158 -123
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/cdsPersistence.js +2 -1
- package/lib/checks/enricher.js +17 -1
- package/lib/checks/invalidTarget.js +3 -1
- package/lib/checks/managedWithoutKeys.js +3 -1
- package/lib/checks/selectItems.js +4 -4
- package/lib/checks/sql-snippets.js +27 -26
- package/lib/checks/types.js +1 -1
- package/lib/checks/validator.js +4 -7
- package/lib/compiler/assert-consistency.js +5 -3
- package/lib/compiler/builtins.js +8 -6
- package/lib/compiler/checks.js +14 -3
- package/lib/compiler/cycle-detector.js +1 -1
- package/lib/compiler/define.js +1103 -0
- package/lib/compiler/extend.js +983 -0
- package/lib/compiler/finalize-parse-cdl.js +231 -0
- package/lib/compiler/index.js +32 -13
- package/lib/compiler/kick-start.js +190 -0
- package/lib/compiler/moduleLayers.js +4 -4
- package/lib/compiler/populate.js +1226 -0
- package/lib/compiler/propagator.js +111 -46
- package/lib/compiler/resolve.js +1433 -0
- package/lib/compiler/shared.js +64 -37
- package/lib/compiler/tweak-assocs.js +529 -0
- package/lib/compiler/utils.js +197 -33
- package/lib/edm/.eslintrc.json +5 -0
- package/lib/edm/annotations/genericTranslation.js +5 -9
- package/lib/edm/annotations/preprocessAnnotations.js +2 -2
- package/lib/edm/csn2edm.js +9 -8
- package/lib/edm/edm.js +11 -12
- package/lib/edm/edmPreprocessor.js +137 -73
- package/lib/edm/edmUtils.js +116 -22
- package/lib/gen/Dictionary.json +10 -3
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +9 -1
- package/lib/gen/language.tokens +86 -83
- package/lib/gen/languageLexer.interp +10 -1
- package/lib/gen/languageLexer.js +860 -833
- package/lib/gen/languageLexer.tokens +78 -75
- package/lib/gen/languageParser.js +5282 -4265
- package/lib/json/from-csn.js +12 -1
- package/lib/json/to-csn.js +126 -66
- package/lib/language/docCommentParser.js +2 -2
- package/lib/language/genericAntlrParser.js +76 -3
- package/lib/language/language.g4 +297 -130
- package/lib/language/multiLineStringParser.js +5 -5
- package/lib/main.d.ts +468 -59
- package/lib/main.js +35 -9
- package/lib/model/api.js +3 -1
- package/lib/model/csnRefs.js +225 -156
- package/lib/model/csnUtils.js +192 -223
- package/lib/model/enrichCsn.js +70 -29
- package/lib/model/revealInternalProperties.js +27 -6
- package/lib/model/sortViews.js +2 -1
- package/lib/modelCompare/compare.js +17 -12
- package/lib/optionProcessor.js +5 -4
- package/lib/render/manageConstraints.js +35 -32
- package/lib/render/toCdl.js +73 -288
- package/lib/render/toHdbcds.js +25 -23
- package/lib/render/toSql.js +98 -41
- package/lib/render/utils/common.js +5 -10
- package/lib/render/utils/sql.js +4 -3
- package/lib/render/utils/stringEscapes.js +111 -0
- package/lib/sql-identifier.js +1 -1
- package/lib/transform/.eslintrc.json +5 -0
- package/lib/transform/db/.eslintrc.json +2 -0
- package/lib/transform/db/applyTransformations.js +35 -12
- package/lib/transform/db/assertUnique.js +1 -1
- package/lib/transform/db/associations.js +103 -305
- package/lib/transform/db/cdsPersistence.js +2 -2
- package/lib/transform/db/constraints.js +55 -52
- package/lib/transform/db/expansion.js +46 -24
- package/lib/transform/db/flattening.js +553 -102
- package/lib/transform/db/groupByOrderBy.js +3 -1
- package/lib/transform/db/transformExists.js +59 -6
- package/lib/transform/db/views.js +5 -4
- package/lib/transform/draft/.eslintrc.json +38 -0
- package/lib/transform/{db/draft.js → draft/db.js} +6 -5
- package/lib/transform/draft/odata.js +227 -0
- package/lib/transform/forHanaNew.js +67 -183
- package/lib/transform/forOdataNew.js +17 -171
- package/lib/transform/localized.js +34 -19
- package/lib/transform/odata/generateForeignKeyElements.js +1 -1
- package/lib/transform/odata/referenceFlattener.js +95 -89
- package/lib/transform/odata/structureFlattener.js +1 -1
- package/lib/transform/odata/toFinalBaseType.js +86 -12
- package/lib/transform/odata/typesExposure.js +5 -5
- package/lib/transform/odata/utils.js +2 -2
- package/lib/transform/transformUtilsNew.js +36 -22
- package/lib/transform/translateAssocsToJoins.js +2 -19
- package/lib/transform/universalCsn/.eslintrc.json +36 -0
- package/lib/transform/universalCsn/coreComputed.js +170 -0
- package/lib/transform/universalCsn/universalCsnEnricher.js +715 -0
- package/lib/transform/universalCsn/utils.js +63 -0
- package/lib/utils/objectUtils.js +30 -0
- package/package.json +1 -1
- package/share/messages/README.md +26 -0
- package/lib/compiler/definer.js +0 -2361
- package/lib/compiler/resolver.js +0 -3079
- package/lib/transform/universalCsnEnricher.js +0 -237
package/lib/language/language.g4
CHANGED
|
@@ -393,7 +393,7 @@ artifactDef[ outer, defOnly = false ] locals[ annos = [] ] // cannot use `parent
|
|
|
393
393
|
| extendProjection[ $outer, this.startLocation(), $annos ]
|
|
394
394
|
| extendType[ $outer, this.startLocation(), $annos ]
|
|
395
395
|
| extendAspect[ $outer, this.startLocation(), $annos ]
|
|
396
|
-
|
|
396
|
+
// Streamlined Syntax
|
|
397
397
|
| extendArtifact[ $outer, this.startLocation(), $annos ]
|
|
398
398
|
)
|
|
399
399
|
|
|
|
@@ -418,7 +418,9 @@ contextDef[ outer, loc, annos, defOnly = false ] locals[ art, name = {} ]
|
|
|
418
418
|
this.docComment( $annos ); }
|
|
419
419
|
annotationAssignment_fix[ $annos ]*
|
|
420
420
|
(
|
|
421
|
-
'{'
|
|
421
|
+
'{' { $art.artifacts = this.createDict(); }
|
|
422
|
+
artifactDef[ $art, defOnly ]*
|
|
423
|
+
'}' { this.setDictEndLocation( $art.artifacts ); }
|
|
422
424
|
optionalSemi
|
|
423
425
|
|
|
|
424
426
|
requiredSemi
|
|
@@ -436,9 +438,9 @@ extendContext[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
436
438
|
{ this.docComment( $annos ); }
|
|
437
439
|
annotationAssignment_ll1[ $annos ]*
|
|
438
440
|
(
|
|
439
|
-
'{'
|
|
440
|
-
artifactDef[ $art, $service ? 'SERVICE' : 'CONTEXT'
|
|
441
|
-
'}'
|
|
441
|
+
'{' { $art.artifacts = this.createDict(); }
|
|
442
|
+
artifactDef[ $art, $service ? 'SERVICE' : 'CONTEXT' ]*
|
|
443
|
+
'}' { this.setDictEndLocation( $art.artifacts ); }
|
|
442
444
|
optionalSemi
|
|
443
445
|
|
|
|
444
446
|
requiredSemi
|
|
@@ -461,23 +463,35 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
461
463
|
)*
|
|
462
464
|
)?
|
|
463
465
|
'{'
|
|
464
|
-
{ $art.elements =
|
|
466
|
+
{ $art.elements = this.createDict(); } // better for include and annotate
|
|
465
467
|
elementDef[ $art ]*
|
|
466
|
-
'}'
|
|
468
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
467
469
|
// TODO: action definitions in a specific section?
|
|
468
|
-
(
|
|
470
|
+
(
|
|
471
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
472
|
+
actionFunctionDef[ $art ]*
|
|
473
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
474
|
+
)?
|
|
469
475
|
optionalSemi
|
|
470
476
|
|
|
|
471
477
|
AS
|
|
472
478
|
( qe=queryExpression
|
|
473
479
|
{ $art.query = $qe.query; $art['$'+'syntax'] = 'entity' }
|
|
474
|
-
(
|
|
480
|
+
(
|
|
481
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
482
|
+
actionFunctionDef[ $art ]*
|
|
483
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
484
|
+
optionalSemi
|
|
475
485
|
| requiredSemi
|
|
476
486
|
)
|
|
477
487
|
| qp=projectionSpec
|
|
478
488
|
{ $art.query = $qp.query; $art['$'+'syntax'] = 'projection'; }
|
|
479
489
|
projectionClauses[ $qp.query ]
|
|
480
|
-
(
|
|
490
|
+
(
|
|
491
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
492
|
+
actionFunctionDef[ $art ]*
|
|
493
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
494
|
+
)?
|
|
481
495
|
optionalSemi // TODO: not fully correct without columns or excluding
|
|
482
496
|
)
|
|
483
497
|
)
|
|
@@ -522,12 +536,12 @@ excludingClause[ query ]
|
|
|
522
536
|
:
|
|
523
537
|
// syntax is less than ideal - EXCLUDING is only useful for `*` - with
|
|
524
538
|
// this syntax, people wonder what happens with explicit select items
|
|
525
|
-
EXCLUDING '{'
|
|
539
|
+
EXCLUDING '{' { $query.excludingDict = this.createDict(); }
|
|
526
540
|
projectionExclusion[ $query ]
|
|
527
541
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
528
542
|
projectionExclusion[ $query ]
|
|
529
543
|
)*
|
|
530
|
-
'}'
|
|
544
|
+
'}' { this.setDictEndLocation( $query.excludingDict ); }
|
|
531
545
|
;
|
|
532
546
|
|
|
533
547
|
projectionExclusion[ outer ] locals[ art ]
|
|
@@ -562,13 +576,19 @@ extendEntity[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
562
576
|
|
|
563
577
|
extendForEntity[ art ]
|
|
564
578
|
:
|
|
565
|
-
'{'
|
|
579
|
+
'{' { $art.elements = this.createDict(); }
|
|
566
580
|
elementDefOrExtend[ $art ]*
|
|
567
|
-
'}'
|
|
568
|
-
(
|
|
581
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
582
|
+
(
|
|
583
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
584
|
+
actionFunctionDef[ $art ]*
|
|
585
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
586
|
+
)?
|
|
569
587
|
optionalSemi
|
|
570
588
|
|
|
|
571
|
-
ACTIONS '{'
|
|
589
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
590
|
+
actionFunctionDef[ $art ]*
|
|
591
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
572
592
|
optionalSemi
|
|
573
593
|
|
|
|
574
594
|
requiredSemi
|
|
@@ -594,10 +614,16 @@ extendProjection[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
594
614
|
)*
|
|
595
615
|
)?
|
|
596
616
|
'}'
|
|
597
|
-
(
|
|
617
|
+
(
|
|
618
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
619
|
+
actionFunctionDef[ $art ]*
|
|
620
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
621
|
+
)?
|
|
598
622
|
optionalSemi
|
|
599
623
|
|
|
|
600
|
-
ACTIONS '{'
|
|
624
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
625
|
+
actionFunctionDef[ $art ]*
|
|
626
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
601
627
|
optionalSemi
|
|
602
628
|
|
|
|
603
629
|
requiredSemi
|
|
@@ -702,12 +728,15 @@ aspectDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
702
728
|
)*
|
|
703
729
|
)?
|
|
704
730
|
)?
|
|
705
|
-
'{'
|
|
706
|
-
{ $art.elements = Object.create(null); } // better for include and annotate
|
|
731
|
+
'{' { $art.elements = this.createDict(); }
|
|
707
732
|
( elementDef[ $art ]* )
|
|
708
|
-
'}'
|
|
733
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
709
734
|
// TODO: action definitions in a specific section?
|
|
710
|
-
(
|
|
735
|
+
(
|
|
736
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
737
|
+
actionFunctionDef[ $art ]*
|
|
738
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
739
|
+
)?
|
|
711
740
|
optionalSemi
|
|
712
741
|
;
|
|
713
742
|
|
|
@@ -758,13 +787,82 @@ annotationDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
758
787
|
typeSpecSemi[ $art, $annos ] // also 'includes'...
|
|
759
788
|
;
|
|
760
789
|
|
|
761
|
-
extendArtifact[ outer, loc, annos ] locals[ art, name = {} ]
|
|
762
|
-
@after
|
|
790
|
+
extendArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
791
|
+
@after{ /* #ATN 1 */ this.attachLocation($art); }
|
|
763
792
|
:
|
|
764
793
|
simplePath[ $name, 'Extend' ]
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
794
|
+
(
|
|
795
|
+
{ $art = this.addItem( $outer, 'extensions', 'extend', $annos, { name: $name }, $loc ); }
|
|
796
|
+
|
|
|
797
|
+
':'
|
|
798
|
+
simplePath[ $elemName, 'ref']
|
|
799
|
+
{{
|
|
800
|
+
const def = this.addItem( $outer, 'extensions', 'extend', null, { name: $name }, $loc );
|
|
801
|
+
$art = this.artifactForElementAnnotateOrExtend( 'extend', def, $elemName.path, $annos, $loc );
|
|
802
|
+
}}
|
|
803
|
+
)
|
|
804
|
+
(
|
|
805
|
+
{ this.docComment( $annos ); }
|
|
806
|
+
annotationAssignment_ll1[ $annos ]*
|
|
807
|
+
(
|
|
808
|
+
'{' { $art.elements = this.createDict(); }
|
|
809
|
+
elementDefOrExtend[ $art ]*
|
|
810
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
811
|
+
optionalSemi
|
|
812
|
+
|
|
|
813
|
+
requiredSemi
|
|
814
|
+
)
|
|
815
|
+
|
|
|
816
|
+
WITH { this.noSemicolonHere(); this.docComment( $annos ); }
|
|
817
|
+
annotationAssignment_ll1[ $annos ]*
|
|
818
|
+
// #ATN: DEFINITIONS, COLUMNS, ACTIONS etc are not reserved and could be identifiers (ref).
|
|
819
|
+
(
|
|
820
|
+
includeRef[ $art ]
|
|
821
|
+
requiredSemi
|
|
822
|
+
|
|
|
823
|
+
'{' { $art.elements = this.createDict(); }
|
|
824
|
+
elementDefOrExtend[ $art ]*
|
|
825
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
826
|
+
optionalSemi
|
|
827
|
+
|
|
|
828
|
+
requiredSemi
|
|
829
|
+
|
|
|
830
|
+
{ this.disallowElementExtension( $elemName, $outer, 'definitions' ); }
|
|
831
|
+
DEFINITIONS
|
|
832
|
+
'{' { $art.artifacts = this.createDict(); }
|
|
833
|
+
artifactDef[ $art, true ]*
|
|
834
|
+
'}' { this.setDictEndLocation( $art.artifacts ); }
|
|
835
|
+
optionalSemi
|
|
836
|
+
|
|
|
837
|
+
{ this.disallowElementExtension( $elemName, $outer, 'columns' ); }
|
|
838
|
+
COLUMNS
|
|
839
|
+
'{' { $art.columns = []; }
|
|
840
|
+
(
|
|
841
|
+
selectItemDef[ $art.columns ]
|
|
842
|
+
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
843
|
+
selectItemDef[ $art.columns ]
|
|
844
|
+
)*
|
|
845
|
+
)?
|
|
846
|
+
'}'
|
|
847
|
+
optionalSemi
|
|
848
|
+
|
|
|
849
|
+
{ this.disallowElementExtension( $elemName, $outer, 'actions' ); }
|
|
850
|
+
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
851
|
+
actionFunctionDef[ $art ]*
|
|
852
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
853
|
+
optionalSemi
|
|
854
|
+
|
|
|
855
|
+
ELEMENTS '{' { $art.elements = this.createDict(); }
|
|
856
|
+
elementDefOrExtend[ $art ]*
|
|
857
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
858
|
+
optionalSemi
|
|
859
|
+
|
|
|
860
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
861
|
+
enumSymbolDef[ $art ]*
|
|
862
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
863
|
+
optionalSemi
|
|
864
|
+
)
|
|
865
|
+
)
|
|
768
866
|
;
|
|
769
867
|
|
|
770
868
|
extendWithOptElements[ art, annos ]
|
|
@@ -775,9 +873,9 @@ extendWithOptElements[ art, annos ]
|
|
|
775
873
|
includeRef[ $art ]
|
|
776
874
|
requiredSemi
|
|
777
875
|
|
|
|
778
|
-
'{'
|
|
876
|
+
'{' { $art.elements = this.createDict(); }
|
|
779
877
|
elementDefOrExtend[ $art ]*
|
|
780
|
-
'}'
|
|
878
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
781
879
|
optionalSemi
|
|
782
880
|
|
|
|
783
881
|
requiredSemi
|
|
@@ -786,59 +884,71 @@ extendWithOptElements[ art, annos ]
|
|
|
786
884
|
{ this.docComment( $annos ); }
|
|
787
885
|
annotationAssignment_ll1[ $annos ]*
|
|
788
886
|
(
|
|
789
|
-
'{'
|
|
887
|
+
'{' { $art.elements = this.createDict(); }
|
|
790
888
|
elementDefOrExtend[ $art ]*
|
|
791
|
-
'}'
|
|
889
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
792
890
|
optionalSemi
|
|
793
891
|
|
|
|
794
892
|
requiredSemi
|
|
795
893
|
)
|
|
796
894
|
;
|
|
797
895
|
|
|
798
|
-
annotateArtifact[ outer, loc, annos ] locals[ art, name = {} ]
|
|
896
|
+
annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
799
897
|
@after { this.attachLocation($art); }
|
|
800
898
|
:
|
|
801
899
|
simplePath[ $name, 'Annotate' ]
|
|
802
|
-
|
|
900
|
+
(
|
|
901
|
+
{ $art = this.addItem( $outer, 'extensions', 'annotate', $annos, { name: $name }, $loc ); }
|
|
902
|
+
|
|
|
903
|
+
':'
|
|
904
|
+
simplePath[ $elemName, 'ref']
|
|
905
|
+
{{
|
|
906
|
+
const def = this.addItem( $outer, 'extensions', 'annotate', null, { name: $name }, $loc );
|
|
907
|
+
$art = this.artifactForElementAnnotateOrExtend( 'annotate', def, $elemName.path, $annos, $loc );
|
|
908
|
+
}}
|
|
909
|
+
)
|
|
910
|
+
|
|
803
911
|
( WITH { this.noSemicolonHere(); } )?
|
|
804
912
|
{ this.docComment( $annos ); }
|
|
805
913
|
annotationAssignment_ll1[ $annos ]*
|
|
806
914
|
(
|
|
807
|
-
'{'
|
|
915
|
+
'{' { $art.elements = this.createDict(); }
|
|
808
916
|
annotateElement[ $art ]*
|
|
809
|
-
'}'
|
|
917
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
810
918
|
(
|
|
811
919
|
ACTIONS
|
|
812
|
-
'{'
|
|
920
|
+
'{' { $art.actions = this.createDict(); }
|
|
813
921
|
annotateAction[ $art ]*
|
|
814
|
-
'}'
|
|
922
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
815
923
|
)?
|
|
816
924
|
optionalSemi
|
|
817
925
|
|
|
|
818
926
|
ACTIONS
|
|
819
|
-
'{'
|
|
927
|
+
'{' { $art.actions = this.createDict(); }
|
|
820
928
|
annotateAction[ $art ]*
|
|
821
|
-
'}'
|
|
929
|
+
'}' { this.setDictEndLocation( $art.actions ); }
|
|
822
930
|
optionalSemi
|
|
823
931
|
|
|
|
824
|
-
'('
|
|
932
|
+
'(' { $art.params = this.createDict(); }
|
|
825
933
|
annotateParam[ $art ]
|
|
826
934
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
827
935
|
annotateParam[ $art ]
|
|
828
936
|
)*
|
|
829
|
-
')'
|
|
937
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
830
938
|
(
|
|
831
|
-
RETURNS
|
|
939
|
+
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
940
|
+
'{' { $art.elements = this.createDict(); }
|
|
832
941
|
annotateElement[ $art ]*
|
|
833
|
-
'}'
|
|
942
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
834
943
|
optionalSemi
|
|
835
944
|
|
|
|
836
945
|
requiredSemi
|
|
837
946
|
)
|
|
838
947
|
|
|
|
839
|
-
RETURNS
|
|
948
|
+
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
949
|
+
'{' { $art.elements = this.createDict(); }
|
|
840
950
|
annotateElement[ $art ]*
|
|
841
|
-
'}'
|
|
951
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
842
952
|
optionalSemi
|
|
843
953
|
|
|
844
954
|
|
|
|
@@ -856,9 +966,9 @@ annotateElement[ outer ] locals[ art, annos = [] ]
|
|
|
856
966
|
this.docComment( $annos ); }
|
|
857
967
|
annotationAssignment_ll1[ $annos ]*
|
|
858
968
|
(
|
|
859
|
-
'{'
|
|
969
|
+
'{' { $art.elements = this.createDict(); }
|
|
860
970
|
annotateElement[ $art ]*
|
|
861
|
-
'}'
|
|
971
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
862
972
|
optionalSemi
|
|
863
973
|
|
|
|
864
974
|
requiredSemi
|
|
@@ -875,17 +985,17 @@ annotateAction [ outer ] locals [ art, annos = [] ]
|
|
|
875
985
|
this.docComment( $annos ); }
|
|
876
986
|
annotationAssignment_ll1[ $annos ]*
|
|
877
987
|
(
|
|
878
|
-
'('
|
|
988
|
+
'(' { $art.params = this.createDict(); }
|
|
879
989
|
annotateParam[ $art ]
|
|
880
990
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
881
991
|
annotateParam[ $art ]
|
|
882
992
|
)*
|
|
883
|
-
')'
|
|
993
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
884
994
|
)?
|
|
885
995
|
(
|
|
886
|
-
RETURNS '{'
|
|
996
|
+
RETURNS '{' { $art.elements = this.createDict(); }
|
|
887
997
|
annotateElement[ $art ]*
|
|
888
|
-
'}'
|
|
998
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
889
999
|
optionalSemi
|
|
890
1000
|
|
|
|
891
1001
|
requiredSemi
|
|
@@ -929,6 +1039,12 @@ enumSymbolDef[ outer ] locals[ art, annos = [] ]
|
|
|
929
1039
|
requiredSemi
|
|
930
1040
|
;
|
|
931
1041
|
|
|
1042
|
+
defaultValue[ art ] locals[ elem, elements = {} ]
|
|
1043
|
+
:
|
|
1044
|
+
// TODO: We may support structured default values here.
|
|
1045
|
+
DEFAULT expr=expression { $art.default = $expr.expr; }
|
|
1046
|
+
;
|
|
1047
|
+
|
|
932
1048
|
elementDefOrExtend[ outer ] locals[ annos = [] ]
|
|
933
1049
|
@after { /* #ATN 1 */ if ($ctx.art) this.attachLocation($art.art); }
|
|
934
1050
|
// tool complains if I test for ($art)
|
|
@@ -995,7 +1111,7 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
995
1111
|
:
|
|
996
1112
|
// TODO: it would be excellent to remove ELEMENT...
|
|
997
1113
|
// or have a special ident rule without the ELEMENT
|
|
998
|
-
// Reason: it would be good for error
|
|
1114
|
+
// Reason: it would be good for error recovery to start a major block without LL1 ambiguity
|
|
999
1115
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1000
1116
|
{ this.setLocalToken( 'VIRTUAL', 'VIRTUAL', /^[:{@=}]$/ ); }
|
|
1001
1117
|
virtual=VIRTUAL? key=KEY?
|
|
@@ -1047,7 +1163,7 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1047
1163
|
)
|
|
1048
1164
|
|
|
|
1049
1165
|
(
|
|
1050
|
-
array=ARRAY of=OF
|
|
1166
|
+
array=ARRAY of=OF
|
|
1051
1167
|
{ $art.items = { location: this.tokenLocation( $array, $of ) }; }
|
|
1052
1168
|
| many=MANY
|
|
1053
1169
|
{ $art.items = { location: this.tokenLocation( $many ) };}
|
|
@@ -1065,10 +1181,9 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1065
1181
|
{ this.docComment( $annos ); }
|
|
1066
1182
|
annotationAssignment_ll1[ $annos ]*
|
|
1067
1183
|
(
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
'}'
|
|
1184
|
+
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1185
|
+
enumSymbolDef[ $art.items ]*
|
|
1186
|
+
'}' { this.setDictEndLocation( $art.items.enum ); }
|
|
1072
1187
|
misplacedAnnotations[ $annos, 'syntax-anno-after-enum' ]?
|
|
1073
1188
|
)?
|
|
1074
1189
|
)
|
|
@@ -1092,13 +1207,14 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1092
1207
|
typeRefOptArgs[ $art ]
|
|
1093
1208
|
{ this.docComment( $annos ); }
|
|
1094
1209
|
annotationAssignment_ll1[ $annos ]*
|
|
1095
|
-
(
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
'}'
|
|
1210
|
+
(
|
|
1211
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1212
|
+
enumSymbolDef[ $art ]*
|
|
1213
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1099
1214
|
elementProperties[ $art ]?
|
|
1100
1215
|
misplacedAnnotations[ $annos, 'syntax-anno-after-enum' ]?
|
|
1101
|
-
|
|
|
1216
|
+
|
|
|
1217
|
+
elementProperties[ $art ]
|
|
1102
1218
|
{ this.docComment( $annos ); }
|
|
1103
1219
|
annotationAssignment_ll1[ $annos ]*
|
|
1104
1220
|
)?
|
|
@@ -1249,7 +1365,7 @@ selectItemInlineDef[ outer ] locals[ annos = [] ]
|
|
|
1249
1365
|
|
|
1250
1366
|
parameterListDef[ art ]
|
|
1251
1367
|
:
|
|
1252
|
-
'('
|
|
1368
|
+
'(' { $art.params = this.createDict(); }
|
|
1253
1369
|
// also empty param list (we might do some hacking later to allow reserved words)
|
|
1254
1370
|
// see annotationAssignment_paren
|
|
1255
1371
|
(
|
|
@@ -1258,7 +1374,7 @@ parameterListDef[ art ]
|
|
|
1258
1374
|
parameterDef[ $art ]
|
|
1259
1375
|
)*
|
|
1260
1376
|
)?
|
|
1261
|
-
')'
|
|
1377
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
1262
1378
|
;
|
|
1263
1379
|
|
|
1264
1380
|
parameterDef[ outer ] locals[ art, annos = [] ]
|
|
@@ -1271,14 +1387,14 @@ parameterDef[ outer ] locals[ art, annos = [] ]
|
|
|
1271
1387
|
this.docComment( $annos ); }
|
|
1272
1388
|
annotationAssignment_fix[ $annos ]*
|
|
1273
1389
|
typeSpec[ $art ]
|
|
1274
|
-
|
|
1390
|
+
defaultValue[ $art ]?
|
|
1275
1391
|
{ this.docComment( $annos ); }
|
|
1276
1392
|
annotationAssignment_ll1[ $annos ]*
|
|
1277
1393
|
;
|
|
1278
1394
|
|
|
1279
1395
|
entityParameters[ art ]
|
|
1280
1396
|
:
|
|
1281
|
-
'('
|
|
1397
|
+
'(' { $art.params = this.createDict(); }
|
|
1282
1398
|
// also empty param list (we might do some hacking later to allow reserved words)
|
|
1283
1399
|
// see annotationAssignment_paren
|
|
1284
1400
|
(
|
|
@@ -1287,7 +1403,7 @@ entityParameters[ art ]
|
|
|
1287
1403
|
entityParameterDef[ $art ]
|
|
1288
1404
|
)*
|
|
1289
1405
|
)?
|
|
1290
|
-
')'
|
|
1406
|
+
')' { this.setDictEndLocation( $art.params ); }
|
|
1291
1407
|
;
|
|
1292
1408
|
|
|
1293
1409
|
entityParameterDef[ outer ] locals[ art, annos = [] ]
|
|
@@ -1300,7 +1416,7 @@ entityParameterDef[ outer ] locals[ art, annos = [] ]
|
|
|
1300
1416
|
this.docComment( $annos ); }
|
|
1301
1417
|
annotationAssignment_fix[ $annos ]*
|
|
1302
1418
|
typeSpec[ $art ]
|
|
1303
|
-
|
|
1419
|
+
defaultValue[ $art ]?
|
|
1304
1420
|
{ this.docComment( $annos ); }
|
|
1305
1421
|
annotationAssignment_ll1[ $annos ]*
|
|
1306
1422
|
;
|
|
@@ -1316,17 +1432,11 @@ nullability[ art ]
|
|
|
1316
1432
|
|
|
1317
1433
|
elementProperties[ elem ]
|
|
1318
1434
|
:
|
|
1319
|
-
nullability[$elem]
|
|
1320
|
-
|
|
1321
|
-
DEFAULT expr=expression
|
|
1322
|
-
{ $elem.default = $expr.expr; }
|
|
1323
|
-
)?
|
|
1435
|
+
nullability[ $elem ]
|
|
1436
|
+
defaultValue[ $elem ]?
|
|
1324
1437
|
|
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
{ $elem.default = $expr.expr; }
|
|
1328
|
-
)
|
|
1329
|
-
nullability[$elem]?
|
|
1438
|
+
defaultValue[ $elem ]
|
|
1439
|
+
nullability[ $elem ]?
|
|
1330
1440
|
|
|
|
1331
1441
|
eq='='
|
|
1332
1442
|
{ this.notSupportedYet( 'Calculated fields are not supported yet', $eq ); }
|
|
@@ -1377,10 +1487,10 @@ typeSpec[ art ] // for params
|
|
|
1377
1487
|
// TODO: no LOCALIZED ?
|
|
1378
1488
|
| typeRefOptArgs[ $art ]
|
|
1379
1489
|
nullability[ $art ]?
|
|
1380
|
-
(
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
'}'
|
|
1490
|
+
(
|
|
1491
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1492
|
+
enumSymbolDef[ $art ]*
|
|
1493
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1384
1494
|
)?
|
|
1385
1495
|
)
|
|
1386
1496
|
;
|
|
@@ -1390,7 +1500,7 @@ returnTypeSpec[ art, annos ]
|
|
|
1390
1500
|
:
|
|
1391
1501
|
ret=RETURNS { $art.returns = { location: this.tokenLocation( $ret ), kind: 'param' }; }
|
|
1392
1502
|
// #ATN: typeSimple can start with ARRAY or TYPE
|
|
1393
|
-
( typeStruct[ $art.returns ]
|
|
1503
|
+
( typeStruct[ $art.returns ]
|
|
1394
1504
|
nullability[ $art.returns ]?
|
|
1395
1505
|
| typeArray[ $art.returns ] // nullability is set in typeArray
|
|
1396
1506
|
| typeTypeOf[ $art.returns ]
|
|
@@ -1398,11 +1508,12 @@ returnTypeSpec[ art, annos ]
|
|
|
1398
1508
|
// TODO: no LOCALIZED ?
|
|
1399
1509
|
| typeRefOptArgs[ $art.returns ]
|
|
1400
1510
|
nullability[ $art.returns ]?
|
|
1401
|
-
(
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
'}'
|
|
1405
|
-
|
|
|
1511
|
+
(
|
|
1512
|
+
ENUM '{' { $art.returns.enum = this.createDict(); }
|
|
1513
|
+
enumSymbolDef[ $art.returns ]*
|
|
1514
|
+
'}' { this.setDictEndLocation( $art.returns.enum ); }
|
|
1515
|
+
|
|
|
1516
|
+
misplacedAnnotations[ $annos, 'syntax-anno-after-params' ]
|
|
1406
1517
|
)?
|
|
1407
1518
|
)
|
|
1408
1519
|
|
|
@@ -1443,7 +1554,7 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1443
1554
|
{ $art.items = { location: this.tokenLocation( $many ) };}
|
|
1444
1555
|
)
|
|
1445
1556
|
// #ATN: typeRefOptArgs can start with TYPE
|
|
1446
|
-
( typeStruct[ $art.items ]
|
|
1557
|
+
( typeStruct[ $art.items ]
|
|
1447
1558
|
nullability[ $art.items ]?
|
|
1448
1559
|
optionalSemi
|
|
1449
1560
|
| typeTypeOf[ $art.items ]
|
|
@@ -1455,21 +1566,24 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1455
1566
|
nullability[ $art.items ]?
|
|
1456
1567
|
{ this.docComment( $annos ); }
|
|
1457
1568
|
annotationAssignment_ll1[ $annos ]*
|
|
1458
|
-
(
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
'}'
|
|
1462
|
-
optionalSemi
|
|
1463
|
-
|
|
|
1569
|
+
(
|
|
1570
|
+
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1571
|
+
enumSymbolDef[ $art.items ]*
|
|
1572
|
+
'}' { this.setDictEndLocation( $art.items.enum ); }
|
|
1573
|
+
optionalSemi
|
|
1574
|
+
|
|
|
1575
|
+
requiredSemi
|
|
1464
1576
|
)
|
|
1465
1577
|
)
|
|
1466
1578
|
|
|
|
1467
1579
|
typeTypeOf[ $art ]
|
|
1580
|
+
defaultValue[ $art ]?
|
|
1468
1581
|
{ this.docComment( $annos ); }
|
|
1469
1582
|
annotationAssignment_ll1[ $annos ]* requiredSemi
|
|
1470
1583
|
|
|
|
1471
1584
|
l=LOCALIZED { $art.localized = this.valueWithTokenLocation( true, $l ); }
|
|
1472
1585
|
typeRefOptArgs[ $art ]
|
|
1586
|
+
defaultValue[ $art ]?
|
|
1473
1587
|
{ this.docComment( $annos ); }
|
|
1474
1588
|
annotationAssignment_ll1[ $annos ]*
|
|
1475
1589
|
requiredSemi
|
|
@@ -1500,12 +1614,19 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1500
1614
|
')'
|
|
1501
1615
|
{ this.docComment( $annos ); }
|
|
1502
1616
|
annotationAssignment_ll1[ $annos ]*
|
|
1503
|
-
(
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
'}'
|
|
1507
|
-
|
|
1508
|
-
|
|
1617
|
+
(
|
|
1618
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1619
|
+
enumSymbolDef[ $art ]*
|
|
1620
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1621
|
+
(
|
|
1622
|
+
optionalSemi
|
|
1623
|
+
|
|
|
1624
|
+
defaultValue[ $art ]
|
|
1625
|
+
requiredSemi
|
|
1626
|
+
)
|
|
1627
|
+
|
|
|
1628
|
+
defaultValue[ $art ]?
|
|
1629
|
+
requiredSemi
|
|
1509
1630
|
)
|
|
1510
1631
|
|
|
|
1511
1632
|
':' // with element, e.g. `type T : E:elem enum { ... }`
|
|
@@ -1513,22 +1634,36 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1513
1634
|
simplePath[ $art.type, 'ref']
|
|
1514
1635
|
{ this.docComment( $annos ); }
|
|
1515
1636
|
annotationAssignment_ll1[ $annos ]*
|
|
1516
|
-
(
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
'}'
|
|
1520
|
-
|
|
1521
|
-
|
|
1637
|
+
(
|
|
1638
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1639
|
+
enumSymbolDef[ $art ]*
|
|
1640
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1641
|
+
(
|
|
1642
|
+
optionalSemi
|
|
1643
|
+
|
|
|
1644
|
+
defaultValue[ $art ]
|
|
1645
|
+
requiredSemi
|
|
1646
|
+
)
|
|
1647
|
+
|
|
|
1648
|
+
defaultValue[ $art ]?
|
|
1649
|
+
requiredSemi
|
|
1522
1650
|
)
|
|
1523
1651
|
|
|
|
1524
1652
|
{ this.docComment( $annos ); }
|
|
1525
1653
|
annotationAssignment_ll1[ $annos ]*
|
|
1526
|
-
(
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
'}'
|
|
1530
|
-
|
|
1531
|
-
|
|
1654
|
+
(
|
|
1655
|
+
ENUM '{' { $art.enum = this.createDict(); }
|
|
1656
|
+
enumSymbolDef[ $art ]*
|
|
1657
|
+
'}' { this.setDictEndLocation( $art.enum ); }
|
|
1658
|
+
(
|
|
1659
|
+
optionalSemi
|
|
1660
|
+
|
|
|
1661
|
+
defaultValue[ $art ]
|
|
1662
|
+
requiredSemi
|
|
1663
|
+
)
|
|
1664
|
+
|
|
|
1665
|
+
defaultValue[ $art ]?
|
|
1666
|
+
requiredSemi
|
|
1532
1667
|
)
|
|
1533
1668
|
|
|
|
1534
1669
|
// TODO: complain if used in anno def?
|
|
@@ -1545,15 +1680,17 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1545
1680
|
typeStruct[ art, attachLoc = false ]
|
|
1546
1681
|
@after { if ($attachLoc) this.attachLocation($art); }
|
|
1547
1682
|
:
|
|
1548
|
-
{ $art.elements =
|
|
1549
|
-
|
|
1683
|
+
'{' { $art.elements = this.createDict(); }
|
|
1684
|
+
elementDef[ $art ]*
|
|
1685
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
1550
1686
|
;
|
|
1551
1687
|
|
|
1552
1688
|
typeCompoStruct[ art ]
|
|
1553
1689
|
@after { this.attachLocation($art); }
|
|
1554
1690
|
:
|
|
1555
|
-
{ $art.elements =
|
|
1556
|
-
|
|
1691
|
+
COMPOSITIONofBRACE { $art.elements = this.createDict(); }
|
|
1692
|
+
elementDef[ $art ]*
|
|
1693
|
+
'}' { this.setDictEndLocation( $art.elements ); }
|
|
1557
1694
|
;
|
|
1558
1695
|
|
|
1559
1696
|
typeArray[ art ]
|
|
@@ -1572,10 +1709,10 @@ typeArray[ art ]
|
|
|
1572
1709
|
nullability[ $art.items ]?
|
|
1573
1710
|
| typeRefOptArgs[ $art.items ]
|
|
1574
1711
|
nullability[ $art.items ]?
|
|
1575
|
-
(
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
'}'
|
|
1712
|
+
(
|
|
1713
|
+
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1714
|
+
enumSymbolDef[ $art.items ]*
|
|
1715
|
+
'}' { this.setDictEndLocation( $art.items.enum ); }
|
|
1579
1716
|
)?
|
|
1580
1717
|
)
|
|
1581
1718
|
;
|
|
@@ -1603,7 +1740,7 @@ typeAssociationBase[ art, handleTypeCompo ] // including Composition
|
|
|
1603
1740
|
typeAssociationCont[ art ]
|
|
1604
1741
|
:
|
|
1605
1742
|
(
|
|
1606
|
-
'{'
|
|
1743
|
+
'{' { $art.foreignKeys = this.createDict(); }
|
|
1607
1744
|
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1608
1745
|
(
|
|
1609
1746
|
foreignKey[ $art ]
|
|
@@ -1611,7 +1748,7 @@ typeAssociationCont[ art ]
|
|
|
1611
1748
|
foreignKey[ $art ]
|
|
1612
1749
|
)*
|
|
1613
1750
|
)?
|
|
1614
|
-
'}'
|
|
1751
|
+
'}' { this.setDictEndLocation( $art.foreignKeys ); }
|
|
1615
1752
|
|
|
|
1616
1753
|
ON cond=condition
|
|
1617
1754
|
{ $art.on=$cond.cond; }
|
|
@@ -1622,7 +1759,7 @@ typeAssociationElementCont[ art, annos ] // including Composition
|
|
|
1622
1759
|
// optional NULL / NOT NULL for managed association only
|
|
1623
1760
|
:
|
|
1624
1761
|
(
|
|
1625
|
-
'{'
|
|
1762
|
+
'{' { $art.foreignKeys = this.createDict(); }
|
|
1626
1763
|
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1627
1764
|
(
|
|
1628
1765
|
foreignKey[ $art ]
|
|
@@ -1630,7 +1767,7 @@ typeAssociationElementCont[ art, annos ] // including Composition
|
|
|
1630
1767
|
foreignKey[ $art ]
|
|
1631
1768
|
)*
|
|
1632
1769
|
)?
|
|
1633
|
-
'}'
|
|
1770
|
+
'}' { this.setDictEndLocation( $art.foreignKeys ); }
|
|
1634
1771
|
nullability[ $art ]?
|
|
1635
1772
|
|
|
|
1636
1773
|
ON cond=condition
|
|
@@ -1770,14 +1907,26 @@ orderByClause[ inQuery ] returns [ query ]
|
|
|
1770
1907
|
( ',' obn=orderBySpec { $query.orderBy.push( $obn.ob ); } )*
|
|
1771
1908
|
;
|
|
1772
1909
|
|
|
1910
|
+
// Generic function ORDER BY clause, e.g. `first_value(id order by name)`
|
|
1911
|
+
// lhsExpr is the left expression of the ORDER BY clause.
|
|
1912
|
+
functionOrderByClause[ lhsExpr ] returns [ expr ]
|
|
1913
|
+
@after { this.attachLocation( $expr ); }
|
|
1914
|
+
:
|
|
1915
|
+
o=ORDER b=BY { $expr = { op: this.valueWithTokenLocation( 'orderBy', $o, $b ) , args: [ $lhsExpr ] }}
|
|
1916
|
+
ob1=orderBySpec { $expr.args.push( $ob1.ob ); }
|
|
1917
|
+
( ',' obn=orderBySpec { $expr.args.push( $obn.ob ); } )*
|
|
1918
|
+
;
|
|
1919
|
+
|
|
1773
1920
|
overOrderByClause returns [ expr ]
|
|
1921
|
+
@after { this.attachLocation( $expr ); }
|
|
1774
1922
|
:
|
|
1775
|
-
o=ORDER b=BY { $expr = { op: this.valueWithTokenLocation( '
|
|
1923
|
+
o=ORDER b=BY { $expr = { op: this.valueWithTokenLocation( 'overOrderBy', $o, $b ) , args: [] }}
|
|
1776
1924
|
ob1=orderBySpec { $expr.args.push( $ob1.ob ); }
|
|
1777
1925
|
( ',' obn=orderBySpec { $expr.args.push( $obn.ob ); } )*
|
|
1778
1926
|
;
|
|
1779
1927
|
|
|
1780
1928
|
partitionByClause returns [ expr ]
|
|
1929
|
+
@after { this.attachLocation( $expr ); }
|
|
1781
1930
|
:
|
|
1782
1931
|
p=PARTITION b=BY { $expr = { op: this.valueWithTokenLocation( 'partitionBy', $p, $b ) , args: [] }}
|
|
1783
1932
|
e1=expression { $expr.args.push( $e1.expr ); }
|
|
@@ -1785,12 +1934,14 @@ partitionByClause returns [ expr ]
|
|
|
1785
1934
|
;
|
|
1786
1935
|
|
|
1787
1936
|
windowFrameClause returns [ wf ]
|
|
1937
|
+
@after { this.attachLocation( $wf ); }
|
|
1788
1938
|
:
|
|
1789
1939
|
r=ROWS { $wf = { op: this.valueWithTokenLocation( 'rows', $r ) , args: [] }}
|
|
1790
1940
|
wfe=windowFrameExtentSpec { $wf.args.push( $wfe.wfe ); }
|
|
1791
1941
|
;
|
|
1792
1942
|
|
|
1793
1943
|
windowFrameExtentSpec returns[ wfe ]
|
|
1944
|
+
@after { this.attachLocation( $wfe ); }
|
|
1794
1945
|
:
|
|
1795
1946
|
{ $wfe = {} }
|
|
1796
1947
|
windowFrameStartSpec [ $wfe ]
|
|
@@ -1820,6 +1971,7 @@ windowFrameBoundSpec returns [ wfb ]
|
|
|
1820
1971
|
;
|
|
1821
1972
|
|
|
1822
1973
|
windowFrameStartSpec [ wf ]
|
|
1974
|
+
@after { this.attachLocation( $wf ); }
|
|
1823
1975
|
:
|
|
1824
1976
|
u=UNBOUNDED p=PRECEDING
|
|
1825
1977
|
{
|
|
@@ -1832,7 +1984,7 @@ windowFrameStartSpec [ wf ]
|
|
|
1832
1984
|
$wf.op = this.valueWithTokenLocation( 'preceding', $p );
|
|
1833
1985
|
$wf.args = [ this.numberLiteral( $n ) ];
|
|
1834
1986
|
}
|
|
1835
|
-
|
|
|
1987
|
+
|
|
|
1836
1988
|
c=CURRENT r=ROW
|
|
1837
1989
|
{
|
|
1838
1990
|
$wf.op = this.valueWithTokenLocation( 'currentRow', $c, $r );
|
|
@@ -1841,7 +1993,7 @@ windowFrameStartSpec [ wf ]
|
|
|
1841
1993
|
;
|
|
1842
1994
|
|
|
1843
1995
|
overClause returns [ over ]
|
|
1844
|
-
@after { this.attachLocation($over); }
|
|
1996
|
+
@after { this.attachLocation( $over ); }
|
|
1845
1997
|
:
|
|
1846
1998
|
o=OVER { $over = { op: this.valueWithTokenLocation( 'over', $o ) , args: [] } }
|
|
1847
1999
|
'('
|
|
@@ -1895,9 +2047,10 @@ queryPrimary returns[ query = {} ]
|
|
|
1895
2047
|
(
|
|
1896
2048
|
FROM querySource[ $query ]
|
|
1897
2049
|
(
|
|
1898
|
-
mixin=MIXIN '{'
|
|
2050
|
+
mixin=MIXIN '{' { $query.mixin = this.createDict(); }
|
|
1899
2051
|
mixinElementDef[ $query ]*
|
|
1900
|
-
'}'
|
|
2052
|
+
'}' { this.setDictEndLocation( $query.mixin ); }
|
|
2053
|
+
INTO
|
|
1901
2054
|
)?
|
|
1902
2055
|
( ad=( ALL | DISTINCT ) // TODO: or directly after SELECT ?
|
|
1903
2056
|
{ $query.quantifier = this.valueWithTokenLocation( $ad.text.toLowerCase(), $ad ); }
|
|
@@ -2351,6 +2504,7 @@ fromArguments[ pathStep ]
|
|
|
2351
2504
|
pathArguments[ pathStep, considerSpecial ]
|
|
2352
2505
|
@after{ /* #ATN 1 */ }
|
|
2353
2506
|
:
|
|
2507
|
+
{ this.excludeExpected([ 'ORDER' ]); }
|
|
2354
2508
|
paren='('
|
|
2355
2509
|
{ this.prepareGenericKeywords( $considerSpecial ); }
|
|
2356
2510
|
// ATN, LL2: Identifier can start both named arguments and the positional.
|
|
@@ -2372,6 +2526,13 @@ pathArguments[ pathStep, considerSpecial ]
|
|
|
2372
2526
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2373
2527
|
funcExpression[ $pathStep, $considerSpecial ]
|
|
2374
2528
|
)*
|
|
2529
|
+
// Note: We can't move this into funcExpression, or we would increase the ATN count because of `,` amiguity.
|
|
2530
|
+
( ob=functionOrderByClause[ $pathStep.args[$pathStep.args.length - 1] ]
|
|
2531
|
+
{
|
|
2532
|
+
// Remove the last entry which was copied to $ob.expr and push $ob.expr.
|
|
2533
|
+
$pathStep.args[$pathStep.args.length - 1] = $ob.expr;
|
|
2534
|
+
}
|
|
2535
|
+
)?
|
|
2375
2536
|
|
|
|
2376
2537
|
a=ALL { $pathStep.quantifier = this.valueWithTokenLocation( 'all', $a ); }
|
|
2377
2538
|
e1=expression { $pathStep.args = [ $e1.expr ]; }
|
|
@@ -2679,6 +2840,7 @@ ident[ category ] returns[ id ]
|
|
|
2679
2840
|
| ASSOCIATION
|
|
2680
2841
|
| BETWEEN
|
|
2681
2842
|
| BOTH
|
|
2843
|
+
| COLUMNS
|
|
2682
2844
|
| COMPOSITION
|
|
2683
2845
|
| CONTEXT
|
|
2684
2846
|
| CROSS
|
|
@@ -2686,8 +2848,10 @@ ident[ category ] returns[ id ]
|
|
|
2686
2848
|
| DAY
|
|
2687
2849
|
| DEFAULT
|
|
2688
2850
|
| DEFINE
|
|
2851
|
+
| DEFINITIONS
|
|
2689
2852
|
| DESC
|
|
2690
2853
|
| ELEMENT
|
|
2854
|
+
| ELEMENTS
|
|
2691
2855
|
| ELSE
|
|
2692
2856
|
| END
|
|
2693
2857
|
| ENTITY
|
|
@@ -2883,6 +3047,7 @@ ASPECT : [aA][sS][pP][eE][cC][tT] ;
|
|
|
2883
3047
|
ASSOCIATION : [aA][sS][sS][oO][cC][iI][aA][tT][iI][oO][nN] ;
|
|
2884
3048
|
BETWEEN : [bB][eE][tT][wW][eE][eE][nN] ;
|
|
2885
3049
|
BOTH : [bB][oO][tT][hH] ;
|
|
3050
|
+
COLUMNS : [cC][oO][lL][uU][mM][nN][sS];
|
|
2886
3051
|
COMPOSITION : [cC][oO][mM][pP][oO][sS][iI][tT][iI][oO][nN] ;
|
|
2887
3052
|
CONTEXT : [cC][oO][nN][tT][eE][xX][tT] ;
|
|
2888
3053
|
CROSS : [cC][rR][oO][sS][sS] ;
|
|
@@ -2890,8 +3055,10 @@ CURRENT : [cC][uU][rR][rR][eE][nN][tT] ;
|
|
|
2890
3055
|
DAY : [dD][aA][yY] ;
|
|
2891
3056
|
DEFAULT : [dD][eE][fF][aA][uU][lL][tT] ;
|
|
2892
3057
|
DEFINE : [dD][eE][fF][iI][nN][eE] ;
|
|
3058
|
+
DEFINITIONS : [dD][eE][fF][iI][nN][iI][tT][iI][oO][nN][sS] ;
|
|
2893
3059
|
DESC : [dD][eE][sS][cC] ;
|
|
2894
3060
|
ELEMENT : [eE][lL][eE][mM][eE][nN][tT] ;
|
|
3061
|
+
ELEMENTS : [eE][lL][eE][mM][eE][nN][tT][sS] ;
|
|
2895
3062
|
ELSE : [eE][lL][sS][eE] ;
|
|
2896
3063
|
END : [eE][nN][dD] ;
|
|
2897
3064
|
ENTITY : [eE][nN][tT][iI][tT][yY] ;
|