From 53067f1b30032e3206ce5d3394506ec897151d99 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Mon, 28 Feb 2022 16:53:44 -0800 Subject: [PATCH 01/14] Add CQL spatial predicates and literals --- FEATURES.md | 8 +- hugo/content/usage/cql.md | 74 +- hugo/content/usage/query_data.md | 10 + hugo/content/usage/query_function.md | 10 + internal/api/api.go | 2 + internal/api/openapi.go | 18 + internal/cql/CQL.g4 | 42 +- internal/cql/CQL.tokens | 181 +-- internal/cql/CqlLexer.g4 | 39 +- internal/cql/CqlLexer.tokens | 181 +-- internal/cql/cql.go | 139 +- internal/cql/cql_base_listener.go | 68 +- internal/cql/cql_lexer.go | 999 ++++++------ internal/cql/cql_listener.go | 68 +- internal/cql/cql_parser.go | 2169 +++++++++----------------- internal/cql/cql_test.go | 57 +- internal/data/db_sql.go | 1 + internal/service/handler.go | 6 +- internal/service/param.go | 11 +- testing/pgfs_test.md | 29 +- 20 files changed, 1769 insertions(+), 2343 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index f92d6d0f..840c0df2 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -44,8 +44,8 @@ It includes [*OGC API - Features*](http://docs.opengeospatial.org/is/17-069r3/17 - `sortby=name`, `sortby=+name`, `sortby=-name` - [x] filtering by property value ( `name=value`, as per [spec sec. 7.15.5](http://docs.opengeospatial.org/is/17-069r3/17-069r3.html#_parameters_for_filtering_on_feature_properties) ) - [x] `filter` with CQL expressions (see below) -- [ ] `filter-lang` -- [ ] `filter-crs` +- [ ] `filter-lang` (only CQL-Text is supported) +- [ ] `filter-crs=srid` ### Query parameters - Extension - [x] `precision` to set output precision of GeoJSON coordinates @@ -64,7 +64,7 @@ It includes [*OGC API - Features*](http://docs.opengeospatial.org/is/17-069r3/17 - [x] property names - [x] character literals - [x] numeric literals -- [ ] spatial literals +- [x] spatial literals - [ ] temporal literals - [x] binary comparisons (`<`,`<=`,`>`,`>=`,`=`,`<>`) - [x] `property [NOT] BETWEEN a AND B` @@ -73,7 +73,7 @@ It includes [*OGC API - Features*](http://docs.opengeospatial.org/is/17-069r3/17 - `pattern` can include `%` wildcards - [x] `property [NOT] IS NULL` - [x] boolean combinations (`AND`,`OR`,`NOT`) -- [ ] spatial predicates +- [x] spatial predicates - [ ] temporal predicates - [ ] functions diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index 3de0d161..154243a9 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -7,7 +7,7 @@ weight: 175 The features returned by `items` queries can be filtered using the `filter` query parameter with an expression written using -the Common Query Language (CQL). +the [Common Query Language](https://portal.ogc.org/files/96288) (CQL). CQL expressions return a value of `true` or `false`. Only features which evaluate to `true` are returned. In `pg_featureserv` the filter expression is evaluated by the database, @@ -15,12 +15,12 @@ so it can take advantage of indexes to make filter evaluation very efficient. This section describes the CQL query language subset supported by `pg_featureserv`. -## Property and Literal Values +## Property and Scalar Literal Values The basic elements of filter expressions are values obtained from feature collection properties and literals. -Properties are referred to by name, and literals can be -numbers, boolean or text values. +Properties are referred to by name. +Scalar literals can be numbers, boolean or text values. #### Example ``` @@ -106,3 +106,69 @@ subexpressions in parentheses. ``` (continent = 'Europe' OR continent = 'Afica') AND pop_est < 1000000 ``` + +## Spatial filters + +CQL supports spatial filters by providing **geometry values** +and **spatial predicates**. + +### Geometry Literals + +Geometry literals use Well-Known Text (WKT) to describe +values for points, lines, polygons, and collections: + +``` +POINT (1 2) +LINESTRING(0 0, 1 1) +POLYGON((0 0, 0 9, 9 0, 0 0)) +POLYGON((0 0, 0 9, 9 0, 0 0),(1 1, 1 8, 8 1, 1 1)) +MULTIPOINT(0 0, 0 9) +MULTILINESTRING((0 0, 1 1),(1 1, 2 2)) +MULTIPOLYGON(((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))) +GEOMETRYCOLLECTION(POLYGON((1 4, 4 1, 1 1, 1 4)),LINESTRING (3 3, 5 5), POINT (1 5)) +``` + +CQL also provides a syntax for concisely defining a rectangular polygon: +``` +ENVELOPE(1, 2, 3, 4) +``` + +By default the coordinate system of geometry literal values is assumed to be geodetic (SRID = 4326). +The `filter-crs=SRID` query parameter can be used to specify that filter geometry literals are in a different coordinate system. + +### Spatial predicates + +Spatial predicates allow filtering features via spatial conditions +on the feature geometry. +Spatial predicates are defined in the form of spatial functions. +Predicates for spatial relationships include: + +* `INTERSECTS` - tests whether two geometries intersect +* `DISJOINT` - tests whether two geometries have no points in common +* `CONTAINS` - tests whether a geometry contains another +* `WITHIN` - tests whether a geometry is within another +* `EQUALS` - tests whether two geometries are topologically equal +* `CROSSES` - tests whether the geometries cross +* `OVERLAPS` - tests whether the geometries overlap +* `TOUCHES` - tests whether the geometries touch + +For precise definitions of the spatial predicates see the +[CQL standard](https://portal.ogc.org/files/96288#enhanced-spatial-operators) +and the [PostGIS function reference](https://postgis.net/docs/reference.html#Spatial_Relationships). + +Typically a spatial predicate will be applied to the spatial column of the collection +being queried, and a geometry literal value. +For example: +``` +filter=INTERSECTS(geom, ENVELOPE(-100 49, -90, 50) ) + +filter=CONTAINS(geom, POINT(-100 49) ) +``` + +The `DWITHIN` predicate allows testing whether a geometry lies within a given distance of another. The distance specified is in the units of the underlying dataset's coordinate system. For example: +``` +filter=DWITHIN(geom, POINT(-100 49), 0.1) +``` + +Note that if a spatial index is defined on the table being queried, +PostGIS will use it to evaluate spatial conditions very efficiently. diff --git a/hugo/content/usage/query_data.md b/hugo/content/usage/query_data.md index a68749b2..7f9dddfc 100644 --- a/hugo/content/usage/query_data.md +++ b/hugo/content/usage/query_data.md @@ -75,6 +75,16 @@ See the [CQL section](/query_data/cql/) for more details. http://localhost:9000/collections/ne.countries/items?filter=continent='Europe' AND pop_est<2000000 ``` +### Specify filter coordinate system + +The coordinate system used by geometry literals in the filter expression +can be specified by using the query parameter `filter-crs=SRID`. + +#### Example +``` +http://localhost:9000/collections/ebc.voting_area/items.json?filter=DWITHIN(geom,POINT(1209000+477000),1000)&filter-crs=3005 +``` + ### Specify response properties The query parameter `properties=PROP1,PROP2,PROP3...` diff --git a/hugo/content/usage/query_function.md b/hugo/content/usage/query_function.md index 6b3a1f72..3ca736bd 100644 --- a/hugo/content/usage/query_function.md +++ b/hugo/content/usage/query_function.md @@ -68,6 +68,16 @@ See the [CQL section](/query_data/cql/) for more details. http://localhost:9000/functions/countries_name/items?name_prefix=C&filter=continent='Europe' AND pop_est<2000000 ``` +### Specify filter coordinate system + +The coordinate system used by geometry literals in the filter expression +can be specified by using the query parameter `filter-crs=SRID`. + +#### Example +``` +http://localhost:9000/functions/countries_name/items.json?filter=DWITHIN(geom,POINT(1209000+477000),1000)&filter-crs=3005 +``` + ### Specify response properties The query parameter `properties=PROP1,PROP2,PROP3...` diff --git a/internal/api/api.go b/internal/api/api.go index caa3e9ee..d03ad5da 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -38,6 +38,7 @@ const ( ParamBbox = "bbox" ParamBboxCrs = "bbox-crs" ParamFilter = "filter" + ParamFilterCrs = "filter-crs" ParamGroupBy = "groupby" ParamOrderBy = "orderby" ParamPrecision = "precision" @@ -241,6 +242,7 @@ type RequestParam struct { BboxCrs int Properties []string Filter string + FilterCrs int GroupBy []string SortBy []data.Sorting Precision int diff --git a/internal/api/openapi.go b/internal/api/openapi.go index cf8cf321..e0b013f6 100644 --- a/internal/api/openapi.go +++ b/internal/api/openapi.go @@ -98,6 +98,22 @@ func GetOpenAPIContent(urlBase string) *openapi3.Swagger { AllowEmptyValue: false, }, } + paramFilterCrs := openapi3.ParameterRef{ + Value: &openapi3.Parameter{ + Name: "filter-crs", + Description: "SRID for filter geometry literals.", + In: "query", + Required: false, + Schema: &openapi3.SchemaRef{ + Value: &openapi3.Schema{ + Type: "integer", + Min: openapi3.Float64Ptr(1), + Default: 4326, + }, + }, + AllowEmptyValue: false, + }, + } paramProperties := openapi3.ParameterRef{ Value: &openapi3.Parameter{ Name: "properties", @@ -303,6 +319,7 @@ func GetOpenAPIContent(urlBase string) *openapi3.Swagger { ¶mBbox, ¶mBboxCrs, ¶mFilter, + ¶mFilterCrs, ¶mTransform, ¶mProperties, ¶mSortBy, @@ -424,6 +441,7 @@ func GetOpenAPIContent(urlBase string) *openapi3.Swagger { ¶mBbox, ¶mBboxCrs, ¶mFilter, + ¶mFilterCrs, ¶mTransform, ¶mProperties, ¶mSortBy, diff --git a/internal/cql/CQL.g4 b/internal/cql/CQL.g4 index 712af9d8..ee05e3b6 100644 --- a/internal/cql/CQL.g4 +++ b/internal/cql/CQL.g4 @@ -34,7 +34,8 @@ predicate : binaryComparisonPredicate | betweenPredicate | isNullPredicate | inPredicate -// | spatialPredicate + | spatialPredicate + | distancePredicate // | temporalPredicate // | arrayPredicate // | existencePredicate @@ -86,6 +87,8 @@ booleanLiteral: BooleanLiteral; spatialPredicate : SpatialOperator LEFTPAREN geomExpression COMMA geomExpression RIGHTPAREN; +distancePredicate : DistanceOperator LEFTPAREN geomExpression COMMA geomExpression COMMA NumericLiteral RIGHTPAREN; + /* # A geometric expression is a property name of a geometry-valued property, # a geometric literal (expressed as WKT) or a function that returns a @@ -98,9 +101,6 @@ geomExpression : propertyName /* #=============================================================================# # Definition of GEOMETRIC literals -# -# NOTE: This is basically BNF that define WKT encoding; it would be nice -# to instead reference some normative BNF for WKT. #=============================================================================# */ @@ -115,44 +115,25 @@ geomLiteral: point point : POINT LEFTPAREN coordinate RIGHTPAREN; -linestring : LINESTRING linestringDef; +linestring : LINESTRING coordList; -linestringDef: LEFTPAREN coordinate (COMMA coordinate)* RIGHTPAREN; +coordList: LEFTPAREN coordinate (COMMA coordinate)* RIGHTPAREN; polygon : POLYGON polygonDef; -polygonDef : LEFTPAREN linestringDef (COMMA linestringDef)* RIGHTPAREN; +polygonDef : LEFTPAREN coordList (COMMA coordList)* RIGHTPAREN; multiPoint : MULTIPOINT LEFTPAREN coordinate (COMMA coordinate)* RIGHTPAREN; -multiLinestring : MULTILINESTRING LEFTPAREN linestringDef (COMMA linestringDef)* RIGHTPAREN; +multiLinestring : MULTILINESTRING LEFTPAREN coordList (COMMA coordList)* RIGHTPAREN; multiPolygon : MULTIPOLYGON LEFTPAREN polygonDef (COMMA polygonDef)* RIGHTPAREN; geometryCollection : GEOMETRYCOLLECTION LEFTPAREN geomLiteral (COMMA geomLiteral)* RIGHTPAREN; -envelope: ENVELOPE LEFTPAREN westBoundLon COMMA southBoundLat COMMA (minElev COMMA)? eastBoundLon COMMA northBoundLat (COMMA maxElev)? RIGHTPAREN; - -coordinate : xCoord yCoord (zCoord)?; - -xCoord : NumericLiteral; - -yCoord : NumericLiteral; - -zCoord : NumericLiteral; - -westBoundLon : NumericLiteral; - -eastBoundLon : NumericLiteral; - -northBoundLat : NumericLiteral; - -southBoundLat : NumericLiteral; - -minElev : NumericLiteral; - -maxElev : NumericLiteral; +envelope: ENVELOPE LEFTPAREN NumericLiteral COMMA NumericLiteral COMMA NumericLiteral COMMA NumericLiteral RIGHTPAREN; +coordinate : NumericLiteral NumericLiteral; /* #=============================================================================# @@ -160,7 +141,6 @@ maxElev : NumericLiteral; # specified temporal operator. #=============================================================================# */ -//CHANGE: allow intervals with / temporalPredicate : temporalExpression (TemporalOperator | ComparisonOperator) temporalExpression; temporalExpression : propertyName @@ -174,8 +154,6 @@ temporalLiteral: TemporalLiteral; # The IN predicate #=============================================================================# */ -//CHANGE: optional PropertyName for id filters -//CHANGE: added missing comma /* inPredicate : (propertyName | function)? (NOT)? IN LEFTPAREN ( characterLiteral | numericLiteral | diff --git a/internal/cql/CQL.tokens b/internal/cql/CQL.tokens index 840b5f11..96a677f2 100644 --- a/internal/cql/CQL.tokens +++ b/internal/cql/CQL.tokens @@ -19,96 +19,97 @@ SINGLECHAR=18 ESCAPECHAR=19 NOCASE=20 SpatialOperator=21 -TemporalOperator=22 -ArrayOperator=23 -EXISTS=24 -EXIST=25 -DOES=26 -IN=27 -POINT=28 -LINESTRING=29 -POLYGON=30 -MULTIPOINT=31 -MULTILINESTRING=32 -MULTIPOLYGON=33 -GEOMETRYCOLLECTION=34 -ENVELOPE=35 -NumericLiteral=36 -Identifier=37 -IdentifierStart=38 -IdentifierPart=39 -ALPHA=40 -DIGIT=41 -OCTOTHORP=42 -DOLLAR=43 -UNDERSCORE=44 -DOUBLEQUOTE=45 -PERCENT=46 -AMPERSAND=47 -QUOTE=48 -LEFTPAREN=49 -RIGHTPAREN=50 -LEFTSQUAREBRACKET=51 -RIGHTSQUAREBRACKET=52 -ASTERISK=53 -PLUS=54 -COMMA=55 -MINUS=56 -PERIOD=57 -SOLIDUS=58 -COLON=59 -SEMICOLON=60 -QUESTIONMARK=61 -VERTICALBAR=62 -BIT=63 -HEXIT=64 -UnsignedNumericLiteral=65 -SignedNumericLiteral=66 -ExactNumericLiteral=67 -ApproximateNumericLiteral=68 -Mantissa=69 -Exponent=70 -SignedInteger=71 -UnsignedInteger=72 -Sign=73 -TemporalLiteral=74 -Instant=75 -Interval=76 -InstantInInterval=77 -FullDate=78 -DateYear=79 -DateMonth=80 -DateDay=81 -UtcTime=82 -TimeZoneOffset=83 -TimeHour=84 -TimeMinute=85 -TimeSecond=86 -NOW=87 -WS=88 -CharacterStringLiteral=89 -QuotedQuote=90 +DistanceOperator=22 +TemporalOperator=23 +ArrayOperator=24 +EXISTS=25 +EXIST=26 +DOES=27 +IN=28 +POINT=29 +LINESTRING=30 +POLYGON=31 +MULTIPOINT=32 +MULTILINESTRING=33 +MULTIPOLYGON=34 +GEOMETRYCOLLECTION=35 +ENVELOPE=36 +NumericLiteral=37 +Identifier=38 +IdentifierStart=39 +IdentifierPart=40 +ALPHA=41 +DIGIT=42 +OCTOTHORP=43 +DOLLAR=44 +UNDERSCORE=45 +DOUBLEQUOTE=46 +PERCENT=47 +AMPERSAND=48 +QUOTE=49 +LEFTPAREN=50 +RIGHTPAREN=51 +LEFTSQUAREBRACKET=52 +RIGHTSQUAREBRACKET=53 +ASTERISK=54 +PLUS=55 +COMMA=56 +MINUS=57 +PERIOD=58 +SOLIDUS=59 +COLON=60 +SEMICOLON=61 +QUESTIONMARK=62 +VERTICALBAR=63 +BIT=64 +HEXIT=65 +UnsignedNumericLiteral=66 +SignedNumericLiteral=67 +ExactNumericLiteral=68 +ApproximateNumericLiteral=69 +Mantissa=70 +Exponent=71 +SignedInteger=72 +UnsignedInteger=73 +Sign=74 +TemporalLiteral=75 +Instant=76 +Interval=77 +InstantInInterval=78 +FullDate=79 +DateYear=80 +DateMonth=81 +DateDay=82 +UtcTime=83 +TimeZoneOffset=84 +TimeHour=85 +TimeMinute=86 +TimeSecond=87 +NOW=88 +WS=89 +CharacterStringLiteral=90 +QuotedQuote=91 '<'=2 '='=3 '>'=4 -'#'=42 -'$'=43 -'_'=44 -'"'=45 -'%'=46 -'&'=47 -'('=49 -')'=50 -'['=51 -']'=52 -'*'=53 -'+'=54 -','=55 -'-'=56 -'.'=57 -'/'=58 -':'=59 -';'=60 -'?'=61 -'|'=62 -'\'\''=90 +'#'=43 +'$'=44 +'_'=45 +'"'=46 +'%'=47 +'&'=48 +'('=50 +')'=51 +'['=52 +']'=53 +'*'=54 +'+'=55 +','=56 +'-'=57 +'.'=58 +'/'=59 +':'=60 +';'=61 +'?'=62 +'|'=63 +'\'\''=91 diff --git a/internal/cql/CqlLexer.g4 b/internal/cql/CqlLexer.g4 index a83b8588..c0ec8017 100644 --- a/internal/cql/CqlLexer.g4 +++ b/internal/cql/CqlLexer.g4 @@ -112,15 +112,15 @@ NOCASE : N O C A S E; #=============================================================================# */ -/* -# NOTE: The buffer operators (DWITHIN and BEYOND) are not included because -# these are outside the scope of a "simple" core for CQL. These -# can be added as extensions. -# -*/ SpatialOperator : E Q U A L S | D I S J O I N T | T O U C H E S | W I T H I N | O V E R L A P S | C R O S S E S | I N T E R S E C T S | C O N T A I N S; +/* +# NOTE: The distance operator BEYOND is not currently included. +# It is equivalent to NOT DWITHIN. +# +*/ +DistanceOperator : D W I T H I N; /* #=============================================================================# # Definition of TEMPORAL operators @@ -134,13 +134,6 @@ TemporalOperator : A F T E R | B E F O R E | B E G I N S | B E G U N B Y | T C O | E N D E D B Y | E N D S | T E Q U A L S | M E E T S | M E T B Y | T O V E R L A P S | O V E R L A P P E D B Y | A N Y I N T E R A C T S; -/* -TemporalOperator : 'AFTER' | 'BEFORE' | 'BEGINS' | 'BEGUNBY' | 'TCONTAINS' - | 'DURING' | 'ENDEDBY' | 'ENDS' | 'TEQUALS' | 'MEETS' - | 'METBY' | 'TOVERLAPS' | 'OVERLAPPEDBY' | 'ANYINTERACTS' - | 'TINTERSECTS'; -*/ - /* #=============================================================================# # Definition of ARRAY operators @@ -208,25 +201,10 @@ IdentifierPart : ALPHA | DIGIT | UNDERSCORE | DOLLAR; //QuoteQuote : QUOTE QUOTE; -/* -# NOTE: This production is supposed to be any alphabetic character from -# the character set. -# -# I use the A-Z, a-z range here as placeholders because: -# (a) I have no idea how to indicate that alpha can be -# any alphabetic UTF-8 character -# (b) the validators I am using can only handle ASCII chars -# -*/ ALPHA : [A-Za-z]; DIGIT : [0-9]; -/*SpecialCharacter : PERCENT | AMPERSAND | LEFTPAREN | RIGHTPAREN | ASTERISK - | PLUS | COMMA | MINUS | PERIOD | SOLIDUS | COLON - | SEMICOLON | LT | GT | EQ | QUESTIONMARK | UNDERSCORE - | VERTICALBAR | DOUBLEQUOTE ;*/ - OCTOTHORP : '#'; DOLLAR : '$'; UNDERSCORE : '_'; @@ -257,8 +235,6 @@ HEXIT : DIGIT | A | B | C | D | E | F; #=============================================================================# */ - - UnsignedNumericLiteral : ExactNumericLiteral | ApproximateNumericLiteral; SignedNumericLiteral : (Sign)? ExactNumericLiteral | ApproximateNumericLiteral; @@ -281,9 +257,6 @@ Sign : PLUS | MINUS; /* #=============================================================================# # Definition of TEMPORAL literals -# -# NOTE: Is the fact the time zones are supported too complicated for a -# simple CQL? Perhaps the "core" of CQL should just support UTC. #=============================================================================# */ diff --git a/internal/cql/CqlLexer.tokens b/internal/cql/CqlLexer.tokens index 840b5f11..96a677f2 100644 --- a/internal/cql/CqlLexer.tokens +++ b/internal/cql/CqlLexer.tokens @@ -19,96 +19,97 @@ SINGLECHAR=18 ESCAPECHAR=19 NOCASE=20 SpatialOperator=21 -TemporalOperator=22 -ArrayOperator=23 -EXISTS=24 -EXIST=25 -DOES=26 -IN=27 -POINT=28 -LINESTRING=29 -POLYGON=30 -MULTIPOINT=31 -MULTILINESTRING=32 -MULTIPOLYGON=33 -GEOMETRYCOLLECTION=34 -ENVELOPE=35 -NumericLiteral=36 -Identifier=37 -IdentifierStart=38 -IdentifierPart=39 -ALPHA=40 -DIGIT=41 -OCTOTHORP=42 -DOLLAR=43 -UNDERSCORE=44 -DOUBLEQUOTE=45 -PERCENT=46 -AMPERSAND=47 -QUOTE=48 -LEFTPAREN=49 -RIGHTPAREN=50 -LEFTSQUAREBRACKET=51 -RIGHTSQUAREBRACKET=52 -ASTERISK=53 -PLUS=54 -COMMA=55 -MINUS=56 -PERIOD=57 -SOLIDUS=58 -COLON=59 -SEMICOLON=60 -QUESTIONMARK=61 -VERTICALBAR=62 -BIT=63 -HEXIT=64 -UnsignedNumericLiteral=65 -SignedNumericLiteral=66 -ExactNumericLiteral=67 -ApproximateNumericLiteral=68 -Mantissa=69 -Exponent=70 -SignedInteger=71 -UnsignedInteger=72 -Sign=73 -TemporalLiteral=74 -Instant=75 -Interval=76 -InstantInInterval=77 -FullDate=78 -DateYear=79 -DateMonth=80 -DateDay=81 -UtcTime=82 -TimeZoneOffset=83 -TimeHour=84 -TimeMinute=85 -TimeSecond=86 -NOW=87 -WS=88 -CharacterStringLiteral=89 -QuotedQuote=90 +DistanceOperator=22 +TemporalOperator=23 +ArrayOperator=24 +EXISTS=25 +EXIST=26 +DOES=27 +IN=28 +POINT=29 +LINESTRING=30 +POLYGON=31 +MULTIPOINT=32 +MULTILINESTRING=33 +MULTIPOLYGON=34 +GEOMETRYCOLLECTION=35 +ENVELOPE=36 +NumericLiteral=37 +Identifier=38 +IdentifierStart=39 +IdentifierPart=40 +ALPHA=41 +DIGIT=42 +OCTOTHORP=43 +DOLLAR=44 +UNDERSCORE=45 +DOUBLEQUOTE=46 +PERCENT=47 +AMPERSAND=48 +QUOTE=49 +LEFTPAREN=50 +RIGHTPAREN=51 +LEFTSQUAREBRACKET=52 +RIGHTSQUAREBRACKET=53 +ASTERISK=54 +PLUS=55 +COMMA=56 +MINUS=57 +PERIOD=58 +SOLIDUS=59 +COLON=60 +SEMICOLON=61 +QUESTIONMARK=62 +VERTICALBAR=63 +BIT=64 +HEXIT=65 +UnsignedNumericLiteral=66 +SignedNumericLiteral=67 +ExactNumericLiteral=68 +ApproximateNumericLiteral=69 +Mantissa=70 +Exponent=71 +SignedInteger=72 +UnsignedInteger=73 +Sign=74 +TemporalLiteral=75 +Instant=76 +Interval=77 +InstantInInterval=78 +FullDate=79 +DateYear=80 +DateMonth=81 +DateDay=82 +UtcTime=83 +TimeZoneOffset=84 +TimeHour=85 +TimeMinute=86 +TimeSecond=87 +NOW=88 +WS=89 +CharacterStringLiteral=90 +QuotedQuote=91 '<'=2 '='=3 '>'=4 -'#'=42 -'$'=43 -'_'=44 -'"'=45 -'%'=46 -'&'=47 -'('=49 -')'=50 -'['=51 -']'=52 -'*'=53 -'+'=54 -','=55 -'-'=56 -'.'=57 -'/'=58 -':'=59 -';'=60 -'?'=61 -'|'=62 -'\'\''=90 +'#'=43 +'$'=44 +'_'=45 +'"'=46 +'%'=47 +'&'=48 +'('=50 +')'=51 +'['=52 +']'=53 +'*'=54 +'+'=55 +','=56 +'-'=57 +'.'=58 +'/'=59 +':'=60 +';'=61 +'?'=62 +'|'=63 +'\'\''=91 diff --git a/internal/cql/cql.go b/internal/cql/cql.go index 0d2bf914..c3549ac3 100644 --- a/internal/cql/cql.go +++ b/internal/cql/cql.go @@ -8,7 +8,7 @@ import ( log "github.com/sirupsen/logrus" ) -func TranspileToSQL(cqlStr string) (string, error) { +func TranspileToSQL(cqlStr string, filterSRID int, sourceSRID int) (string, error) { if len(cqlStr) < 1 { return "", nil } @@ -29,8 +29,8 @@ func TranspileToSQL(cqlStr string) (string, error) { parser.AddErrorListener(parseErrors) tree := parser.CqlFilter() - // Finally parse the expression - listener := NewCqlListener() + //-- parse the CQL expression + listener := NewCqlListener(filterSRID, sourceSRID) antlr.ParseTreeWalkerDefault.Walk(listener, tree) if parseErrors.errorCount > 0 { @@ -97,15 +97,20 @@ func (l *CqlErrorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa type cqlListener struct { *BaseCQLListener - + // SRID for filter CRS + filterSRID int + // SRID for source CRS + sourceSRID int // SQL strings for nodes result map[*antlr.BaseRuleContext]string // result SQL sql string } -func NewCqlListener() *cqlListener { +func NewCqlListener(filterSRID int, sourceSRID int) *cqlListener { this := new(cqlListener) + this.filterSRID = filterSRID + this.sourceSRID = sourceSRID this.result = make(map[*antlr.BaseRuleContext]string) return this } @@ -127,6 +132,22 @@ func (l *cqlListener) saveFrag(ctx antlr.ParserRuleContext, sql string) { l.result[ctx.GetBaseRuleContext()] = sql } +func (l *cqlListener) sqlGeometryLiteral(wkt string) string { + sql := fmt.Sprintf("'SRID=%d;%s'::geometry", l.filterSRID, wkt) + return sql +} + +func (l *cqlListener) sqlEnvelopeLiteral(b1 string, b2 string, b3 string, b4 string) string { + return fmt.Sprintf("ST_MakeEnvelope(%s,%s,%s,%s,%d)", b1, b2, b3, b4, l.filterSRID) +} + +func (l *cqlListener) sqlTransform(sql string) string { + if l.sourceSRID == l.filterSRID { + return sql + } + return fmt.Sprintf("ST_Transform(%s,%d)", sql, l.sourceSRID) +} + // helper function to avoid nil pointer problems func getText(ctx antlr.ParserRuleContext) string { if ctx == nil { @@ -201,6 +222,10 @@ func (l *cqlListener) ExitPredicate(ctx *PredicateContext) { sql = l.sqlFrag(ctx.IsNullPredicate()) } else if ctx.InPredicate() != nil { sql = l.sqlFrag(ctx.InPredicate()) + } else if ctx.SpatialPredicate() != nil { + sql = l.sqlFrag(ctx.SpatialPredicate()) + } else if ctx.DistancePredicate() != nil { + sql = l.sqlFrag(ctx.DistancePredicate()) } l.saveFrag(ctx, sql) } @@ -301,8 +326,107 @@ func inPredValueList(ctx *InPredicateContext, sb *strings.Builder) { } } -func toBool(boolText string) bool { - return strings.ToLower(boolText) == "true" +func (l *cqlListener) ExitSpatialPredicate(ctx *SpatialPredicateContext) { + var sb strings.Builder + sb.WriteString(toPostGISFunction(ctx.SpatialOperator().GetText())) + sb.WriteString("(") + sb.WriteString(l.sqlFrag(ctx.GeomExpression(0))) + sb.WriteString(",") + sb.WriteString(l.sqlFrag(ctx.GeomExpression(1))) + sb.WriteString(")") + l.saveFrag(ctx, sb.String()) +} + +func (l *cqlListener) ExitDistancePredicate(ctx *DistancePredicateContext) { + var sb strings.Builder + sb.WriteString(toPostGISFunction(ctx.DistanceOperator().GetText())) + sb.WriteString("(") + sb.WriteString(l.sqlFrag(ctx.GeomExpression(0))) + sb.WriteString(",") + sb.WriteString(l.sqlFrag(ctx.GeomExpression(1))) + sb.WriteString(",") + sb.WriteString(ctx.NumericLiteral().GetText()) + sb.WriteString(")") + l.saveFrag(ctx, sb.String()) +} + +func (l *cqlListener) ExitGeomExpression(ctx *GeomExpressionContext) { + var sb strings.Builder + if ctx.PropertyName() != nil { + sb.WriteString(quotedName(getText(ctx.PropertyName()))) + } else { + sb.WriteString(l.sqlFrag(ctx.GeomLiteral())) + } + l.saveFrag(ctx, sb.String()) +} + +func (l *cqlListener) ExitGeomLiteral(ctx *GeomLiteralContext) { + envCtx, ok := ctx.GetChild(0).(*EnvelopeContext) + var sql string + if ok { + nums := envCtx.AllNumericLiteral() + b1 := nums[0].GetText() + b2 := nums[1].GetText() + b3 := nums[2].GetText() + b4 := nums[3].GetText() + sql = l.sqlEnvelopeLiteral(b1, b2, b3, b4) + } else { + wkt := getGeomText(ctx) + sql = l.sqlGeometryLiteral(wkt) + } + sql = l.sqlTransform(sql) + l.saveFrag(ctx, sql) +} + +func getGeomText(ctx *GeomLiteralContext) string { + trees := ctx.GetChildren() + var sb strings.Builder + extractGeomText(trees, &sb) + return sb.String() +} + +func extractGeomText(trees []antlr.Tree, sb *strings.Builder) { + isPrevNumeric := false + for _, t := range trees { + tn, ok := t.(antlr.TerminalNode) + if ok { + //-- add a blank between consecutive numbers to separate them + if tn.GetSymbol().GetTokenType() == CQLNumericLiteral { + if isPrevNumeric { + sb.WriteString(" ") + } + isPrevNumeric = true + } else { + isPrevNumeric = false + } + sb.WriteString(strings.ToUpper(tn.GetText())) + } else { + ch := t.GetChildren() + extractGeomText(ch, sb) + } + } +} + +var pgFunctionForCql = map[string]string{ + "crosses": "ST_Crosses", + "contains": "ST_Contains", + "disjoint": "ST_Disjoint", + "equals": "ST_Equals", + "intersects": "ST_Intersects", + "overlaps": "ST_Overlaps", + "touches": "ST_Touches", + "within": "ST_Within", + + "dwithin": "ST_DWithin", +} + +func toPostGISFunction(cqlFunName string) string { + cqlNameLow := strings.ToLower(cqlFunName) + if fun, ok := pgFunctionForCql[cqlNameLow]; ok { + return fun + } + //-- this will trigger a SQL error + return "UNKNOWN_" + cqlFunName } func quotedName(name string) string { @@ -315,5 +439,6 @@ func quotedName(name string) string { func quotedText(s string) string { //TODO: make this better (escape quotes, etc) + //TODO: is SQL injection a risk here? return s } diff --git a/internal/cql/cql_base_listener.go b/internal/cql/cql_base_listener.go index 450b05bb..aef0ac67 100644 --- a/internal/cql/cql_base_listener.go +++ b/internal/cql/cql_base_listener.go @@ -116,6 +116,12 @@ func (s *BaseCQLListener) EnterSpatialPredicate(ctx *SpatialPredicateContext) {} // ExitSpatialPredicate is called when production spatialPredicate is exited. func (s *BaseCQLListener) ExitSpatialPredicate(ctx *SpatialPredicateContext) {} +// EnterDistancePredicate is called when production distancePredicate is entered. +func (s *BaseCQLListener) EnterDistancePredicate(ctx *DistancePredicateContext) {} + +// ExitDistancePredicate is called when production distancePredicate is exited. +func (s *BaseCQLListener) ExitDistancePredicate(ctx *DistancePredicateContext) {} + // EnterGeomExpression is called when production geomExpression is entered. func (s *BaseCQLListener) EnterGeomExpression(ctx *GeomExpressionContext) {} @@ -140,11 +146,11 @@ func (s *BaseCQLListener) EnterLinestring(ctx *LinestringContext) {} // ExitLinestring is called when production linestring is exited. func (s *BaseCQLListener) ExitLinestring(ctx *LinestringContext) {} -// EnterLinestringDef is called when production linestringDef is entered. -func (s *BaseCQLListener) EnterLinestringDef(ctx *LinestringDefContext) {} +// EnterCoordList is called when production coordList is entered. +func (s *BaseCQLListener) EnterCoordList(ctx *CoordListContext) {} -// ExitLinestringDef is called when production linestringDef is exited. -func (s *BaseCQLListener) ExitLinestringDef(ctx *LinestringDefContext) {} +// ExitCoordList is called when production coordList is exited. +func (s *BaseCQLListener) ExitCoordList(ctx *CoordListContext) {} // EnterPolygon is called when production polygon is entered. func (s *BaseCQLListener) EnterPolygon(ctx *PolygonContext) {} @@ -194,60 +200,6 @@ func (s *BaseCQLListener) EnterCoordinate(ctx *CoordinateContext) {} // ExitCoordinate is called when production coordinate is exited. func (s *BaseCQLListener) ExitCoordinate(ctx *CoordinateContext) {} -// EnterXCoord is called when production xCoord is entered. -func (s *BaseCQLListener) EnterXCoord(ctx *XCoordContext) {} - -// ExitXCoord is called when production xCoord is exited. -func (s *BaseCQLListener) ExitXCoord(ctx *XCoordContext) {} - -// EnterYCoord is called when production yCoord is entered. -func (s *BaseCQLListener) EnterYCoord(ctx *YCoordContext) {} - -// ExitYCoord is called when production yCoord is exited. -func (s *BaseCQLListener) ExitYCoord(ctx *YCoordContext) {} - -// EnterZCoord is called when production zCoord is entered. -func (s *BaseCQLListener) EnterZCoord(ctx *ZCoordContext) {} - -// ExitZCoord is called when production zCoord is exited. -func (s *BaseCQLListener) ExitZCoord(ctx *ZCoordContext) {} - -// EnterWestBoundLon is called when production westBoundLon is entered. -func (s *BaseCQLListener) EnterWestBoundLon(ctx *WestBoundLonContext) {} - -// ExitWestBoundLon is called when production westBoundLon is exited. -func (s *BaseCQLListener) ExitWestBoundLon(ctx *WestBoundLonContext) {} - -// EnterEastBoundLon is called when production eastBoundLon is entered. -func (s *BaseCQLListener) EnterEastBoundLon(ctx *EastBoundLonContext) {} - -// ExitEastBoundLon is called when production eastBoundLon is exited. -func (s *BaseCQLListener) ExitEastBoundLon(ctx *EastBoundLonContext) {} - -// EnterNorthBoundLat is called when production northBoundLat is entered. -func (s *BaseCQLListener) EnterNorthBoundLat(ctx *NorthBoundLatContext) {} - -// ExitNorthBoundLat is called when production northBoundLat is exited. -func (s *BaseCQLListener) ExitNorthBoundLat(ctx *NorthBoundLatContext) {} - -// EnterSouthBoundLat is called when production southBoundLat is entered. -func (s *BaseCQLListener) EnterSouthBoundLat(ctx *SouthBoundLatContext) {} - -// ExitSouthBoundLat is called when production southBoundLat is exited. -func (s *BaseCQLListener) ExitSouthBoundLat(ctx *SouthBoundLatContext) {} - -// EnterMinElev is called when production minElev is entered. -func (s *BaseCQLListener) EnterMinElev(ctx *MinElevContext) {} - -// ExitMinElev is called when production minElev is exited. -func (s *BaseCQLListener) ExitMinElev(ctx *MinElevContext) {} - -// EnterMaxElev is called when production maxElev is entered. -func (s *BaseCQLListener) EnterMaxElev(ctx *MaxElevContext) {} - -// ExitMaxElev is called when production maxElev is exited. -func (s *BaseCQLListener) ExitMaxElev(ctx *MaxElevContext) {} - // EnterTemporalPredicate is called when production temporalPredicate is entered. func (s *BaseCQLListener) EnterTemporalPredicate(ctx *TemporalPredicateContext) {} diff --git a/internal/cql/cql_lexer.go b/internal/cql/cql_lexer.go index 054e8f57..e0fdf680 100644 --- a/internal/cql/cql_lexer.go +++ b/internal/cql/cql_lexer.go @@ -14,7 +14,7 @@ var _ = fmt.Printf var _ = unicode.IsLetter var serializedLexerAtn = []uint16{ - 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 92, 978, + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 93, 988, 8, 1, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, @@ -38,422 +38,427 @@ var serializedLexerAtn = []uint16{ 4, 106, 9, 106, 4, 107, 9, 107, 4, 108, 9, 108, 4, 109, 9, 109, 4, 110, 9, 110, 4, 111, 9, 111, 4, 112, 9, 112, 4, 113, 9, 113, 4, 114, 9, 114, 4, 115, 9, 115, 4, 116, 9, 116, 4, 117, 9, 117, 4, 118, 9, 118, 4, 119, - 9, 119, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, - 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 12, 3, - 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, - 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 22, 3, 22, 3, - 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, 3, 27, 3, 28, - 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 299, 10, 28, 3, 29, 3, 29, 3, - 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 34, - 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, - 35, 3, 35, 3, 35, 5, 35, 327, 10, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 37, - 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, 39, 3, 39, 3, - 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, 3, 41, 3, 41, - 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, 43, 3, 43, 3, - 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, - 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, - 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, - 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, + 9, 119, 4, 120, 9, 120, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, + 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, + 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, + 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, + 22, 3, 22, 3, 23, 3, 23, 3, 24, 3, 24, 3, 25, 3, 25, 3, 26, 3, 26, 3, 27, + 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 301, 10, 28, 3, + 29, 3, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, + 3, 33, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, 35, 3, + 35, 3, 35, 3, 35, 3, 35, 3, 35, 5, 35, 329, 10, 35, 3, 36, 3, 36, 3, 36, + 3, 36, 3, 37, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 3, 38, 3, 39, 3, 39, 3, + 39, 3, 39, 3, 39, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 40, 3, 41, 3, 41, + 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 41, 3, 42, 3, 42, 3, 42, 3, 43, 3, + 43, 3, 43, 3, 43, 3, 43, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, 3, 44, + 3, 44, 3, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, 45, 3, + 45, 3, 45, 3, 45, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, 3, 46, + 3, 46, 3, 46, 3, 46, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 47, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, 48, 3, - 48, 3, 48, 3, 48, 5, 48, 473, 10, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, - 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, - 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, - 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, - 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, - 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, - 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, - 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, - 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, - 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, - 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, - 3, 49, 3, 49, 3, 49, 3, 49, 5, 49, 589, 10, 49, 3, 50, 3, 50, 3, 50, 3, + 48, 3, 48, 3, 48, 3, 48, 3, 48, 5, 48, 475, 10, 48, 3, 49, 3, 49, 3, 49, + 3, 49, 3, 49, 3, 49, 3, 49, 3, 49, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, - 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 5, 50, 631, 10, 50, 3, 51, 3, 51, 3, - 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, 3, 52, - 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, - 55, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 3, 56, - 3, 56, 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, - 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, - 3, 58, 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, - 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 60, 3, 60, 3, 60, - 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, - 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, - 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, 3, 62, 3, - 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, 3, 63, - 3, 63, 3, 64, 3, 64, 5, 64, 754, 10, 64, 3, 65, 3, 65, 7, 65, 758, 10, - 65, 12, 65, 14, 65, 761, 11, 65, 3, 65, 3, 65, 3, 65, 3, 65, 5, 65, 767, - 10, 65, 3, 66, 3, 66, 3, 67, 3, 67, 3, 67, 3, 67, 5, 67, 775, 10, 67, 3, - 68, 3, 68, 3, 69, 3, 69, 3, 70, 3, 70, 3, 71, 3, 71, 3, 72, 3, 72, 3, 73, - 3, 73, 3, 74, 3, 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 77, 3, 77, 3, 78, 3, - 78, 3, 79, 3, 79, 3, 80, 3, 80, 3, 81, 3, 81, 3, 82, 3, 82, 3, 83, 3, 83, - 3, 84, 3, 84, 3, 85, 3, 85, 3, 86, 3, 86, 3, 87, 3, 87, 3, 88, 3, 88, 3, - 89, 3, 89, 3, 90, 3, 90, 3, 91, 3, 91, 3, 92, 3, 92, 3, 92, 3, 92, 3, 92, - 3, 92, 3, 92, 5, 92, 832, 10, 92, 3, 93, 3, 93, 5, 93, 836, 10, 93, 3, - 94, 5, 94, 839, 10, 94, 3, 94, 3, 94, 5, 94, 843, 10, 94, 3, 95, 3, 95, - 3, 95, 5, 95, 848, 10, 95, 5, 95, 850, 10, 95, 3, 95, 3, 95, 3, 95, 5, - 95, 855, 10, 95, 3, 96, 3, 96, 3, 96, 3, 96, 3, 97, 3, 97, 3, 98, 3, 98, - 3, 99, 5, 99, 866, 10, 99, 3, 99, 3, 99, 3, 100, 6, 100, 871, 10, 100, - 13, 100, 14, 100, 872, 3, 101, 3, 101, 5, 101, 877, 10, 101, 3, 102, 3, - 102, 5, 102, 881, 10, 102, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, 3, 103, - 3, 103, 3, 103, 3, 103, 5, 103, 892, 10, 103, 3, 104, 5, 104, 895, 10, - 104, 3, 104, 3, 104, 5, 104, 899, 10, 104, 3, 105, 3, 105, 3, 105, 5, 105, - 904, 10, 105, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 106, 3, 107, 3, - 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, - 109, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 3, 110, 5, 110, 929, 10, 110, - 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 5, 111, 937, 10, 111, 3, - 112, 3, 112, 3, 112, 3, 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, - 114, 6, 114, 949, 10, 114, 13, 114, 14, 114, 950, 5, 114, 953, 10, 114, - 3, 115, 3, 115, 3, 115, 3, 115, 3, 116, 6, 116, 960, 10, 116, 13, 116, - 14, 116, 961, 3, 116, 3, 116, 3, 117, 3, 117, 3, 117, 3, 117, 3, 118, 3, - 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, 119, 3, 119, 3, 119, 2, 2, 120, + 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, + 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, + 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, + 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, + 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, + 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, + 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, + 50, 3, 50, 3, 50, 3, 50, 5, 50, 599, 10, 50, 3, 51, 3, 51, 3, 51, 3, 51, + 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, + 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, + 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, 51, 3, + 51, 3, 51, 3, 51, 3, 51, 3, 51, 5, 51, 641, 10, 51, 3, 52, 3, 52, 3, 52, + 3, 52, 3, 52, 3, 52, 3, 52, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, + 54, 3, 54, 3, 54, 3, 54, 3, 54, 3, 55, 3, 55, 3, 55, 3, 56, 3, 56, 3, 56, + 3, 56, 3, 56, 3, 56, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, 57, 3, + 57, 3, 57, 3, 57, 3, 57, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, 3, 58, + 3, 58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, + 59, 3, 59, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, + 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 60, 3, 61, 3, 61, 3, 61, 3, + 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 61, 3, 62, + 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, + 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 62, 3, 63, 3, 63, 3, 63, + 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 63, 3, 64, 3, 64, 3, 64, 3, 64, 3, + 64, 3, 65, 3, 65, 5, 65, 764, 10, 65, 3, 66, 3, 66, 7, 66, 768, 10, 66, + 12, 66, 14, 66, 771, 11, 66, 3, 66, 3, 66, 3, 66, 3, 66, 5, 66, 777, 10, + 66, 3, 67, 3, 67, 3, 68, 3, 68, 3, 68, 3, 68, 5, 68, 785, 10, 68, 3, 69, + 3, 69, 3, 70, 3, 70, 3, 71, 3, 71, 3, 72, 3, 72, 3, 73, 3, 73, 3, 74, 3, + 74, 3, 75, 3, 75, 3, 76, 3, 76, 3, 77, 3, 77, 3, 78, 3, 78, 3, 79, 3, 79, + 3, 80, 3, 80, 3, 81, 3, 81, 3, 82, 3, 82, 3, 83, 3, 83, 3, 84, 3, 84, 3, + 85, 3, 85, 3, 86, 3, 86, 3, 87, 3, 87, 3, 88, 3, 88, 3, 89, 3, 89, 3, 90, + 3, 90, 3, 91, 3, 91, 3, 92, 3, 92, 3, 93, 3, 93, 3, 93, 3, 93, 3, 93, 3, + 93, 3, 93, 5, 93, 842, 10, 93, 3, 94, 3, 94, 5, 94, 846, 10, 94, 3, 95, + 5, 95, 849, 10, 95, 3, 95, 3, 95, 5, 95, 853, 10, 95, 3, 96, 3, 96, 3, + 96, 5, 96, 858, 10, 96, 5, 96, 860, 10, 96, 3, 96, 3, 96, 3, 96, 5, 96, + 865, 10, 96, 3, 97, 3, 97, 3, 97, 3, 97, 3, 98, 3, 98, 3, 99, 3, 99, 3, + 100, 5, 100, 876, 10, 100, 3, 100, 3, 100, 3, 101, 6, 101, 881, 10, 101, + 13, 101, 14, 101, 882, 3, 102, 3, 102, 5, 102, 887, 10, 102, 3, 103, 3, + 103, 5, 103, 891, 10, 103, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, 3, 104, + 3, 104, 3, 104, 3, 104, 5, 104, 902, 10, 104, 3, 105, 5, 105, 905, 10, + 105, 3, 105, 3, 105, 5, 105, 909, 10, 105, 3, 106, 3, 106, 3, 106, 5, 106, + 914, 10, 106, 3, 107, 3, 107, 3, 107, 3, 107, 3, 107, 3, 107, 3, 108, 3, + 108, 3, 108, 3, 108, 3, 108, 3, 109, 3, 109, 3, 109, 3, 110, 3, 110, 3, + 110, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 3, 111, 5, 111, 939, 10, 111, + 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 3, 112, 5, 112, 947, 10, 112, 3, + 113, 3, 113, 3, 113, 3, 114, 3, 114, 3, 114, 3, 115, 3, 115, 3, 115, 3, + 115, 6, 115, 959, 10, 115, 13, 115, 14, 115, 960, 5, 115, 963, 10, 115, + 3, 116, 3, 116, 3, 116, 3, 116, 3, 117, 6, 117, 970, 10, 117, 13, 117, + 14, 117, 971, 3, 117, 3, 117, 3, 118, 3, 118, 3, 118, 3, 118, 3, 119, 3, + 119, 3, 119, 3, 119, 3, 119, 3, 120, 3, 120, 3, 120, 3, 120, 2, 2, 121, 4, 2, 6, 2, 8, 2, 10, 2, 12, 2, 14, 2, 16, 2, 18, 2, 20, 2, 22, 2, 24, 2, 26, 2, 28, 2, 30, 2, 32, 2, 34, 2, 36, 2, 38, 2, 40, 2, 42, 2, 44, 2, 46, 2, 48, 2, 50, 2, 52, 2, 54, 2, 56, 3, 58, 4, 60, 5, 62, 6, 64, 7, 66, 8, 68, 9, 70, 10, 72, 11, 74, 12, 76, 13, 78, 14, 80, 15, 82, 16, 84, 17, 86, 18, 88, 19, 90, 20, 92, 21, 94, 22, 96, 23, 98, 24, 100, 25, 102, 26, 104, 27, 106, 28, 108, 29, 110, 30, 112, 31, 114, 32, 116, 33, 118, 34, - 120, 35, 122, 36, 124, 37, 126, 2, 128, 38, 130, 39, 132, 40, 134, 41, + 120, 35, 122, 36, 124, 37, 126, 38, 128, 2, 130, 39, 132, 40, 134, 41, 136, 42, 138, 43, 140, 44, 142, 45, 144, 46, 146, 47, 148, 48, 150, 49, 152, 50, 154, 51, 156, 52, 158, 53, 160, 54, 162, 55, 164, 56, 166, 57, 168, 58, 170, 59, 172, 60, 174, 61, 176, 62, 178, 63, 180, 64, 182, 65, 184, 66, 186, 67, 188, 68, 190, 69, 192, 70, 194, 71, 196, 72, 198, 73, 200, 74, 202, 75, 204, 76, 206, 77, 208, 78, 210, 79, 212, 80, 214, 81, 216, 82, 218, 83, 220, 84, 222, 85, 224, 86, 226, 87, 228, 88, 230, 89, - 232, 90, 234, 91, 236, 92, 238, 2, 4, 2, 3, 32, 4, 2, 67, 67, 99, 99, 4, - 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, 102, 4, - 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, 105, 4, - 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, 108, 4, - 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, 111, 4, - 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, 114, 4, - 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, 117, 4, - 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, 120, 4, - 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, 123, 4, - 2, 92, 92, 124, 124, 4, 2, 67, 92, 99, 124, 3, 2, 50, 59, 5, 2, 11, 12, - 15, 15, 34, 34, 3, 2, 41, 41, 2, 1011, 2, 56, 3, 2, 2, 2, 2, 58, 3, 2, - 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, 66, 3, - 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, 2, 74, - 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, 2, 2, - 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, 2, 2, - 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, 2, 2, - 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, 104, 3, - 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, 2, 2, 2, - 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, 3, 2, - 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, 2, 126, - 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, 2, 2, 2, - 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, 140, 3, - 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, 2, 2, 2, - 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, 3, 2, - 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, 2, 162, - 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, 2, 2, 2, - 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, 176, 3, - 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, 2, 2, 2, - 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, 3, 2, - 2, 2, 2, 192, 3, 2, 2, 2, 2, 194, 3, 2, 2, 2, 2, 196, 3, 2, 2, 2, 2, 198, - 3, 2, 2, 2, 2, 200, 3, 2, 2, 2, 2, 202, 3, 2, 2, 2, 2, 204, 3, 2, 2, 2, - 2, 206, 3, 2, 2, 2, 2, 208, 3, 2, 2, 2, 2, 210, 3, 2, 2, 2, 2, 212, 3, - 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, 2, 2, 2, - 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, 3, 2, - 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, 3, 234, - 3, 2, 2, 2, 3, 236, 3, 2, 2, 2, 3, 238, 3, 2, 2, 2, 4, 240, 3, 2, 2, 2, - 6, 242, 3, 2, 2, 2, 8, 244, 3, 2, 2, 2, 10, 246, 3, 2, 2, 2, 12, 248, 3, - 2, 2, 2, 14, 250, 3, 2, 2, 2, 16, 252, 3, 2, 2, 2, 18, 254, 3, 2, 2, 2, - 20, 256, 3, 2, 2, 2, 22, 258, 3, 2, 2, 2, 24, 260, 3, 2, 2, 2, 26, 262, - 3, 2, 2, 2, 28, 264, 3, 2, 2, 2, 30, 266, 3, 2, 2, 2, 32, 268, 3, 2, 2, - 2, 34, 270, 3, 2, 2, 2, 36, 272, 3, 2, 2, 2, 38, 274, 3, 2, 2, 2, 40, 276, - 3, 2, 2, 2, 42, 278, 3, 2, 2, 2, 44, 280, 3, 2, 2, 2, 46, 282, 3, 2, 2, - 2, 48, 284, 3, 2, 2, 2, 50, 286, 3, 2, 2, 2, 52, 288, 3, 2, 2, 2, 54, 290, - 3, 2, 2, 2, 56, 298, 3, 2, 2, 2, 58, 300, 3, 2, 2, 2, 60, 302, 3, 2, 2, - 2, 62, 304, 3, 2, 2, 2, 64, 306, 3, 2, 2, 2, 66, 309, 3, 2, 2, 2, 68, 312, - 3, 2, 2, 2, 70, 326, 3, 2, 2, 2, 72, 328, 3, 2, 2, 2, 74, 332, 3, 2, 2, - 2, 76, 335, 3, 2, 2, 2, 78, 339, 3, 2, 2, 2, 80, 344, 3, 2, 2, 2, 82, 350, - 3, 2, 2, 2, 84, 358, 3, 2, 2, 2, 86, 361, 3, 2, 2, 2, 88, 366, 3, 2, 2, - 2, 90, 375, 3, 2, 2, 2, 92, 386, 3, 2, 2, 2, 94, 397, 3, 2, 2, 2, 96, 472, - 3, 2, 2, 2, 98, 588, 3, 2, 2, 2, 100, 630, 3, 2, 2, 2, 102, 632, 3, 2, - 2, 2, 104, 639, 3, 2, 2, 2, 106, 645, 3, 2, 2, 2, 108, 650, 3, 2, 2, 2, - 110, 653, 3, 2, 2, 2, 112, 659, 3, 2, 2, 2, 114, 670, 3, 2, 2, 2, 116, - 678, 3, 2, 2, 2, 118, 689, 3, 2, 2, 2, 120, 705, 3, 2, 2, 2, 122, 718, - 3, 2, 2, 2, 124, 737, 3, 2, 2, 2, 126, 746, 3, 2, 2, 2, 128, 753, 3, 2, - 2, 2, 130, 766, 3, 2, 2, 2, 132, 768, 3, 2, 2, 2, 134, 774, 3, 2, 2, 2, - 136, 776, 3, 2, 2, 2, 138, 778, 3, 2, 2, 2, 140, 780, 3, 2, 2, 2, 142, - 782, 3, 2, 2, 2, 144, 784, 3, 2, 2, 2, 146, 786, 3, 2, 2, 2, 148, 788, - 3, 2, 2, 2, 150, 790, 3, 2, 2, 2, 152, 792, 3, 2, 2, 2, 154, 794, 3, 2, - 2, 2, 156, 796, 3, 2, 2, 2, 158, 798, 3, 2, 2, 2, 160, 800, 3, 2, 2, 2, - 162, 802, 3, 2, 2, 2, 164, 804, 3, 2, 2, 2, 166, 806, 3, 2, 2, 2, 168, - 808, 3, 2, 2, 2, 170, 810, 3, 2, 2, 2, 172, 812, 3, 2, 2, 2, 174, 814, - 3, 2, 2, 2, 176, 816, 3, 2, 2, 2, 178, 818, 3, 2, 2, 2, 180, 820, 3, 2, - 2, 2, 182, 822, 3, 2, 2, 2, 184, 831, 3, 2, 2, 2, 186, 835, 3, 2, 2, 2, - 188, 842, 3, 2, 2, 2, 190, 854, 3, 2, 2, 2, 192, 856, 3, 2, 2, 2, 194, - 860, 3, 2, 2, 2, 196, 862, 3, 2, 2, 2, 198, 865, 3, 2, 2, 2, 200, 870, - 3, 2, 2, 2, 202, 876, 3, 2, 2, 2, 204, 880, 3, 2, 2, 2, 206, 891, 3, 2, - 2, 2, 208, 894, 3, 2, 2, 2, 210, 903, 3, 2, 2, 2, 212, 905, 3, 2, 2, 2, - 214, 911, 3, 2, 2, 2, 216, 916, 3, 2, 2, 2, 218, 919, 3, 2, 2, 2, 220, - 922, 3, 2, 2, 2, 222, 936, 3, 2, 2, 2, 224, 938, 3, 2, 2, 2, 226, 941, - 3, 2, 2, 2, 228, 944, 3, 2, 2, 2, 230, 954, 3, 2, 2, 2, 232, 959, 3, 2, - 2, 2, 234, 965, 3, 2, 2, 2, 236, 969, 3, 2, 2, 2, 238, 974, 3, 2, 2, 2, - 240, 241, 9, 2, 2, 2, 241, 5, 3, 2, 2, 2, 242, 243, 9, 3, 2, 2, 243, 7, - 3, 2, 2, 2, 244, 245, 9, 4, 2, 2, 245, 9, 3, 2, 2, 2, 246, 247, 9, 5, 2, - 2, 247, 11, 3, 2, 2, 2, 248, 249, 9, 6, 2, 2, 249, 13, 3, 2, 2, 2, 250, - 251, 9, 7, 2, 2, 251, 15, 3, 2, 2, 2, 252, 253, 9, 8, 2, 2, 253, 17, 3, - 2, 2, 2, 254, 255, 9, 9, 2, 2, 255, 19, 3, 2, 2, 2, 256, 257, 9, 10, 2, - 2, 257, 21, 3, 2, 2, 2, 258, 259, 9, 11, 2, 2, 259, 23, 3, 2, 2, 2, 260, - 261, 9, 12, 2, 2, 261, 25, 3, 2, 2, 2, 262, 263, 9, 13, 2, 2, 263, 27, - 3, 2, 2, 2, 264, 265, 9, 14, 2, 2, 265, 29, 3, 2, 2, 2, 266, 267, 9, 15, - 2, 2, 267, 31, 3, 2, 2, 2, 268, 269, 9, 16, 2, 2, 269, 33, 3, 2, 2, 2, - 270, 271, 9, 17, 2, 2, 271, 35, 3, 2, 2, 2, 272, 273, 9, 18, 2, 2, 273, - 37, 3, 2, 2, 2, 274, 275, 9, 19, 2, 2, 275, 39, 3, 2, 2, 2, 276, 277, 9, - 20, 2, 2, 277, 41, 3, 2, 2, 2, 278, 279, 9, 21, 2, 2, 279, 43, 3, 2, 2, - 2, 280, 281, 9, 22, 2, 2, 281, 45, 3, 2, 2, 2, 282, 283, 9, 23, 2, 2, 283, - 47, 3, 2, 2, 2, 284, 285, 9, 24, 2, 2, 285, 49, 3, 2, 2, 2, 286, 287, 9, - 25, 2, 2, 287, 51, 3, 2, 2, 2, 288, 289, 9, 26, 2, 2, 289, 53, 3, 2, 2, - 2, 290, 291, 9, 27, 2, 2, 291, 55, 3, 2, 2, 2, 292, 299, 5, 60, 30, 2, - 293, 299, 5, 64, 32, 2, 294, 299, 5, 58, 29, 2, 295, 299, 5, 62, 31, 2, - 296, 299, 5, 68, 34, 2, 297, 299, 5, 66, 33, 2, 298, 292, 3, 2, 2, 2, 298, - 293, 3, 2, 2, 2, 298, 294, 3, 2, 2, 2, 298, 295, 3, 2, 2, 2, 298, 296, - 3, 2, 2, 2, 298, 297, 3, 2, 2, 2, 299, 57, 3, 2, 2, 2, 300, 301, 7, 62, - 2, 2, 301, 59, 3, 2, 2, 2, 302, 303, 7, 63, 2, 2, 303, 61, 3, 2, 2, 2, - 304, 305, 7, 64, 2, 2, 305, 63, 3, 2, 2, 2, 306, 307, 5, 58, 29, 2, 307, - 308, 5, 62, 31, 2, 308, 65, 3, 2, 2, 2, 309, 310, 5, 62, 31, 2, 310, 311, - 5, 60, 30, 2, 311, 67, 3, 2, 2, 2, 312, 313, 5, 58, 29, 2, 313, 314, 5, - 60, 30, 2, 314, 69, 3, 2, 2, 2, 315, 316, 5, 42, 21, 2, 316, 317, 5, 38, - 19, 2, 317, 318, 5, 44, 22, 2, 318, 319, 5, 12, 6, 2, 319, 327, 3, 2, 2, - 2, 320, 321, 5, 14, 7, 2, 321, 322, 5, 4, 2, 2, 322, 323, 5, 26, 13, 2, - 323, 324, 5, 40, 20, 2, 324, 325, 5, 12, 6, 2, 325, 327, 3, 2, 2, 2, 326, - 315, 3, 2, 2, 2, 326, 320, 3, 2, 2, 2, 327, 71, 3, 2, 2, 2, 328, 329, 5, - 4, 2, 2, 329, 330, 5, 30, 15, 2, 330, 331, 5, 10, 5, 2, 331, 73, 3, 2, - 2, 2, 332, 333, 5, 32, 16, 2, 333, 334, 5, 38, 19, 2, 334, 75, 3, 2, 2, - 2, 335, 336, 5, 30, 15, 2, 336, 337, 5, 32, 16, 2, 337, 338, 5, 42, 21, - 2, 338, 77, 3, 2, 2, 2, 339, 340, 5, 26, 13, 2, 340, 341, 5, 20, 10, 2, - 341, 342, 5, 24, 12, 2, 342, 343, 5, 12, 6, 2, 343, 79, 3, 2, 2, 2, 344, - 345, 5, 20, 10, 2, 345, 346, 5, 26, 13, 2, 346, 347, 5, 20, 10, 2, 347, - 348, 5, 24, 12, 2, 348, 349, 5, 12, 6, 2, 349, 81, 3, 2, 2, 2, 350, 351, - 5, 6, 3, 2, 351, 352, 5, 12, 6, 2, 352, 353, 5, 42, 21, 2, 353, 354, 5, - 48, 24, 2, 354, 355, 5, 12, 6, 2, 355, 356, 5, 12, 6, 2, 356, 357, 5, 30, - 15, 2, 357, 83, 3, 2, 2, 2, 358, 359, 5, 20, 10, 2, 359, 360, 5, 40, 20, - 2, 360, 85, 3, 2, 2, 2, 361, 362, 5, 30, 15, 2, 362, 363, 5, 44, 22, 2, - 363, 364, 5, 26, 13, 2, 364, 365, 5, 26, 13, 2, 365, 87, 3, 2, 2, 2, 366, - 367, 5, 48, 24, 2, 367, 368, 5, 20, 10, 2, 368, 369, 5, 26, 13, 2, 369, - 370, 5, 10, 5, 2, 370, 371, 5, 8, 4, 2, 371, 372, 5, 4, 2, 2, 372, 373, - 5, 38, 19, 2, 373, 374, 5, 10, 5, 2, 374, 89, 3, 2, 2, 2, 375, 376, 5, - 40, 20, 2, 376, 377, 5, 20, 10, 2, 377, 378, 5, 30, 15, 2, 378, 379, 5, - 16, 8, 2, 379, 380, 5, 26, 13, 2, 380, 381, 5, 12, 6, 2, 381, 382, 5, 8, - 4, 2, 382, 383, 5, 18, 9, 2, 383, 384, 5, 4, 2, 2, 384, 385, 5, 38, 19, - 2, 385, 91, 3, 2, 2, 2, 386, 387, 5, 12, 6, 2, 387, 388, 5, 40, 20, 2, - 388, 389, 5, 8, 4, 2, 389, 390, 5, 4, 2, 2, 390, 391, 5, 34, 17, 2, 391, - 392, 5, 12, 6, 2, 392, 393, 5, 8, 4, 2, 393, 394, 5, 18, 9, 2, 394, 395, - 5, 4, 2, 2, 395, 396, 5, 38, 19, 2, 396, 93, 3, 2, 2, 2, 397, 398, 5, 30, - 15, 2, 398, 399, 5, 32, 16, 2, 399, 400, 5, 8, 4, 2, 400, 401, 5, 4, 2, - 2, 401, 402, 5, 40, 20, 2, 402, 403, 5, 12, 6, 2, 403, 95, 3, 2, 2, 2, - 404, 405, 5, 12, 6, 2, 405, 406, 5, 36, 18, 2, 406, 407, 5, 44, 22, 2, - 407, 408, 5, 4, 2, 2, 408, 409, 5, 26, 13, 2, 409, 410, 5, 40, 20, 2, 410, - 473, 3, 2, 2, 2, 411, 412, 5, 10, 5, 2, 412, 413, 5, 20, 10, 2, 413, 414, - 5, 40, 20, 2, 414, 415, 5, 22, 11, 2, 415, 416, 5, 32, 16, 2, 416, 417, - 5, 20, 10, 2, 417, 418, 5, 30, 15, 2, 418, 419, 5, 42, 21, 2, 419, 473, - 3, 2, 2, 2, 420, 421, 5, 42, 21, 2, 421, 422, 5, 32, 16, 2, 422, 423, 5, - 44, 22, 2, 423, 424, 5, 8, 4, 2, 424, 425, 5, 18, 9, 2, 425, 426, 5, 12, - 6, 2, 426, 427, 5, 40, 20, 2, 427, 473, 3, 2, 2, 2, 428, 429, 5, 48, 24, - 2, 429, 430, 5, 20, 10, 2, 430, 431, 5, 42, 21, 2, 431, 432, 5, 18, 9, - 2, 432, 433, 5, 20, 10, 2, 433, 434, 5, 30, 15, 2, 434, 473, 3, 2, 2, 2, - 435, 436, 5, 32, 16, 2, 436, 437, 5, 46, 23, 2, 437, 438, 5, 12, 6, 2, - 438, 439, 5, 38, 19, 2, 439, 440, 5, 26, 13, 2, 440, 441, 5, 4, 2, 2, 441, - 442, 5, 34, 17, 2, 442, 443, 5, 40, 20, 2, 443, 473, 3, 2, 2, 2, 444, 445, - 5, 8, 4, 2, 445, 446, 5, 38, 19, 2, 446, 447, 5, 32, 16, 2, 447, 448, 5, - 40, 20, 2, 448, 449, 5, 40, 20, 2, 449, 450, 5, 12, 6, 2, 450, 451, 5, - 40, 20, 2, 451, 473, 3, 2, 2, 2, 452, 453, 5, 20, 10, 2, 453, 454, 5, 30, - 15, 2, 454, 455, 5, 42, 21, 2, 455, 456, 5, 12, 6, 2, 456, 457, 5, 38, - 19, 2, 457, 458, 5, 40, 20, 2, 458, 459, 5, 12, 6, 2, 459, 460, 5, 8, 4, - 2, 460, 461, 5, 42, 21, 2, 461, 462, 5, 40, 20, 2, 462, 473, 3, 2, 2, 2, - 463, 464, 5, 8, 4, 2, 464, 465, 5, 32, 16, 2, 465, 466, 5, 30, 15, 2, 466, - 467, 5, 42, 21, 2, 467, 468, 5, 4, 2, 2, 468, 469, 5, 20, 10, 2, 469, 470, - 5, 30, 15, 2, 470, 471, 5, 40, 20, 2, 471, 473, 3, 2, 2, 2, 472, 404, 3, - 2, 2, 2, 472, 411, 3, 2, 2, 2, 472, 420, 3, 2, 2, 2, 472, 428, 3, 2, 2, - 2, 472, 435, 3, 2, 2, 2, 472, 444, 3, 2, 2, 2, 472, 452, 3, 2, 2, 2, 472, - 463, 3, 2, 2, 2, 473, 97, 3, 2, 2, 2, 474, 475, 5, 4, 2, 2, 475, 476, 5, - 14, 7, 2, 476, 477, 5, 42, 21, 2, 477, 478, 5, 12, 6, 2, 478, 479, 5, 38, - 19, 2, 479, 589, 3, 2, 2, 2, 480, 481, 5, 6, 3, 2, 481, 482, 5, 12, 6, - 2, 482, 483, 5, 14, 7, 2, 483, 484, 5, 32, 16, 2, 484, 485, 5, 38, 19, - 2, 485, 486, 5, 12, 6, 2, 486, 589, 3, 2, 2, 2, 487, 488, 5, 6, 3, 2, 488, - 489, 5, 12, 6, 2, 489, 490, 5, 16, 8, 2, 490, 491, 5, 20, 10, 2, 491, 492, - 5, 30, 15, 2, 492, 493, 5, 40, 20, 2, 493, 589, 3, 2, 2, 2, 494, 495, 5, - 6, 3, 2, 495, 496, 5, 12, 6, 2, 496, 497, 5, 16, 8, 2, 497, 498, 5, 44, - 22, 2, 498, 499, 5, 30, 15, 2, 499, 500, 5, 6, 3, 2, 500, 501, 5, 52, 26, - 2, 501, 589, 3, 2, 2, 2, 502, 503, 5, 42, 21, 2, 503, 504, 5, 8, 4, 2, - 504, 505, 5, 32, 16, 2, 505, 506, 5, 30, 15, 2, 506, 507, 5, 42, 21, 2, - 507, 508, 5, 4, 2, 2, 508, 509, 5, 20, 10, 2, 509, 510, 5, 30, 15, 2, 510, - 511, 5, 40, 20, 2, 511, 589, 3, 2, 2, 2, 512, 513, 5, 10, 5, 2, 513, 514, - 5, 44, 22, 2, 514, 515, 5, 38, 19, 2, 515, 516, 5, 20, 10, 2, 516, 517, - 5, 30, 15, 2, 517, 518, 5, 16, 8, 2, 518, 589, 3, 2, 2, 2, 519, 520, 5, - 12, 6, 2, 520, 521, 5, 30, 15, 2, 521, 522, 5, 10, 5, 2, 522, 523, 5, 12, - 6, 2, 523, 524, 5, 10, 5, 2, 524, 525, 5, 6, 3, 2, 525, 526, 5, 52, 26, - 2, 526, 589, 3, 2, 2, 2, 527, 528, 5, 12, 6, 2, 528, 529, 5, 30, 15, 2, - 529, 530, 5, 10, 5, 2, 530, 531, 5, 40, 20, 2, 531, 589, 3, 2, 2, 2, 532, - 533, 5, 42, 21, 2, 533, 534, 5, 12, 6, 2, 534, 535, 5, 36, 18, 2, 535, - 536, 5, 44, 22, 2, 536, 537, 5, 4, 2, 2, 537, 538, 5, 26, 13, 2, 538, 539, - 5, 40, 20, 2, 539, 589, 3, 2, 2, 2, 540, 541, 5, 28, 14, 2, 541, 542, 5, - 12, 6, 2, 542, 543, 5, 12, 6, 2, 543, 544, 5, 42, 21, 2, 544, 545, 5, 40, - 20, 2, 545, 589, 3, 2, 2, 2, 546, 547, 5, 28, 14, 2, 547, 548, 5, 12, 6, - 2, 548, 549, 5, 42, 21, 2, 549, 550, 5, 6, 3, 2, 550, 551, 5, 52, 26, 2, - 551, 589, 3, 2, 2, 2, 552, 553, 5, 42, 21, 2, 553, 554, 5, 32, 16, 2, 554, - 555, 5, 46, 23, 2, 555, 556, 5, 12, 6, 2, 556, 557, 5, 38, 19, 2, 557, - 558, 5, 26, 13, 2, 558, 559, 5, 4, 2, 2, 559, 560, 5, 34, 17, 2, 560, 561, - 5, 40, 20, 2, 561, 589, 3, 2, 2, 2, 562, 563, 5, 32, 16, 2, 563, 564, 5, - 46, 23, 2, 564, 565, 5, 12, 6, 2, 565, 566, 5, 38, 19, 2, 566, 567, 5, - 26, 13, 2, 567, 568, 5, 4, 2, 2, 568, 569, 5, 34, 17, 2, 569, 570, 5, 34, - 17, 2, 570, 571, 5, 12, 6, 2, 571, 572, 5, 10, 5, 2, 572, 573, 5, 6, 3, - 2, 573, 574, 5, 52, 26, 2, 574, 589, 3, 2, 2, 2, 575, 576, 5, 4, 2, 2, - 576, 577, 5, 30, 15, 2, 577, 578, 5, 52, 26, 2, 578, 579, 5, 20, 10, 2, - 579, 580, 5, 30, 15, 2, 580, 581, 5, 42, 21, 2, 581, 582, 5, 12, 6, 2, - 582, 583, 5, 38, 19, 2, 583, 584, 5, 4, 2, 2, 584, 585, 5, 8, 4, 2, 585, - 586, 5, 42, 21, 2, 586, 587, 5, 40, 20, 2, 587, 589, 3, 2, 2, 2, 588, 474, - 3, 2, 2, 2, 588, 480, 3, 2, 2, 2, 588, 487, 3, 2, 2, 2, 588, 494, 3, 2, - 2, 2, 588, 502, 3, 2, 2, 2, 588, 512, 3, 2, 2, 2, 588, 519, 3, 2, 2, 2, - 588, 527, 3, 2, 2, 2, 588, 532, 3, 2, 2, 2, 588, 540, 3, 2, 2, 2, 588, - 546, 3, 2, 2, 2, 588, 552, 3, 2, 2, 2, 588, 562, 3, 2, 2, 2, 588, 575, - 3, 2, 2, 2, 589, 99, 3, 2, 2, 2, 590, 591, 5, 4, 2, 2, 591, 592, 5, 12, - 6, 2, 592, 593, 5, 36, 18, 2, 593, 594, 5, 44, 22, 2, 594, 595, 5, 4, 2, - 2, 595, 596, 5, 26, 13, 2, 596, 597, 5, 40, 20, 2, 597, 631, 3, 2, 2, 2, - 598, 599, 5, 4, 2, 2, 599, 600, 5, 8, 4, 2, 600, 601, 5, 32, 16, 2, 601, - 602, 5, 30, 15, 2, 602, 603, 5, 42, 21, 2, 603, 604, 5, 4, 2, 2, 604, 605, - 5, 20, 10, 2, 605, 606, 5, 30, 15, 2, 606, 607, 5, 40, 20, 2, 607, 631, - 3, 2, 2, 2, 608, 609, 5, 8, 4, 2, 609, 610, 5, 32, 16, 2, 610, 611, 5, - 30, 15, 2, 611, 612, 5, 42, 21, 2, 612, 613, 5, 4, 2, 2, 613, 614, 5, 20, - 10, 2, 614, 615, 5, 30, 15, 2, 615, 616, 5, 12, 6, 2, 616, 617, 5, 10, - 5, 2, 617, 618, 5, 6, 3, 2, 618, 619, 5, 52, 26, 2, 619, 631, 3, 2, 2, - 2, 620, 621, 5, 4, 2, 2, 621, 622, 5, 32, 16, 2, 622, 623, 5, 46, 23, 2, - 623, 624, 5, 12, 6, 2, 624, 625, 5, 38, 19, 2, 625, 626, 5, 26, 13, 2, - 626, 627, 5, 4, 2, 2, 627, 628, 5, 34, 17, 2, 628, 629, 5, 40, 20, 2, 629, - 631, 3, 2, 2, 2, 630, 590, 3, 2, 2, 2, 630, 598, 3, 2, 2, 2, 630, 608, - 3, 2, 2, 2, 630, 620, 3, 2, 2, 2, 631, 101, 3, 2, 2, 2, 632, 633, 5, 12, - 6, 2, 633, 634, 5, 50, 25, 2, 634, 635, 5, 20, 10, 2, 635, 636, 5, 40, - 20, 2, 636, 637, 5, 42, 21, 2, 637, 638, 5, 40, 20, 2, 638, 103, 3, 2, - 2, 2, 639, 640, 5, 12, 6, 2, 640, 641, 5, 50, 25, 2, 641, 642, 5, 20, 10, - 2, 642, 643, 5, 40, 20, 2, 643, 644, 5, 42, 21, 2, 644, 105, 3, 2, 2, 2, - 645, 646, 5, 10, 5, 2, 646, 647, 5, 32, 16, 2, 647, 648, 5, 12, 6, 2, 648, - 649, 5, 40, 20, 2, 649, 107, 3, 2, 2, 2, 650, 651, 5, 20, 10, 2, 651, 652, - 5, 30, 15, 2, 652, 109, 3, 2, 2, 2, 653, 654, 5, 34, 17, 2, 654, 655, 5, - 32, 16, 2, 655, 656, 5, 20, 10, 2, 656, 657, 5, 30, 15, 2, 657, 658, 5, - 42, 21, 2, 658, 111, 3, 2, 2, 2, 659, 660, 5, 26, 13, 2, 660, 661, 5, 20, - 10, 2, 661, 662, 5, 30, 15, 2, 662, 663, 5, 12, 6, 2, 663, 664, 5, 40, - 20, 2, 664, 665, 5, 42, 21, 2, 665, 666, 5, 38, 19, 2, 666, 667, 5, 20, - 10, 2, 667, 668, 5, 30, 15, 2, 668, 669, 5, 16, 8, 2, 669, 113, 3, 2, 2, - 2, 670, 671, 5, 34, 17, 2, 671, 672, 5, 32, 16, 2, 672, 673, 5, 26, 13, - 2, 673, 674, 5, 52, 26, 2, 674, 675, 5, 16, 8, 2, 675, 676, 5, 32, 16, - 2, 676, 677, 5, 30, 15, 2, 677, 115, 3, 2, 2, 2, 678, 679, 5, 28, 14, 2, - 679, 680, 5, 44, 22, 2, 680, 681, 5, 26, 13, 2, 681, 682, 5, 42, 21, 2, - 682, 683, 5, 20, 10, 2, 683, 684, 5, 34, 17, 2, 684, 685, 5, 32, 16, 2, - 685, 686, 5, 20, 10, 2, 686, 687, 5, 30, 15, 2, 687, 688, 5, 42, 21, 2, - 688, 117, 3, 2, 2, 2, 689, 690, 5, 28, 14, 2, 690, 691, 5, 44, 22, 2, 691, - 692, 5, 26, 13, 2, 692, 693, 5, 42, 21, 2, 693, 694, 5, 20, 10, 2, 694, - 695, 5, 26, 13, 2, 695, 696, 5, 20, 10, 2, 696, 697, 5, 30, 15, 2, 697, - 698, 5, 12, 6, 2, 698, 699, 5, 40, 20, 2, 699, 700, 5, 42, 21, 2, 700, - 701, 5, 38, 19, 2, 701, 702, 5, 20, 10, 2, 702, 703, 5, 30, 15, 2, 703, - 704, 5, 16, 8, 2, 704, 119, 3, 2, 2, 2, 705, 706, 5, 28, 14, 2, 706, 707, - 5, 44, 22, 2, 707, 708, 5, 26, 13, 2, 708, 709, 5, 42, 21, 2, 709, 710, - 5, 20, 10, 2, 710, 711, 5, 34, 17, 2, 711, 712, 5, 32, 16, 2, 712, 713, - 5, 26, 13, 2, 713, 714, 5, 52, 26, 2, 714, 715, 5, 16, 8, 2, 715, 716, - 5, 32, 16, 2, 716, 717, 5, 30, 15, 2, 717, 121, 3, 2, 2, 2, 718, 719, 5, - 16, 8, 2, 719, 720, 5, 12, 6, 2, 720, 721, 5, 32, 16, 2, 721, 722, 5, 28, - 14, 2, 722, 723, 5, 12, 6, 2, 723, 724, 5, 42, 21, 2, 724, 725, 5, 38, - 19, 2, 725, 726, 5, 52, 26, 2, 726, 727, 5, 8, 4, 2, 727, 728, 5, 32, 16, - 2, 728, 729, 5, 26, 13, 2, 729, 730, 5, 26, 13, 2, 730, 731, 5, 12, 6, - 2, 731, 732, 5, 8, 4, 2, 732, 733, 5, 42, 21, 2, 733, 734, 5, 20, 10, 2, - 734, 735, 5, 32, 16, 2, 735, 736, 5, 30, 15, 2, 736, 123, 3, 2, 2, 2, 737, - 738, 5, 12, 6, 2, 738, 739, 5, 30, 15, 2, 739, 740, 5, 46, 23, 2, 740, - 741, 5, 12, 6, 2, 741, 742, 5, 26, 13, 2, 742, 743, 5, 32, 16, 2, 743, - 744, 5, 34, 17, 2, 744, 745, 5, 12, 6, 2, 745, 125, 3, 2, 2, 2, 746, 747, - 5, 152, 76, 2, 747, 748, 3, 2, 2, 2, 748, 749, 8, 63, 2, 2, 749, 750, 8, - 63, 3, 2, 750, 127, 3, 2, 2, 2, 751, 754, 5, 186, 93, 2, 752, 754, 5, 188, - 94, 2, 753, 751, 3, 2, 2, 2, 753, 752, 3, 2, 2, 2, 754, 129, 3, 2, 2, 2, - 755, 759, 5, 132, 66, 2, 756, 758, 5, 134, 67, 2, 757, 756, 3, 2, 2, 2, - 758, 761, 3, 2, 2, 2, 759, 757, 3, 2, 2, 2, 759, 760, 3, 2, 2, 2, 760, - 767, 3, 2, 2, 2, 761, 759, 3, 2, 2, 2, 762, 763, 5, 146, 73, 2, 763, 764, - 5, 130, 65, 2, 764, 765, 5, 146, 73, 2, 765, 767, 3, 2, 2, 2, 766, 755, - 3, 2, 2, 2, 766, 762, 3, 2, 2, 2, 767, 131, 3, 2, 2, 2, 768, 769, 5, 136, - 68, 2, 769, 133, 3, 2, 2, 2, 770, 775, 5, 136, 68, 2, 771, 775, 5, 138, - 69, 2, 772, 775, 5, 144, 72, 2, 773, 775, 5, 142, 71, 2, 774, 770, 3, 2, - 2, 2, 774, 771, 3, 2, 2, 2, 774, 772, 3, 2, 2, 2, 774, 773, 3, 2, 2, 2, - 775, 135, 3, 2, 2, 2, 776, 777, 9, 28, 2, 2, 777, 137, 3, 2, 2, 2, 778, - 779, 9, 29, 2, 2, 779, 139, 3, 2, 2, 2, 780, 781, 7, 37, 2, 2, 781, 141, - 3, 2, 2, 2, 782, 783, 7, 38, 2, 2, 783, 143, 3, 2, 2, 2, 784, 785, 7, 97, - 2, 2, 785, 145, 3, 2, 2, 2, 786, 787, 7, 36, 2, 2, 787, 147, 3, 2, 2, 2, - 788, 789, 7, 39, 2, 2, 789, 149, 3, 2, 2, 2, 790, 791, 7, 40, 2, 2, 791, - 151, 3, 2, 2, 2, 792, 793, 7, 41, 2, 2, 793, 153, 3, 2, 2, 2, 794, 795, - 7, 42, 2, 2, 795, 155, 3, 2, 2, 2, 796, 797, 7, 43, 2, 2, 797, 157, 3, - 2, 2, 2, 798, 799, 7, 93, 2, 2, 799, 159, 3, 2, 2, 2, 800, 801, 7, 95, - 2, 2, 801, 161, 3, 2, 2, 2, 802, 803, 7, 44, 2, 2, 803, 163, 3, 2, 2, 2, - 804, 805, 7, 45, 2, 2, 805, 165, 3, 2, 2, 2, 806, 807, 7, 46, 2, 2, 807, - 167, 3, 2, 2, 2, 808, 809, 7, 47, 2, 2, 809, 169, 3, 2, 2, 2, 810, 811, - 7, 48, 2, 2, 811, 171, 3, 2, 2, 2, 812, 813, 7, 49, 2, 2, 813, 173, 3, - 2, 2, 2, 814, 815, 7, 60, 2, 2, 815, 175, 3, 2, 2, 2, 816, 817, 7, 61, - 2, 2, 817, 177, 3, 2, 2, 2, 818, 819, 7, 65, 2, 2, 819, 179, 3, 2, 2, 2, - 820, 821, 7, 126, 2, 2, 821, 181, 3, 2, 2, 2, 822, 823, 4, 50, 51, 2, 823, - 183, 3, 2, 2, 2, 824, 832, 5, 138, 69, 2, 825, 832, 5, 4, 2, 2, 826, 832, - 5, 6, 3, 2, 827, 832, 5, 8, 4, 2, 828, 832, 5, 10, 5, 2, 829, 832, 5, 12, - 6, 2, 830, 832, 5, 14, 7, 2, 831, 824, 3, 2, 2, 2, 831, 825, 3, 2, 2, 2, - 831, 826, 3, 2, 2, 2, 831, 827, 3, 2, 2, 2, 831, 828, 3, 2, 2, 2, 831, - 829, 3, 2, 2, 2, 831, 830, 3, 2, 2, 2, 832, 185, 3, 2, 2, 2, 833, 836, - 5, 190, 95, 2, 834, 836, 5, 192, 96, 2, 835, 833, 3, 2, 2, 2, 835, 834, - 3, 2, 2, 2, 836, 187, 3, 2, 2, 2, 837, 839, 5, 202, 101, 2, 838, 837, 3, - 2, 2, 2, 838, 839, 3, 2, 2, 2, 839, 840, 3, 2, 2, 2, 840, 843, 5, 190, - 95, 2, 841, 843, 5, 192, 96, 2, 842, 838, 3, 2, 2, 2, 842, 841, 3, 2, 2, - 2, 843, 189, 3, 2, 2, 2, 844, 849, 5, 200, 100, 2, 845, 847, 5, 170, 85, - 2, 846, 848, 5, 200, 100, 2, 847, 846, 3, 2, 2, 2, 847, 848, 3, 2, 2, 2, - 848, 850, 3, 2, 2, 2, 849, 845, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, - 855, 3, 2, 2, 2, 851, 852, 5, 170, 85, 2, 852, 853, 5, 200, 100, 2, 853, - 855, 3, 2, 2, 2, 854, 844, 3, 2, 2, 2, 854, 851, 3, 2, 2, 2, 855, 191, - 3, 2, 2, 2, 856, 857, 5, 194, 97, 2, 857, 858, 7, 71, 2, 2, 858, 859, 5, - 196, 98, 2, 859, 193, 3, 2, 2, 2, 860, 861, 5, 190, 95, 2, 861, 195, 3, - 2, 2, 2, 862, 863, 5, 198, 99, 2, 863, 197, 3, 2, 2, 2, 864, 866, 5, 202, - 101, 2, 865, 864, 3, 2, 2, 2, 865, 866, 3, 2, 2, 2, 866, 867, 3, 2, 2, - 2, 867, 868, 5, 200, 100, 2, 868, 199, 3, 2, 2, 2, 869, 871, 5, 138, 69, - 2, 870, 869, 3, 2, 2, 2, 871, 872, 3, 2, 2, 2, 872, 870, 3, 2, 2, 2, 872, - 873, 3, 2, 2, 2, 873, 201, 3, 2, 2, 2, 874, 877, 5, 164, 82, 2, 875, 877, - 5, 168, 84, 2, 876, 874, 3, 2, 2, 2, 876, 875, 3, 2, 2, 2, 877, 203, 3, - 2, 2, 2, 878, 881, 5, 206, 103, 2, 879, 881, 5, 208, 104, 2, 880, 878, - 3, 2, 2, 2, 880, 879, 3, 2, 2, 2, 881, 205, 3, 2, 2, 2, 882, 892, 5, 212, - 106, 2, 883, 884, 5, 212, 106, 2, 884, 885, 7, 86, 2, 2, 885, 886, 5, 220, - 110, 2, 886, 892, 3, 2, 2, 2, 887, 888, 5, 230, 115, 2, 888, 889, 5, 154, - 77, 2, 889, 890, 5, 156, 78, 2, 890, 892, 3, 2, 2, 2, 891, 882, 3, 2, 2, - 2, 891, 883, 3, 2, 2, 2, 891, 887, 3, 2, 2, 2, 892, 207, 3, 2, 2, 2, 893, - 895, 5, 210, 105, 2, 894, 893, 3, 2, 2, 2, 894, 895, 3, 2, 2, 2, 895, 896, - 3, 2, 2, 2, 896, 898, 5, 172, 86, 2, 897, 899, 5, 210, 105, 2, 898, 897, - 3, 2, 2, 2, 898, 899, 3, 2, 2, 2, 899, 209, 3, 2, 2, 2, 900, 901, 7, 48, - 2, 2, 901, 904, 7, 48, 2, 2, 902, 904, 5, 206, 103, 2, 903, 900, 3, 2, - 2, 2, 903, 902, 3, 2, 2, 2, 904, 211, 3, 2, 2, 2, 905, 906, 5, 214, 107, - 2, 906, 907, 7, 47, 2, 2, 907, 908, 5, 216, 108, 2, 908, 909, 7, 47, 2, - 2, 909, 910, 5, 218, 109, 2, 910, 213, 3, 2, 2, 2, 911, 912, 5, 138, 69, - 2, 912, 913, 5, 138, 69, 2, 913, 914, 5, 138, 69, 2, 914, 915, 5, 138, - 69, 2, 915, 215, 3, 2, 2, 2, 916, 917, 5, 138, 69, 2, 917, 918, 5, 138, - 69, 2, 918, 217, 3, 2, 2, 2, 919, 920, 5, 138, 69, 2, 920, 921, 5, 138, - 69, 2, 921, 219, 3, 2, 2, 2, 922, 923, 5, 224, 112, 2, 923, 924, 7, 60, - 2, 2, 924, 925, 5, 226, 113, 2, 925, 926, 7, 60, 2, 2, 926, 928, 5, 228, - 114, 2, 927, 929, 5, 222, 111, 2, 928, 927, 3, 2, 2, 2, 928, 929, 3, 2, - 2, 2, 929, 221, 3, 2, 2, 2, 930, 937, 7, 92, 2, 2, 931, 932, 5, 202, 101, - 2, 932, 933, 5, 224, 112, 2, 933, 934, 7, 60, 2, 2, 934, 935, 5, 226, 113, - 2, 935, 937, 3, 2, 2, 2, 936, 930, 3, 2, 2, 2, 936, 931, 3, 2, 2, 2, 937, - 223, 3, 2, 2, 2, 938, 939, 5, 138, 69, 2, 939, 940, 5, 138, 69, 2, 940, - 225, 3, 2, 2, 2, 941, 942, 5, 138, 69, 2, 942, 943, 5, 138, 69, 2, 943, - 227, 3, 2, 2, 2, 944, 945, 5, 138, 69, 2, 945, 952, 5, 138, 69, 2, 946, - 948, 5, 170, 85, 2, 947, 949, 5, 138, 69, 2, 948, 947, 3, 2, 2, 2, 949, - 950, 3, 2, 2, 2, 950, 948, 3, 2, 2, 2, 950, 951, 3, 2, 2, 2, 951, 953, - 3, 2, 2, 2, 952, 946, 3, 2, 2, 2, 952, 953, 3, 2, 2, 2, 953, 229, 3, 2, - 2, 2, 954, 955, 5, 30, 15, 2, 955, 956, 5, 32, 16, 2, 956, 957, 5, 48, - 24, 2, 957, 231, 3, 2, 2, 2, 958, 960, 9, 30, 2, 2, 959, 958, 3, 2, 2, - 2, 960, 961, 3, 2, 2, 2, 961, 959, 3, 2, 2, 2, 961, 962, 3, 2, 2, 2, 962, - 963, 3, 2, 2, 2, 963, 964, 8, 116, 4, 2, 964, 233, 3, 2, 2, 2, 965, 966, - 7, 41, 2, 2, 966, 967, 3, 2, 2, 2, 967, 968, 8, 117, 5, 2, 968, 235, 3, - 2, 2, 2, 969, 970, 7, 41, 2, 2, 970, 971, 7, 41, 2, 2, 971, 972, 3, 2, - 2, 2, 972, 973, 8, 118, 2, 2, 973, 237, 3, 2, 2, 2, 974, 975, 10, 31, 2, - 2, 975, 976, 3, 2, 2, 2, 976, 977, 8, 119, 2, 2, 977, 239, 3, 2, 2, 2, - 33, 2, 3, 298, 326, 472, 588, 630, 753, 759, 766, 774, 831, 835, 838, 842, - 847, 849, 854, 865, 872, 876, 880, 891, 894, 898, 903, 928, 936, 950, 952, - 961, 6, 5, 2, 2, 4, 3, 2, 8, 2, 2, 4, 2, 2, + 232, 90, 234, 91, 236, 92, 238, 93, 240, 2, 4, 2, 3, 32, 4, 2, 67, 67, + 99, 99, 4, 2, 68, 68, 100, 100, 4, 2, 69, 69, 101, 101, 4, 2, 70, 70, 102, + 102, 4, 2, 71, 71, 103, 103, 4, 2, 72, 72, 104, 104, 4, 2, 73, 73, 105, + 105, 4, 2, 74, 74, 106, 106, 4, 2, 75, 75, 107, 107, 4, 2, 76, 76, 108, + 108, 4, 2, 77, 77, 109, 109, 4, 2, 78, 78, 110, 110, 4, 2, 79, 79, 111, + 111, 4, 2, 80, 80, 112, 112, 4, 2, 81, 81, 113, 113, 4, 2, 82, 82, 114, + 114, 4, 2, 83, 83, 115, 115, 4, 2, 84, 84, 116, 116, 4, 2, 85, 85, 117, + 117, 4, 2, 86, 86, 118, 118, 4, 2, 87, 87, 119, 119, 4, 2, 88, 88, 120, + 120, 4, 2, 89, 89, 121, 121, 4, 2, 90, 90, 122, 122, 4, 2, 91, 91, 123, + 123, 4, 2, 92, 92, 124, 124, 4, 2, 67, 92, 99, 124, 3, 2, 50, 59, 5, 2, + 11, 12, 15, 15, 34, 34, 3, 2, 41, 41, 2, 1021, 2, 56, 3, 2, 2, 2, 2, 58, + 3, 2, 2, 2, 2, 60, 3, 2, 2, 2, 2, 62, 3, 2, 2, 2, 2, 64, 3, 2, 2, 2, 2, + 66, 3, 2, 2, 2, 2, 68, 3, 2, 2, 2, 2, 70, 3, 2, 2, 2, 2, 72, 3, 2, 2, 2, + 2, 74, 3, 2, 2, 2, 2, 76, 3, 2, 2, 2, 2, 78, 3, 2, 2, 2, 2, 80, 3, 2, 2, + 2, 2, 82, 3, 2, 2, 2, 2, 84, 3, 2, 2, 2, 2, 86, 3, 2, 2, 2, 2, 88, 3, 2, + 2, 2, 2, 90, 3, 2, 2, 2, 2, 92, 3, 2, 2, 2, 2, 94, 3, 2, 2, 2, 2, 96, 3, + 2, 2, 2, 2, 98, 3, 2, 2, 2, 2, 100, 3, 2, 2, 2, 2, 102, 3, 2, 2, 2, 2, + 104, 3, 2, 2, 2, 2, 106, 3, 2, 2, 2, 2, 108, 3, 2, 2, 2, 2, 110, 3, 2, + 2, 2, 2, 112, 3, 2, 2, 2, 2, 114, 3, 2, 2, 2, 2, 116, 3, 2, 2, 2, 2, 118, + 3, 2, 2, 2, 2, 120, 3, 2, 2, 2, 2, 122, 3, 2, 2, 2, 2, 124, 3, 2, 2, 2, + 2, 126, 3, 2, 2, 2, 2, 128, 3, 2, 2, 2, 2, 130, 3, 2, 2, 2, 2, 132, 3, + 2, 2, 2, 2, 134, 3, 2, 2, 2, 2, 136, 3, 2, 2, 2, 2, 138, 3, 2, 2, 2, 2, + 140, 3, 2, 2, 2, 2, 142, 3, 2, 2, 2, 2, 144, 3, 2, 2, 2, 2, 146, 3, 2, + 2, 2, 2, 148, 3, 2, 2, 2, 2, 150, 3, 2, 2, 2, 2, 152, 3, 2, 2, 2, 2, 154, + 3, 2, 2, 2, 2, 156, 3, 2, 2, 2, 2, 158, 3, 2, 2, 2, 2, 160, 3, 2, 2, 2, + 2, 162, 3, 2, 2, 2, 2, 164, 3, 2, 2, 2, 2, 166, 3, 2, 2, 2, 2, 168, 3, + 2, 2, 2, 2, 170, 3, 2, 2, 2, 2, 172, 3, 2, 2, 2, 2, 174, 3, 2, 2, 2, 2, + 176, 3, 2, 2, 2, 2, 178, 3, 2, 2, 2, 2, 180, 3, 2, 2, 2, 2, 182, 3, 2, + 2, 2, 2, 184, 3, 2, 2, 2, 2, 186, 3, 2, 2, 2, 2, 188, 3, 2, 2, 2, 2, 190, + 3, 2, 2, 2, 2, 192, 3, 2, 2, 2, 2, 194, 3, 2, 2, 2, 2, 196, 3, 2, 2, 2, + 2, 198, 3, 2, 2, 2, 2, 200, 3, 2, 2, 2, 2, 202, 3, 2, 2, 2, 2, 204, 3, + 2, 2, 2, 2, 206, 3, 2, 2, 2, 2, 208, 3, 2, 2, 2, 2, 210, 3, 2, 2, 2, 2, + 212, 3, 2, 2, 2, 2, 214, 3, 2, 2, 2, 2, 216, 3, 2, 2, 2, 2, 218, 3, 2, + 2, 2, 2, 220, 3, 2, 2, 2, 2, 222, 3, 2, 2, 2, 2, 224, 3, 2, 2, 2, 2, 226, + 3, 2, 2, 2, 2, 228, 3, 2, 2, 2, 2, 230, 3, 2, 2, 2, 2, 232, 3, 2, 2, 2, + 2, 234, 3, 2, 2, 2, 3, 236, 3, 2, 2, 2, 3, 238, 3, 2, 2, 2, 3, 240, 3, + 2, 2, 2, 4, 242, 3, 2, 2, 2, 6, 244, 3, 2, 2, 2, 8, 246, 3, 2, 2, 2, 10, + 248, 3, 2, 2, 2, 12, 250, 3, 2, 2, 2, 14, 252, 3, 2, 2, 2, 16, 254, 3, + 2, 2, 2, 18, 256, 3, 2, 2, 2, 20, 258, 3, 2, 2, 2, 22, 260, 3, 2, 2, 2, + 24, 262, 3, 2, 2, 2, 26, 264, 3, 2, 2, 2, 28, 266, 3, 2, 2, 2, 30, 268, + 3, 2, 2, 2, 32, 270, 3, 2, 2, 2, 34, 272, 3, 2, 2, 2, 36, 274, 3, 2, 2, + 2, 38, 276, 3, 2, 2, 2, 40, 278, 3, 2, 2, 2, 42, 280, 3, 2, 2, 2, 44, 282, + 3, 2, 2, 2, 46, 284, 3, 2, 2, 2, 48, 286, 3, 2, 2, 2, 50, 288, 3, 2, 2, + 2, 52, 290, 3, 2, 2, 2, 54, 292, 3, 2, 2, 2, 56, 300, 3, 2, 2, 2, 58, 302, + 3, 2, 2, 2, 60, 304, 3, 2, 2, 2, 62, 306, 3, 2, 2, 2, 64, 308, 3, 2, 2, + 2, 66, 311, 3, 2, 2, 2, 68, 314, 3, 2, 2, 2, 70, 328, 3, 2, 2, 2, 72, 330, + 3, 2, 2, 2, 74, 334, 3, 2, 2, 2, 76, 337, 3, 2, 2, 2, 78, 341, 3, 2, 2, + 2, 80, 346, 3, 2, 2, 2, 82, 352, 3, 2, 2, 2, 84, 360, 3, 2, 2, 2, 86, 363, + 3, 2, 2, 2, 88, 368, 3, 2, 2, 2, 90, 377, 3, 2, 2, 2, 92, 388, 3, 2, 2, + 2, 94, 399, 3, 2, 2, 2, 96, 474, 3, 2, 2, 2, 98, 476, 3, 2, 2, 2, 100, + 598, 3, 2, 2, 2, 102, 640, 3, 2, 2, 2, 104, 642, 3, 2, 2, 2, 106, 649, + 3, 2, 2, 2, 108, 655, 3, 2, 2, 2, 110, 660, 3, 2, 2, 2, 112, 663, 3, 2, + 2, 2, 114, 669, 3, 2, 2, 2, 116, 680, 3, 2, 2, 2, 118, 688, 3, 2, 2, 2, + 120, 699, 3, 2, 2, 2, 122, 715, 3, 2, 2, 2, 124, 728, 3, 2, 2, 2, 126, + 747, 3, 2, 2, 2, 128, 756, 3, 2, 2, 2, 130, 763, 3, 2, 2, 2, 132, 776, + 3, 2, 2, 2, 134, 778, 3, 2, 2, 2, 136, 784, 3, 2, 2, 2, 138, 786, 3, 2, + 2, 2, 140, 788, 3, 2, 2, 2, 142, 790, 3, 2, 2, 2, 144, 792, 3, 2, 2, 2, + 146, 794, 3, 2, 2, 2, 148, 796, 3, 2, 2, 2, 150, 798, 3, 2, 2, 2, 152, + 800, 3, 2, 2, 2, 154, 802, 3, 2, 2, 2, 156, 804, 3, 2, 2, 2, 158, 806, + 3, 2, 2, 2, 160, 808, 3, 2, 2, 2, 162, 810, 3, 2, 2, 2, 164, 812, 3, 2, + 2, 2, 166, 814, 3, 2, 2, 2, 168, 816, 3, 2, 2, 2, 170, 818, 3, 2, 2, 2, + 172, 820, 3, 2, 2, 2, 174, 822, 3, 2, 2, 2, 176, 824, 3, 2, 2, 2, 178, + 826, 3, 2, 2, 2, 180, 828, 3, 2, 2, 2, 182, 830, 3, 2, 2, 2, 184, 832, + 3, 2, 2, 2, 186, 841, 3, 2, 2, 2, 188, 845, 3, 2, 2, 2, 190, 852, 3, 2, + 2, 2, 192, 864, 3, 2, 2, 2, 194, 866, 3, 2, 2, 2, 196, 870, 3, 2, 2, 2, + 198, 872, 3, 2, 2, 2, 200, 875, 3, 2, 2, 2, 202, 880, 3, 2, 2, 2, 204, + 886, 3, 2, 2, 2, 206, 890, 3, 2, 2, 2, 208, 901, 3, 2, 2, 2, 210, 904, + 3, 2, 2, 2, 212, 913, 3, 2, 2, 2, 214, 915, 3, 2, 2, 2, 216, 921, 3, 2, + 2, 2, 218, 926, 3, 2, 2, 2, 220, 929, 3, 2, 2, 2, 222, 932, 3, 2, 2, 2, + 224, 946, 3, 2, 2, 2, 226, 948, 3, 2, 2, 2, 228, 951, 3, 2, 2, 2, 230, + 954, 3, 2, 2, 2, 232, 964, 3, 2, 2, 2, 234, 969, 3, 2, 2, 2, 236, 975, + 3, 2, 2, 2, 238, 979, 3, 2, 2, 2, 240, 984, 3, 2, 2, 2, 242, 243, 9, 2, + 2, 2, 243, 5, 3, 2, 2, 2, 244, 245, 9, 3, 2, 2, 245, 7, 3, 2, 2, 2, 246, + 247, 9, 4, 2, 2, 247, 9, 3, 2, 2, 2, 248, 249, 9, 5, 2, 2, 249, 11, 3, + 2, 2, 2, 250, 251, 9, 6, 2, 2, 251, 13, 3, 2, 2, 2, 252, 253, 9, 7, 2, + 2, 253, 15, 3, 2, 2, 2, 254, 255, 9, 8, 2, 2, 255, 17, 3, 2, 2, 2, 256, + 257, 9, 9, 2, 2, 257, 19, 3, 2, 2, 2, 258, 259, 9, 10, 2, 2, 259, 21, 3, + 2, 2, 2, 260, 261, 9, 11, 2, 2, 261, 23, 3, 2, 2, 2, 262, 263, 9, 12, 2, + 2, 263, 25, 3, 2, 2, 2, 264, 265, 9, 13, 2, 2, 265, 27, 3, 2, 2, 2, 266, + 267, 9, 14, 2, 2, 267, 29, 3, 2, 2, 2, 268, 269, 9, 15, 2, 2, 269, 31, + 3, 2, 2, 2, 270, 271, 9, 16, 2, 2, 271, 33, 3, 2, 2, 2, 272, 273, 9, 17, + 2, 2, 273, 35, 3, 2, 2, 2, 274, 275, 9, 18, 2, 2, 275, 37, 3, 2, 2, 2, + 276, 277, 9, 19, 2, 2, 277, 39, 3, 2, 2, 2, 278, 279, 9, 20, 2, 2, 279, + 41, 3, 2, 2, 2, 280, 281, 9, 21, 2, 2, 281, 43, 3, 2, 2, 2, 282, 283, 9, + 22, 2, 2, 283, 45, 3, 2, 2, 2, 284, 285, 9, 23, 2, 2, 285, 47, 3, 2, 2, + 2, 286, 287, 9, 24, 2, 2, 287, 49, 3, 2, 2, 2, 288, 289, 9, 25, 2, 2, 289, + 51, 3, 2, 2, 2, 290, 291, 9, 26, 2, 2, 291, 53, 3, 2, 2, 2, 292, 293, 9, + 27, 2, 2, 293, 55, 3, 2, 2, 2, 294, 301, 5, 60, 30, 2, 295, 301, 5, 64, + 32, 2, 296, 301, 5, 58, 29, 2, 297, 301, 5, 62, 31, 2, 298, 301, 5, 68, + 34, 2, 299, 301, 5, 66, 33, 2, 300, 294, 3, 2, 2, 2, 300, 295, 3, 2, 2, + 2, 300, 296, 3, 2, 2, 2, 300, 297, 3, 2, 2, 2, 300, 298, 3, 2, 2, 2, 300, + 299, 3, 2, 2, 2, 301, 57, 3, 2, 2, 2, 302, 303, 7, 62, 2, 2, 303, 59, 3, + 2, 2, 2, 304, 305, 7, 63, 2, 2, 305, 61, 3, 2, 2, 2, 306, 307, 7, 64, 2, + 2, 307, 63, 3, 2, 2, 2, 308, 309, 5, 58, 29, 2, 309, 310, 5, 62, 31, 2, + 310, 65, 3, 2, 2, 2, 311, 312, 5, 62, 31, 2, 312, 313, 5, 60, 30, 2, 313, + 67, 3, 2, 2, 2, 314, 315, 5, 58, 29, 2, 315, 316, 5, 60, 30, 2, 316, 69, + 3, 2, 2, 2, 317, 318, 5, 42, 21, 2, 318, 319, 5, 38, 19, 2, 319, 320, 5, + 44, 22, 2, 320, 321, 5, 12, 6, 2, 321, 329, 3, 2, 2, 2, 322, 323, 5, 14, + 7, 2, 323, 324, 5, 4, 2, 2, 324, 325, 5, 26, 13, 2, 325, 326, 5, 40, 20, + 2, 326, 327, 5, 12, 6, 2, 327, 329, 3, 2, 2, 2, 328, 317, 3, 2, 2, 2, 328, + 322, 3, 2, 2, 2, 329, 71, 3, 2, 2, 2, 330, 331, 5, 4, 2, 2, 331, 332, 5, + 30, 15, 2, 332, 333, 5, 10, 5, 2, 333, 73, 3, 2, 2, 2, 334, 335, 5, 32, + 16, 2, 335, 336, 5, 38, 19, 2, 336, 75, 3, 2, 2, 2, 337, 338, 5, 30, 15, + 2, 338, 339, 5, 32, 16, 2, 339, 340, 5, 42, 21, 2, 340, 77, 3, 2, 2, 2, + 341, 342, 5, 26, 13, 2, 342, 343, 5, 20, 10, 2, 343, 344, 5, 24, 12, 2, + 344, 345, 5, 12, 6, 2, 345, 79, 3, 2, 2, 2, 346, 347, 5, 20, 10, 2, 347, + 348, 5, 26, 13, 2, 348, 349, 5, 20, 10, 2, 349, 350, 5, 24, 12, 2, 350, + 351, 5, 12, 6, 2, 351, 81, 3, 2, 2, 2, 352, 353, 5, 6, 3, 2, 353, 354, + 5, 12, 6, 2, 354, 355, 5, 42, 21, 2, 355, 356, 5, 48, 24, 2, 356, 357, + 5, 12, 6, 2, 357, 358, 5, 12, 6, 2, 358, 359, 5, 30, 15, 2, 359, 83, 3, + 2, 2, 2, 360, 361, 5, 20, 10, 2, 361, 362, 5, 40, 20, 2, 362, 85, 3, 2, + 2, 2, 363, 364, 5, 30, 15, 2, 364, 365, 5, 44, 22, 2, 365, 366, 5, 26, + 13, 2, 366, 367, 5, 26, 13, 2, 367, 87, 3, 2, 2, 2, 368, 369, 5, 48, 24, + 2, 369, 370, 5, 20, 10, 2, 370, 371, 5, 26, 13, 2, 371, 372, 5, 10, 5, + 2, 372, 373, 5, 8, 4, 2, 373, 374, 5, 4, 2, 2, 374, 375, 5, 38, 19, 2, + 375, 376, 5, 10, 5, 2, 376, 89, 3, 2, 2, 2, 377, 378, 5, 40, 20, 2, 378, + 379, 5, 20, 10, 2, 379, 380, 5, 30, 15, 2, 380, 381, 5, 16, 8, 2, 381, + 382, 5, 26, 13, 2, 382, 383, 5, 12, 6, 2, 383, 384, 5, 8, 4, 2, 384, 385, + 5, 18, 9, 2, 385, 386, 5, 4, 2, 2, 386, 387, 5, 38, 19, 2, 387, 91, 3, + 2, 2, 2, 388, 389, 5, 12, 6, 2, 389, 390, 5, 40, 20, 2, 390, 391, 5, 8, + 4, 2, 391, 392, 5, 4, 2, 2, 392, 393, 5, 34, 17, 2, 393, 394, 5, 12, 6, + 2, 394, 395, 5, 8, 4, 2, 395, 396, 5, 18, 9, 2, 396, 397, 5, 4, 2, 2, 397, + 398, 5, 38, 19, 2, 398, 93, 3, 2, 2, 2, 399, 400, 5, 30, 15, 2, 400, 401, + 5, 32, 16, 2, 401, 402, 5, 8, 4, 2, 402, 403, 5, 4, 2, 2, 403, 404, 5, + 40, 20, 2, 404, 405, 5, 12, 6, 2, 405, 95, 3, 2, 2, 2, 406, 407, 5, 12, + 6, 2, 407, 408, 5, 36, 18, 2, 408, 409, 5, 44, 22, 2, 409, 410, 5, 4, 2, + 2, 410, 411, 5, 26, 13, 2, 411, 412, 5, 40, 20, 2, 412, 475, 3, 2, 2, 2, + 413, 414, 5, 10, 5, 2, 414, 415, 5, 20, 10, 2, 415, 416, 5, 40, 20, 2, + 416, 417, 5, 22, 11, 2, 417, 418, 5, 32, 16, 2, 418, 419, 5, 20, 10, 2, + 419, 420, 5, 30, 15, 2, 420, 421, 5, 42, 21, 2, 421, 475, 3, 2, 2, 2, 422, + 423, 5, 42, 21, 2, 423, 424, 5, 32, 16, 2, 424, 425, 5, 44, 22, 2, 425, + 426, 5, 8, 4, 2, 426, 427, 5, 18, 9, 2, 427, 428, 5, 12, 6, 2, 428, 429, + 5, 40, 20, 2, 429, 475, 3, 2, 2, 2, 430, 431, 5, 48, 24, 2, 431, 432, 5, + 20, 10, 2, 432, 433, 5, 42, 21, 2, 433, 434, 5, 18, 9, 2, 434, 435, 5, + 20, 10, 2, 435, 436, 5, 30, 15, 2, 436, 475, 3, 2, 2, 2, 437, 438, 5, 32, + 16, 2, 438, 439, 5, 46, 23, 2, 439, 440, 5, 12, 6, 2, 440, 441, 5, 38, + 19, 2, 441, 442, 5, 26, 13, 2, 442, 443, 5, 4, 2, 2, 443, 444, 5, 34, 17, + 2, 444, 445, 5, 40, 20, 2, 445, 475, 3, 2, 2, 2, 446, 447, 5, 8, 4, 2, + 447, 448, 5, 38, 19, 2, 448, 449, 5, 32, 16, 2, 449, 450, 5, 40, 20, 2, + 450, 451, 5, 40, 20, 2, 451, 452, 5, 12, 6, 2, 452, 453, 5, 40, 20, 2, + 453, 475, 3, 2, 2, 2, 454, 455, 5, 20, 10, 2, 455, 456, 5, 30, 15, 2, 456, + 457, 5, 42, 21, 2, 457, 458, 5, 12, 6, 2, 458, 459, 5, 38, 19, 2, 459, + 460, 5, 40, 20, 2, 460, 461, 5, 12, 6, 2, 461, 462, 5, 8, 4, 2, 462, 463, + 5, 42, 21, 2, 463, 464, 5, 40, 20, 2, 464, 475, 3, 2, 2, 2, 465, 466, 5, + 8, 4, 2, 466, 467, 5, 32, 16, 2, 467, 468, 5, 30, 15, 2, 468, 469, 5, 42, + 21, 2, 469, 470, 5, 4, 2, 2, 470, 471, 5, 20, 10, 2, 471, 472, 5, 30, 15, + 2, 472, 473, 5, 40, 20, 2, 473, 475, 3, 2, 2, 2, 474, 406, 3, 2, 2, 2, + 474, 413, 3, 2, 2, 2, 474, 422, 3, 2, 2, 2, 474, 430, 3, 2, 2, 2, 474, + 437, 3, 2, 2, 2, 474, 446, 3, 2, 2, 2, 474, 454, 3, 2, 2, 2, 474, 465, + 3, 2, 2, 2, 475, 97, 3, 2, 2, 2, 476, 477, 5, 10, 5, 2, 477, 478, 5, 48, + 24, 2, 478, 479, 5, 20, 10, 2, 479, 480, 5, 42, 21, 2, 480, 481, 5, 18, + 9, 2, 481, 482, 5, 20, 10, 2, 482, 483, 5, 30, 15, 2, 483, 99, 3, 2, 2, + 2, 484, 485, 5, 4, 2, 2, 485, 486, 5, 14, 7, 2, 486, 487, 5, 42, 21, 2, + 487, 488, 5, 12, 6, 2, 488, 489, 5, 38, 19, 2, 489, 599, 3, 2, 2, 2, 490, + 491, 5, 6, 3, 2, 491, 492, 5, 12, 6, 2, 492, 493, 5, 14, 7, 2, 493, 494, + 5, 32, 16, 2, 494, 495, 5, 38, 19, 2, 495, 496, 5, 12, 6, 2, 496, 599, + 3, 2, 2, 2, 497, 498, 5, 6, 3, 2, 498, 499, 5, 12, 6, 2, 499, 500, 5, 16, + 8, 2, 500, 501, 5, 20, 10, 2, 501, 502, 5, 30, 15, 2, 502, 503, 5, 40, + 20, 2, 503, 599, 3, 2, 2, 2, 504, 505, 5, 6, 3, 2, 505, 506, 5, 12, 6, + 2, 506, 507, 5, 16, 8, 2, 507, 508, 5, 44, 22, 2, 508, 509, 5, 30, 15, + 2, 509, 510, 5, 6, 3, 2, 510, 511, 5, 52, 26, 2, 511, 599, 3, 2, 2, 2, + 512, 513, 5, 42, 21, 2, 513, 514, 5, 8, 4, 2, 514, 515, 5, 32, 16, 2, 515, + 516, 5, 30, 15, 2, 516, 517, 5, 42, 21, 2, 517, 518, 5, 4, 2, 2, 518, 519, + 5, 20, 10, 2, 519, 520, 5, 30, 15, 2, 520, 521, 5, 40, 20, 2, 521, 599, + 3, 2, 2, 2, 522, 523, 5, 10, 5, 2, 523, 524, 5, 44, 22, 2, 524, 525, 5, + 38, 19, 2, 525, 526, 5, 20, 10, 2, 526, 527, 5, 30, 15, 2, 527, 528, 5, + 16, 8, 2, 528, 599, 3, 2, 2, 2, 529, 530, 5, 12, 6, 2, 530, 531, 5, 30, + 15, 2, 531, 532, 5, 10, 5, 2, 532, 533, 5, 12, 6, 2, 533, 534, 5, 10, 5, + 2, 534, 535, 5, 6, 3, 2, 535, 536, 5, 52, 26, 2, 536, 599, 3, 2, 2, 2, + 537, 538, 5, 12, 6, 2, 538, 539, 5, 30, 15, 2, 539, 540, 5, 10, 5, 2, 540, + 541, 5, 40, 20, 2, 541, 599, 3, 2, 2, 2, 542, 543, 5, 42, 21, 2, 543, 544, + 5, 12, 6, 2, 544, 545, 5, 36, 18, 2, 545, 546, 5, 44, 22, 2, 546, 547, + 5, 4, 2, 2, 547, 548, 5, 26, 13, 2, 548, 549, 5, 40, 20, 2, 549, 599, 3, + 2, 2, 2, 550, 551, 5, 28, 14, 2, 551, 552, 5, 12, 6, 2, 552, 553, 5, 12, + 6, 2, 553, 554, 5, 42, 21, 2, 554, 555, 5, 40, 20, 2, 555, 599, 3, 2, 2, + 2, 556, 557, 5, 28, 14, 2, 557, 558, 5, 12, 6, 2, 558, 559, 5, 42, 21, + 2, 559, 560, 5, 6, 3, 2, 560, 561, 5, 52, 26, 2, 561, 599, 3, 2, 2, 2, + 562, 563, 5, 42, 21, 2, 563, 564, 5, 32, 16, 2, 564, 565, 5, 46, 23, 2, + 565, 566, 5, 12, 6, 2, 566, 567, 5, 38, 19, 2, 567, 568, 5, 26, 13, 2, + 568, 569, 5, 4, 2, 2, 569, 570, 5, 34, 17, 2, 570, 571, 5, 40, 20, 2, 571, + 599, 3, 2, 2, 2, 572, 573, 5, 32, 16, 2, 573, 574, 5, 46, 23, 2, 574, 575, + 5, 12, 6, 2, 575, 576, 5, 38, 19, 2, 576, 577, 5, 26, 13, 2, 577, 578, + 5, 4, 2, 2, 578, 579, 5, 34, 17, 2, 579, 580, 5, 34, 17, 2, 580, 581, 5, + 12, 6, 2, 581, 582, 5, 10, 5, 2, 582, 583, 5, 6, 3, 2, 583, 584, 5, 52, + 26, 2, 584, 599, 3, 2, 2, 2, 585, 586, 5, 4, 2, 2, 586, 587, 5, 30, 15, + 2, 587, 588, 5, 52, 26, 2, 588, 589, 5, 20, 10, 2, 589, 590, 5, 30, 15, + 2, 590, 591, 5, 42, 21, 2, 591, 592, 5, 12, 6, 2, 592, 593, 5, 38, 19, + 2, 593, 594, 5, 4, 2, 2, 594, 595, 5, 8, 4, 2, 595, 596, 5, 42, 21, 2, + 596, 597, 5, 40, 20, 2, 597, 599, 3, 2, 2, 2, 598, 484, 3, 2, 2, 2, 598, + 490, 3, 2, 2, 2, 598, 497, 3, 2, 2, 2, 598, 504, 3, 2, 2, 2, 598, 512, + 3, 2, 2, 2, 598, 522, 3, 2, 2, 2, 598, 529, 3, 2, 2, 2, 598, 537, 3, 2, + 2, 2, 598, 542, 3, 2, 2, 2, 598, 550, 3, 2, 2, 2, 598, 556, 3, 2, 2, 2, + 598, 562, 3, 2, 2, 2, 598, 572, 3, 2, 2, 2, 598, 585, 3, 2, 2, 2, 599, + 101, 3, 2, 2, 2, 600, 601, 5, 4, 2, 2, 601, 602, 5, 12, 6, 2, 602, 603, + 5, 36, 18, 2, 603, 604, 5, 44, 22, 2, 604, 605, 5, 4, 2, 2, 605, 606, 5, + 26, 13, 2, 606, 607, 5, 40, 20, 2, 607, 641, 3, 2, 2, 2, 608, 609, 5, 4, + 2, 2, 609, 610, 5, 8, 4, 2, 610, 611, 5, 32, 16, 2, 611, 612, 5, 30, 15, + 2, 612, 613, 5, 42, 21, 2, 613, 614, 5, 4, 2, 2, 614, 615, 5, 20, 10, 2, + 615, 616, 5, 30, 15, 2, 616, 617, 5, 40, 20, 2, 617, 641, 3, 2, 2, 2, 618, + 619, 5, 8, 4, 2, 619, 620, 5, 32, 16, 2, 620, 621, 5, 30, 15, 2, 621, 622, + 5, 42, 21, 2, 622, 623, 5, 4, 2, 2, 623, 624, 5, 20, 10, 2, 624, 625, 5, + 30, 15, 2, 625, 626, 5, 12, 6, 2, 626, 627, 5, 10, 5, 2, 627, 628, 5, 6, + 3, 2, 628, 629, 5, 52, 26, 2, 629, 641, 3, 2, 2, 2, 630, 631, 5, 4, 2, + 2, 631, 632, 5, 32, 16, 2, 632, 633, 5, 46, 23, 2, 633, 634, 5, 12, 6, + 2, 634, 635, 5, 38, 19, 2, 635, 636, 5, 26, 13, 2, 636, 637, 5, 4, 2, 2, + 637, 638, 5, 34, 17, 2, 638, 639, 5, 40, 20, 2, 639, 641, 3, 2, 2, 2, 640, + 600, 3, 2, 2, 2, 640, 608, 3, 2, 2, 2, 640, 618, 3, 2, 2, 2, 640, 630, + 3, 2, 2, 2, 641, 103, 3, 2, 2, 2, 642, 643, 5, 12, 6, 2, 643, 644, 5, 50, + 25, 2, 644, 645, 5, 20, 10, 2, 645, 646, 5, 40, 20, 2, 646, 647, 5, 42, + 21, 2, 647, 648, 5, 40, 20, 2, 648, 105, 3, 2, 2, 2, 649, 650, 5, 12, 6, + 2, 650, 651, 5, 50, 25, 2, 651, 652, 5, 20, 10, 2, 652, 653, 5, 40, 20, + 2, 653, 654, 5, 42, 21, 2, 654, 107, 3, 2, 2, 2, 655, 656, 5, 10, 5, 2, + 656, 657, 5, 32, 16, 2, 657, 658, 5, 12, 6, 2, 658, 659, 5, 40, 20, 2, + 659, 109, 3, 2, 2, 2, 660, 661, 5, 20, 10, 2, 661, 662, 5, 30, 15, 2, 662, + 111, 3, 2, 2, 2, 663, 664, 5, 34, 17, 2, 664, 665, 5, 32, 16, 2, 665, 666, + 5, 20, 10, 2, 666, 667, 5, 30, 15, 2, 667, 668, 5, 42, 21, 2, 668, 113, + 3, 2, 2, 2, 669, 670, 5, 26, 13, 2, 670, 671, 5, 20, 10, 2, 671, 672, 5, + 30, 15, 2, 672, 673, 5, 12, 6, 2, 673, 674, 5, 40, 20, 2, 674, 675, 5, + 42, 21, 2, 675, 676, 5, 38, 19, 2, 676, 677, 5, 20, 10, 2, 677, 678, 5, + 30, 15, 2, 678, 679, 5, 16, 8, 2, 679, 115, 3, 2, 2, 2, 680, 681, 5, 34, + 17, 2, 681, 682, 5, 32, 16, 2, 682, 683, 5, 26, 13, 2, 683, 684, 5, 52, + 26, 2, 684, 685, 5, 16, 8, 2, 685, 686, 5, 32, 16, 2, 686, 687, 5, 30, + 15, 2, 687, 117, 3, 2, 2, 2, 688, 689, 5, 28, 14, 2, 689, 690, 5, 44, 22, + 2, 690, 691, 5, 26, 13, 2, 691, 692, 5, 42, 21, 2, 692, 693, 5, 20, 10, + 2, 693, 694, 5, 34, 17, 2, 694, 695, 5, 32, 16, 2, 695, 696, 5, 20, 10, + 2, 696, 697, 5, 30, 15, 2, 697, 698, 5, 42, 21, 2, 698, 119, 3, 2, 2, 2, + 699, 700, 5, 28, 14, 2, 700, 701, 5, 44, 22, 2, 701, 702, 5, 26, 13, 2, + 702, 703, 5, 42, 21, 2, 703, 704, 5, 20, 10, 2, 704, 705, 5, 26, 13, 2, + 705, 706, 5, 20, 10, 2, 706, 707, 5, 30, 15, 2, 707, 708, 5, 12, 6, 2, + 708, 709, 5, 40, 20, 2, 709, 710, 5, 42, 21, 2, 710, 711, 5, 38, 19, 2, + 711, 712, 5, 20, 10, 2, 712, 713, 5, 30, 15, 2, 713, 714, 5, 16, 8, 2, + 714, 121, 3, 2, 2, 2, 715, 716, 5, 28, 14, 2, 716, 717, 5, 44, 22, 2, 717, + 718, 5, 26, 13, 2, 718, 719, 5, 42, 21, 2, 719, 720, 5, 20, 10, 2, 720, + 721, 5, 34, 17, 2, 721, 722, 5, 32, 16, 2, 722, 723, 5, 26, 13, 2, 723, + 724, 5, 52, 26, 2, 724, 725, 5, 16, 8, 2, 725, 726, 5, 32, 16, 2, 726, + 727, 5, 30, 15, 2, 727, 123, 3, 2, 2, 2, 728, 729, 5, 16, 8, 2, 729, 730, + 5, 12, 6, 2, 730, 731, 5, 32, 16, 2, 731, 732, 5, 28, 14, 2, 732, 733, + 5, 12, 6, 2, 733, 734, 5, 42, 21, 2, 734, 735, 5, 38, 19, 2, 735, 736, + 5, 52, 26, 2, 736, 737, 5, 8, 4, 2, 737, 738, 5, 32, 16, 2, 738, 739, 5, + 26, 13, 2, 739, 740, 5, 26, 13, 2, 740, 741, 5, 12, 6, 2, 741, 742, 5, + 8, 4, 2, 742, 743, 5, 42, 21, 2, 743, 744, 5, 20, 10, 2, 744, 745, 5, 32, + 16, 2, 745, 746, 5, 30, 15, 2, 746, 125, 3, 2, 2, 2, 747, 748, 5, 12, 6, + 2, 748, 749, 5, 30, 15, 2, 749, 750, 5, 46, 23, 2, 750, 751, 5, 12, 6, + 2, 751, 752, 5, 26, 13, 2, 752, 753, 5, 32, 16, 2, 753, 754, 5, 34, 17, + 2, 754, 755, 5, 12, 6, 2, 755, 127, 3, 2, 2, 2, 756, 757, 5, 154, 77, 2, + 757, 758, 3, 2, 2, 2, 758, 759, 8, 64, 2, 2, 759, 760, 8, 64, 3, 2, 760, + 129, 3, 2, 2, 2, 761, 764, 5, 188, 94, 2, 762, 764, 5, 190, 95, 2, 763, + 761, 3, 2, 2, 2, 763, 762, 3, 2, 2, 2, 764, 131, 3, 2, 2, 2, 765, 769, + 5, 134, 67, 2, 766, 768, 5, 136, 68, 2, 767, 766, 3, 2, 2, 2, 768, 771, + 3, 2, 2, 2, 769, 767, 3, 2, 2, 2, 769, 770, 3, 2, 2, 2, 770, 777, 3, 2, + 2, 2, 771, 769, 3, 2, 2, 2, 772, 773, 5, 148, 74, 2, 773, 774, 5, 132, + 66, 2, 774, 775, 5, 148, 74, 2, 775, 777, 3, 2, 2, 2, 776, 765, 3, 2, 2, + 2, 776, 772, 3, 2, 2, 2, 777, 133, 3, 2, 2, 2, 778, 779, 5, 138, 69, 2, + 779, 135, 3, 2, 2, 2, 780, 785, 5, 138, 69, 2, 781, 785, 5, 140, 70, 2, + 782, 785, 5, 146, 73, 2, 783, 785, 5, 144, 72, 2, 784, 780, 3, 2, 2, 2, + 784, 781, 3, 2, 2, 2, 784, 782, 3, 2, 2, 2, 784, 783, 3, 2, 2, 2, 785, + 137, 3, 2, 2, 2, 786, 787, 9, 28, 2, 2, 787, 139, 3, 2, 2, 2, 788, 789, + 9, 29, 2, 2, 789, 141, 3, 2, 2, 2, 790, 791, 7, 37, 2, 2, 791, 143, 3, + 2, 2, 2, 792, 793, 7, 38, 2, 2, 793, 145, 3, 2, 2, 2, 794, 795, 7, 97, + 2, 2, 795, 147, 3, 2, 2, 2, 796, 797, 7, 36, 2, 2, 797, 149, 3, 2, 2, 2, + 798, 799, 7, 39, 2, 2, 799, 151, 3, 2, 2, 2, 800, 801, 7, 40, 2, 2, 801, + 153, 3, 2, 2, 2, 802, 803, 7, 41, 2, 2, 803, 155, 3, 2, 2, 2, 804, 805, + 7, 42, 2, 2, 805, 157, 3, 2, 2, 2, 806, 807, 7, 43, 2, 2, 807, 159, 3, + 2, 2, 2, 808, 809, 7, 93, 2, 2, 809, 161, 3, 2, 2, 2, 810, 811, 7, 95, + 2, 2, 811, 163, 3, 2, 2, 2, 812, 813, 7, 44, 2, 2, 813, 165, 3, 2, 2, 2, + 814, 815, 7, 45, 2, 2, 815, 167, 3, 2, 2, 2, 816, 817, 7, 46, 2, 2, 817, + 169, 3, 2, 2, 2, 818, 819, 7, 47, 2, 2, 819, 171, 3, 2, 2, 2, 820, 821, + 7, 48, 2, 2, 821, 173, 3, 2, 2, 2, 822, 823, 7, 49, 2, 2, 823, 175, 3, + 2, 2, 2, 824, 825, 7, 60, 2, 2, 825, 177, 3, 2, 2, 2, 826, 827, 7, 61, + 2, 2, 827, 179, 3, 2, 2, 2, 828, 829, 7, 65, 2, 2, 829, 181, 3, 2, 2, 2, + 830, 831, 7, 126, 2, 2, 831, 183, 3, 2, 2, 2, 832, 833, 4, 50, 51, 2, 833, + 185, 3, 2, 2, 2, 834, 842, 5, 140, 70, 2, 835, 842, 5, 4, 2, 2, 836, 842, + 5, 6, 3, 2, 837, 842, 5, 8, 4, 2, 838, 842, 5, 10, 5, 2, 839, 842, 5, 12, + 6, 2, 840, 842, 5, 14, 7, 2, 841, 834, 3, 2, 2, 2, 841, 835, 3, 2, 2, 2, + 841, 836, 3, 2, 2, 2, 841, 837, 3, 2, 2, 2, 841, 838, 3, 2, 2, 2, 841, + 839, 3, 2, 2, 2, 841, 840, 3, 2, 2, 2, 842, 187, 3, 2, 2, 2, 843, 846, + 5, 192, 96, 2, 844, 846, 5, 194, 97, 2, 845, 843, 3, 2, 2, 2, 845, 844, + 3, 2, 2, 2, 846, 189, 3, 2, 2, 2, 847, 849, 5, 204, 102, 2, 848, 847, 3, + 2, 2, 2, 848, 849, 3, 2, 2, 2, 849, 850, 3, 2, 2, 2, 850, 853, 5, 192, + 96, 2, 851, 853, 5, 194, 97, 2, 852, 848, 3, 2, 2, 2, 852, 851, 3, 2, 2, + 2, 853, 191, 3, 2, 2, 2, 854, 859, 5, 202, 101, 2, 855, 857, 5, 172, 86, + 2, 856, 858, 5, 202, 101, 2, 857, 856, 3, 2, 2, 2, 857, 858, 3, 2, 2, 2, + 858, 860, 3, 2, 2, 2, 859, 855, 3, 2, 2, 2, 859, 860, 3, 2, 2, 2, 860, + 865, 3, 2, 2, 2, 861, 862, 5, 172, 86, 2, 862, 863, 5, 202, 101, 2, 863, + 865, 3, 2, 2, 2, 864, 854, 3, 2, 2, 2, 864, 861, 3, 2, 2, 2, 865, 193, + 3, 2, 2, 2, 866, 867, 5, 196, 98, 2, 867, 868, 7, 71, 2, 2, 868, 869, 5, + 198, 99, 2, 869, 195, 3, 2, 2, 2, 870, 871, 5, 192, 96, 2, 871, 197, 3, + 2, 2, 2, 872, 873, 5, 200, 100, 2, 873, 199, 3, 2, 2, 2, 874, 876, 5, 204, + 102, 2, 875, 874, 3, 2, 2, 2, 875, 876, 3, 2, 2, 2, 876, 877, 3, 2, 2, + 2, 877, 878, 5, 202, 101, 2, 878, 201, 3, 2, 2, 2, 879, 881, 5, 140, 70, + 2, 880, 879, 3, 2, 2, 2, 881, 882, 3, 2, 2, 2, 882, 880, 3, 2, 2, 2, 882, + 883, 3, 2, 2, 2, 883, 203, 3, 2, 2, 2, 884, 887, 5, 166, 83, 2, 885, 887, + 5, 170, 85, 2, 886, 884, 3, 2, 2, 2, 886, 885, 3, 2, 2, 2, 887, 205, 3, + 2, 2, 2, 888, 891, 5, 208, 104, 2, 889, 891, 5, 210, 105, 2, 890, 888, + 3, 2, 2, 2, 890, 889, 3, 2, 2, 2, 891, 207, 3, 2, 2, 2, 892, 902, 5, 214, + 107, 2, 893, 894, 5, 214, 107, 2, 894, 895, 7, 86, 2, 2, 895, 896, 5, 222, + 111, 2, 896, 902, 3, 2, 2, 2, 897, 898, 5, 232, 116, 2, 898, 899, 5, 156, + 78, 2, 899, 900, 5, 158, 79, 2, 900, 902, 3, 2, 2, 2, 901, 892, 3, 2, 2, + 2, 901, 893, 3, 2, 2, 2, 901, 897, 3, 2, 2, 2, 902, 209, 3, 2, 2, 2, 903, + 905, 5, 212, 106, 2, 904, 903, 3, 2, 2, 2, 904, 905, 3, 2, 2, 2, 905, 906, + 3, 2, 2, 2, 906, 908, 5, 174, 87, 2, 907, 909, 5, 212, 106, 2, 908, 907, + 3, 2, 2, 2, 908, 909, 3, 2, 2, 2, 909, 211, 3, 2, 2, 2, 910, 911, 7, 48, + 2, 2, 911, 914, 7, 48, 2, 2, 912, 914, 5, 208, 104, 2, 913, 910, 3, 2, + 2, 2, 913, 912, 3, 2, 2, 2, 914, 213, 3, 2, 2, 2, 915, 916, 5, 216, 108, + 2, 916, 917, 7, 47, 2, 2, 917, 918, 5, 218, 109, 2, 918, 919, 7, 47, 2, + 2, 919, 920, 5, 220, 110, 2, 920, 215, 3, 2, 2, 2, 921, 922, 5, 140, 70, + 2, 922, 923, 5, 140, 70, 2, 923, 924, 5, 140, 70, 2, 924, 925, 5, 140, + 70, 2, 925, 217, 3, 2, 2, 2, 926, 927, 5, 140, 70, 2, 927, 928, 5, 140, + 70, 2, 928, 219, 3, 2, 2, 2, 929, 930, 5, 140, 70, 2, 930, 931, 5, 140, + 70, 2, 931, 221, 3, 2, 2, 2, 932, 933, 5, 226, 113, 2, 933, 934, 7, 60, + 2, 2, 934, 935, 5, 228, 114, 2, 935, 936, 7, 60, 2, 2, 936, 938, 5, 230, + 115, 2, 937, 939, 5, 224, 112, 2, 938, 937, 3, 2, 2, 2, 938, 939, 3, 2, + 2, 2, 939, 223, 3, 2, 2, 2, 940, 947, 7, 92, 2, 2, 941, 942, 5, 204, 102, + 2, 942, 943, 5, 226, 113, 2, 943, 944, 7, 60, 2, 2, 944, 945, 5, 228, 114, + 2, 945, 947, 3, 2, 2, 2, 946, 940, 3, 2, 2, 2, 946, 941, 3, 2, 2, 2, 947, + 225, 3, 2, 2, 2, 948, 949, 5, 140, 70, 2, 949, 950, 5, 140, 70, 2, 950, + 227, 3, 2, 2, 2, 951, 952, 5, 140, 70, 2, 952, 953, 5, 140, 70, 2, 953, + 229, 3, 2, 2, 2, 954, 955, 5, 140, 70, 2, 955, 962, 5, 140, 70, 2, 956, + 958, 5, 172, 86, 2, 957, 959, 5, 140, 70, 2, 958, 957, 3, 2, 2, 2, 959, + 960, 3, 2, 2, 2, 960, 958, 3, 2, 2, 2, 960, 961, 3, 2, 2, 2, 961, 963, + 3, 2, 2, 2, 962, 956, 3, 2, 2, 2, 962, 963, 3, 2, 2, 2, 963, 231, 3, 2, + 2, 2, 964, 965, 5, 30, 15, 2, 965, 966, 5, 32, 16, 2, 966, 967, 5, 48, + 24, 2, 967, 233, 3, 2, 2, 2, 968, 970, 9, 30, 2, 2, 969, 968, 3, 2, 2, + 2, 970, 971, 3, 2, 2, 2, 971, 969, 3, 2, 2, 2, 971, 972, 3, 2, 2, 2, 972, + 973, 3, 2, 2, 2, 973, 974, 8, 117, 4, 2, 974, 235, 3, 2, 2, 2, 975, 976, + 7, 41, 2, 2, 976, 977, 3, 2, 2, 2, 977, 978, 8, 118, 5, 2, 978, 237, 3, + 2, 2, 2, 979, 980, 7, 41, 2, 2, 980, 981, 7, 41, 2, 2, 981, 982, 3, 2, + 2, 2, 982, 983, 8, 119, 2, 2, 983, 239, 3, 2, 2, 2, 984, 985, 10, 31, 2, + 2, 985, 986, 3, 2, 2, 2, 986, 987, 8, 120, 2, 2, 987, 241, 3, 2, 2, 2, + 33, 2, 3, 300, 328, 474, 598, 640, 763, 769, 776, 784, 841, 845, 848, 852, + 857, 859, 864, 875, 882, 886, 890, 901, 904, 908, 913, 938, 946, 960, 962, + 971, 6, 5, 2, 2, 4, 3, 2, 8, 2, 2, 4, 2, 2, } var lexerDeserializer = antlr.NewATNDeserializer(nil) @@ -470,28 +475,30 @@ var lexerModeNames = []string{ var lexerLiteralNames = []string{ "", "", "'<'", "'='", "'>'", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "'#'", "'$'", "'_'", "'\"'", "'%'", "'&'", - "", "'('", "')'", "'['", "']'", "'*'", "'+'", "','", "'-'", "'.'", "'/'", - "':'", "';'", "'?'", "'|'", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "''''", + "", "", "", "", "", "", "", "", "", "'#'", "'$'", "'_'", "'\"'", "'%'", + "'&'", "", "'('", "')'", "'['", "']'", "'*'", "'+'", "','", "'-'", "'.'", + "'/'", "':'", "';'", "'?'", "'|'", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "''''", } var lexerSymbolicNames = []string{ "", "ComparisonOperator", "LT", "EQ", "GT", "NEQ", "GTEQ", "LTEQ", "BooleanLiteral", "AND", "OR", "NOT", "LIKE", "ILIKE", "BETWEEN", "IS", "NULL", "WILDCARD", - "SINGLECHAR", "ESCAPECHAR", "NOCASE", "SpatialOperator", "TemporalOperator", - "ArrayOperator", "EXISTS", "EXIST", "DOES", "IN", "POINT", "LINESTRING", - "POLYGON", "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION", - "ENVELOPE", "NumericLiteral", "Identifier", "IdentifierStart", "IdentifierPart", - "ALPHA", "DIGIT", "OCTOTHORP", "DOLLAR", "UNDERSCORE", "DOUBLEQUOTE", "PERCENT", - "AMPERSAND", "QUOTE", "LEFTPAREN", "RIGHTPAREN", "LEFTSQUAREBRACKET", "RIGHTSQUAREBRACKET", - "ASTERISK", "PLUS", "COMMA", "MINUS", "PERIOD", "SOLIDUS", "COLON", "SEMICOLON", - "QUESTIONMARK", "VERTICALBAR", "BIT", "HEXIT", "UnsignedNumericLiteral", - "SignedNumericLiteral", "ExactNumericLiteral", "ApproximateNumericLiteral", - "Mantissa", "Exponent", "SignedInteger", "UnsignedInteger", "Sign", "TemporalLiteral", - "Instant", "Interval", "InstantInInterval", "FullDate", "DateYear", "DateMonth", - "DateDay", "UtcTime", "TimeZoneOffset", "TimeHour", "TimeMinute", "TimeSecond", - "NOW", "WS", "CharacterStringLiteral", "QuotedQuote", + "SINGLECHAR", "ESCAPECHAR", "NOCASE", "SpatialOperator", "DistanceOperator", + "TemporalOperator", "ArrayOperator", "EXISTS", "EXIST", "DOES", "IN", "POINT", + "LINESTRING", "POLYGON", "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", + "GEOMETRYCOLLECTION", "ENVELOPE", "NumericLiteral", "Identifier", "IdentifierStart", + "IdentifierPart", "ALPHA", "DIGIT", "OCTOTHORP", "DOLLAR", "UNDERSCORE", + "DOUBLEQUOTE", "PERCENT", "AMPERSAND", "QUOTE", "LEFTPAREN", "RIGHTPAREN", + "LEFTSQUAREBRACKET", "RIGHTSQUAREBRACKET", "ASTERISK", "PLUS", "COMMA", + "MINUS", "PERIOD", "SOLIDUS", "COLON", "SEMICOLON", "QUESTIONMARK", "VERTICALBAR", + "BIT", "HEXIT", "UnsignedNumericLiteral", "SignedNumericLiteral", "ExactNumericLiteral", + "ApproximateNumericLiteral", "Mantissa", "Exponent", "SignedInteger", "UnsignedInteger", + "Sign", "TemporalLiteral", "Instant", "Interval", "InstantInInterval", + "FullDate", "DateYear", "DateMonth", "DateDay", "UtcTime", "TimeZoneOffset", + "TimeHour", "TimeMinute", "TimeSecond", "NOW", "WS", "CharacterStringLiteral", + "QuotedQuote", } var lexerRuleNames = []string{ @@ -499,19 +506,20 @@ var lexerRuleNames = []string{ "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "ComparisonOperator", "LT", "EQ", "GT", "NEQ", "GTEQ", "LTEQ", "BooleanLiteral", "AND", "OR", "NOT", "LIKE", "ILIKE", "BETWEEN", "IS", "NULL", "WILDCARD", "SINGLECHAR", - "ESCAPECHAR", "NOCASE", "SpatialOperator", "TemporalOperator", "ArrayOperator", - "EXISTS", "EXIST", "DOES", "IN", "POINT", "LINESTRING", "POLYGON", "MULTIPOINT", - "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION", "ENVELOPE", "CharacterStringLiteralStart", - "NumericLiteral", "Identifier", "IdentifierStart", "IdentifierPart", "ALPHA", - "DIGIT", "OCTOTHORP", "DOLLAR", "UNDERSCORE", "DOUBLEQUOTE", "PERCENT", - "AMPERSAND", "QUOTE", "LEFTPAREN", "RIGHTPAREN", "LEFTSQUAREBRACKET", "RIGHTSQUAREBRACKET", - "ASTERISK", "PLUS", "COMMA", "MINUS", "PERIOD", "SOLIDUS", "COLON", "SEMICOLON", - "QUESTIONMARK", "VERTICALBAR", "BIT", "HEXIT", "UnsignedNumericLiteral", - "SignedNumericLiteral", "ExactNumericLiteral", "ApproximateNumericLiteral", - "Mantissa", "Exponent", "SignedInteger", "UnsignedInteger", "Sign", "TemporalLiteral", - "Instant", "Interval", "InstantInInterval", "FullDate", "DateYear", "DateMonth", - "DateDay", "UtcTime", "TimeZoneOffset", "TimeHour", "TimeMinute", "TimeSecond", - "NOW", "WS", "CharacterStringLiteral", "QuotedQuote", "Character", + "ESCAPECHAR", "NOCASE", "SpatialOperator", "DistanceOperator", "TemporalOperator", + "ArrayOperator", "EXISTS", "EXIST", "DOES", "IN", "POINT", "LINESTRING", + "POLYGON", "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION", + "ENVELOPE", "CharacterStringLiteralStart", "NumericLiteral", "Identifier", + "IdentifierStart", "IdentifierPart", "ALPHA", "DIGIT", "OCTOTHORP", "DOLLAR", + "UNDERSCORE", "DOUBLEQUOTE", "PERCENT", "AMPERSAND", "QUOTE", "LEFTPAREN", + "RIGHTPAREN", "LEFTSQUAREBRACKET", "RIGHTSQUAREBRACKET", "ASTERISK", "PLUS", + "COMMA", "MINUS", "PERIOD", "SOLIDUS", "COLON", "SEMICOLON", "QUESTIONMARK", + "VERTICALBAR", "BIT", "HEXIT", "UnsignedNumericLiteral", "SignedNumericLiteral", + "ExactNumericLiteral", "ApproximateNumericLiteral", "Mantissa", "Exponent", + "SignedInteger", "UnsignedInteger", "Sign", "TemporalLiteral", "Instant", + "Interval", "InstantInInterval", "FullDate", "DateYear", "DateMonth", "DateDay", + "UtcTime", "TimeZoneOffset", "TimeHour", "TimeMinute", "TimeSecond", "NOW", + "WS", "CharacterStringLiteral", "QuotedQuote", "Character", } type CqlLexer struct { @@ -570,75 +578,76 @@ const ( CqlLexerESCAPECHAR = 19 CqlLexerNOCASE = 20 CqlLexerSpatialOperator = 21 - CqlLexerTemporalOperator = 22 - CqlLexerArrayOperator = 23 - CqlLexerEXISTS = 24 - CqlLexerEXIST = 25 - CqlLexerDOES = 26 - CqlLexerIN = 27 - CqlLexerPOINT = 28 - CqlLexerLINESTRING = 29 - CqlLexerPOLYGON = 30 - CqlLexerMULTIPOINT = 31 - CqlLexerMULTILINESTRING = 32 - CqlLexerMULTIPOLYGON = 33 - CqlLexerGEOMETRYCOLLECTION = 34 - CqlLexerENVELOPE = 35 - CqlLexerNumericLiteral = 36 - CqlLexerIdentifier = 37 - CqlLexerIdentifierStart = 38 - CqlLexerIdentifierPart = 39 - CqlLexerALPHA = 40 - CqlLexerDIGIT = 41 - CqlLexerOCTOTHORP = 42 - CqlLexerDOLLAR = 43 - CqlLexerUNDERSCORE = 44 - CqlLexerDOUBLEQUOTE = 45 - CqlLexerPERCENT = 46 - CqlLexerAMPERSAND = 47 - CqlLexerQUOTE = 48 - CqlLexerLEFTPAREN = 49 - CqlLexerRIGHTPAREN = 50 - CqlLexerLEFTSQUAREBRACKET = 51 - CqlLexerRIGHTSQUAREBRACKET = 52 - CqlLexerASTERISK = 53 - CqlLexerPLUS = 54 - CqlLexerCOMMA = 55 - CqlLexerMINUS = 56 - CqlLexerPERIOD = 57 - CqlLexerSOLIDUS = 58 - CqlLexerCOLON = 59 - CqlLexerSEMICOLON = 60 - CqlLexerQUESTIONMARK = 61 - CqlLexerVERTICALBAR = 62 - CqlLexerBIT = 63 - CqlLexerHEXIT = 64 - CqlLexerUnsignedNumericLiteral = 65 - CqlLexerSignedNumericLiteral = 66 - CqlLexerExactNumericLiteral = 67 - CqlLexerApproximateNumericLiteral = 68 - CqlLexerMantissa = 69 - CqlLexerExponent = 70 - CqlLexerSignedInteger = 71 - CqlLexerUnsignedInteger = 72 - CqlLexerSign = 73 - CqlLexerTemporalLiteral = 74 - CqlLexerInstant = 75 - CqlLexerInterval = 76 - CqlLexerInstantInInterval = 77 - CqlLexerFullDate = 78 - CqlLexerDateYear = 79 - CqlLexerDateMonth = 80 - CqlLexerDateDay = 81 - CqlLexerUtcTime = 82 - CqlLexerTimeZoneOffset = 83 - CqlLexerTimeHour = 84 - CqlLexerTimeMinute = 85 - CqlLexerTimeSecond = 86 - CqlLexerNOW = 87 - CqlLexerWS = 88 - CqlLexerCharacterStringLiteral = 89 - CqlLexerQuotedQuote = 90 + CqlLexerDistanceOperator = 22 + CqlLexerTemporalOperator = 23 + CqlLexerArrayOperator = 24 + CqlLexerEXISTS = 25 + CqlLexerEXIST = 26 + CqlLexerDOES = 27 + CqlLexerIN = 28 + CqlLexerPOINT = 29 + CqlLexerLINESTRING = 30 + CqlLexerPOLYGON = 31 + CqlLexerMULTIPOINT = 32 + CqlLexerMULTILINESTRING = 33 + CqlLexerMULTIPOLYGON = 34 + CqlLexerGEOMETRYCOLLECTION = 35 + CqlLexerENVELOPE = 36 + CqlLexerNumericLiteral = 37 + CqlLexerIdentifier = 38 + CqlLexerIdentifierStart = 39 + CqlLexerIdentifierPart = 40 + CqlLexerALPHA = 41 + CqlLexerDIGIT = 42 + CqlLexerOCTOTHORP = 43 + CqlLexerDOLLAR = 44 + CqlLexerUNDERSCORE = 45 + CqlLexerDOUBLEQUOTE = 46 + CqlLexerPERCENT = 47 + CqlLexerAMPERSAND = 48 + CqlLexerQUOTE = 49 + CqlLexerLEFTPAREN = 50 + CqlLexerRIGHTPAREN = 51 + CqlLexerLEFTSQUAREBRACKET = 52 + CqlLexerRIGHTSQUAREBRACKET = 53 + CqlLexerASTERISK = 54 + CqlLexerPLUS = 55 + CqlLexerCOMMA = 56 + CqlLexerMINUS = 57 + CqlLexerPERIOD = 58 + CqlLexerSOLIDUS = 59 + CqlLexerCOLON = 60 + CqlLexerSEMICOLON = 61 + CqlLexerQUESTIONMARK = 62 + CqlLexerVERTICALBAR = 63 + CqlLexerBIT = 64 + CqlLexerHEXIT = 65 + CqlLexerUnsignedNumericLiteral = 66 + CqlLexerSignedNumericLiteral = 67 + CqlLexerExactNumericLiteral = 68 + CqlLexerApproximateNumericLiteral = 69 + CqlLexerMantissa = 70 + CqlLexerExponent = 71 + CqlLexerSignedInteger = 72 + CqlLexerUnsignedInteger = 73 + CqlLexerSign = 74 + CqlLexerTemporalLiteral = 75 + CqlLexerInstant = 76 + CqlLexerInterval = 77 + CqlLexerInstantInInterval = 78 + CqlLexerFullDate = 79 + CqlLexerDateYear = 80 + CqlLexerDateMonth = 81 + CqlLexerDateDay = 82 + CqlLexerUtcTime = 83 + CqlLexerTimeZoneOffset = 84 + CqlLexerTimeHour = 85 + CqlLexerTimeMinute = 86 + CqlLexerTimeSecond = 87 + CqlLexerNOW = 88 + CqlLexerWS = 89 + CqlLexerCharacterStringLiteral = 90 + CqlLexerQuotedQuote = 91 ) // CqlLexerSTR is the CqlLexer mode. diff --git a/internal/cql/cql_listener.go b/internal/cql/cql_listener.go index 84762182..3bdb4a97 100644 --- a/internal/cql/cql_listener.go +++ b/internal/cql/cql_listener.go @@ -55,6 +55,9 @@ type CQLListener interface { // EnterSpatialPredicate is called when entering the spatialPredicate production. EnterSpatialPredicate(c *SpatialPredicateContext) + // EnterDistancePredicate is called when entering the distancePredicate production. + EnterDistancePredicate(c *DistancePredicateContext) + // EnterGeomExpression is called when entering the geomExpression production. EnterGeomExpression(c *GeomExpressionContext) @@ -67,8 +70,8 @@ type CQLListener interface { // EnterLinestring is called when entering the linestring production. EnterLinestring(c *LinestringContext) - // EnterLinestringDef is called when entering the linestringDef production. - EnterLinestringDef(c *LinestringDefContext) + // EnterCoordList is called when entering the coordList production. + EnterCoordList(c *CoordListContext) // EnterPolygon is called when entering the polygon production. EnterPolygon(c *PolygonContext) @@ -94,33 +97,6 @@ type CQLListener interface { // EnterCoordinate is called when entering the coordinate production. EnterCoordinate(c *CoordinateContext) - // EnterXCoord is called when entering the xCoord production. - EnterXCoord(c *XCoordContext) - - // EnterYCoord is called when entering the yCoord production. - EnterYCoord(c *YCoordContext) - - // EnterZCoord is called when entering the zCoord production. - EnterZCoord(c *ZCoordContext) - - // EnterWestBoundLon is called when entering the westBoundLon production. - EnterWestBoundLon(c *WestBoundLonContext) - - // EnterEastBoundLon is called when entering the eastBoundLon production. - EnterEastBoundLon(c *EastBoundLonContext) - - // EnterNorthBoundLat is called when entering the northBoundLat production. - EnterNorthBoundLat(c *NorthBoundLatContext) - - // EnterSouthBoundLat is called when entering the southBoundLat production. - EnterSouthBoundLat(c *SouthBoundLatContext) - - // EnterMinElev is called when entering the minElev production. - EnterMinElev(c *MinElevContext) - - // EnterMaxElev is called when entering the maxElev production. - EnterMaxElev(c *MaxElevContext) - // EnterTemporalPredicate is called when entering the temporalPredicate production. EnterTemporalPredicate(c *TemporalPredicateContext) @@ -181,6 +157,9 @@ type CQLListener interface { // ExitSpatialPredicate is called when exiting the spatialPredicate production. ExitSpatialPredicate(c *SpatialPredicateContext) + // ExitDistancePredicate is called when exiting the distancePredicate production. + ExitDistancePredicate(c *DistancePredicateContext) + // ExitGeomExpression is called when exiting the geomExpression production. ExitGeomExpression(c *GeomExpressionContext) @@ -193,8 +172,8 @@ type CQLListener interface { // ExitLinestring is called when exiting the linestring production. ExitLinestring(c *LinestringContext) - // ExitLinestringDef is called when exiting the linestringDef production. - ExitLinestringDef(c *LinestringDefContext) + // ExitCoordList is called when exiting the coordList production. + ExitCoordList(c *CoordListContext) // ExitPolygon is called when exiting the polygon production. ExitPolygon(c *PolygonContext) @@ -220,33 +199,6 @@ type CQLListener interface { // ExitCoordinate is called when exiting the coordinate production. ExitCoordinate(c *CoordinateContext) - // ExitXCoord is called when exiting the xCoord production. - ExitXCoord(c *XCoordContext) - - // ExitYCoord is called when exiting the yCoord production. - ExitYCoord(c *YCoordContext) - - // ExitZCoord is called when exiting the zCoord production. - ExitZCoord(c *ZCoordContext) - - // ExitWestBoundLon is called when exiting the westBoundLon production. - ExitWestBoundLon(c *WestBoundLonContext) - - // ExitEastBoundLon is called when exiting the eastBoundLon production. - ExitEastBoundLon(c *EastBoundLonContext) - - // ExitNorthBoundLat is called when exiting the northBoundLat production. - ExitNorthBoundLat(c *NorthBoundLatContext) - - // ExitSouthBoundLat is called when exiting the southBoundLat production. - ExitSouthBoundLat(c *SouthBoundLatContext) - - // ExitMinElev is called when exiting the minElev production. - ExitMinElev(c *MinElevContext) - - // ExitMaxElev is called when exiting the maxElev production. - ExitMaxElev(c *MaxElevContext) - // ExitTemporalPredicate is called when exiting the temporalPredicate production. ExitTemporalPredicate(c *TemporalPredicateContext) diff --git a/internal/cql/cql_parser.go b/internal/cql/cql_parser.go index 427beb8a..96a6758b 100644 --- a/internal/cql/cql_parser.go +++ b/internal/cql/cql_parser.go @@ -15,154 +15,141 @@ var _ = reflect.Copy var _ = strconv.Itoa var parserATN = []uint16{ - 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 92, 353, + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 93, 319, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, - 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4, 39, 9, - 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 3, 2, 3, 2, - 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 96, 10, 3, 12, 3, 14, 3, - 99, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 107, 10, 4, 12, 4, - 14, 4, 110, 11, 4, 3, 5, 5, 5, 113, 10, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, - 3, 6, 3, 6, 5, 6, 122, 10, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 129, - 10, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 5, 9, 137, 10, 9, 3, 9, 3, 9, - 3, 9, 3, 10, 3, 10, 5, 10, 144, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, - 10, 3, 11, 3, 11, 3, 11, 5, 11, 154, 10, 11, 3, 11, 3, 11, 3, 12, 3, 12, - 3, 12, 3, 12, 5, 12, 162, 10, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, - 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, - 3, 18, 5, 18, 181, 10, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, 19, 3, - 19, 3, 19, 5, 19, 191, 10, 19, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 21, - 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 7, 22, 205, 10, 22, 12, 22, 14, - 22, 208, 11, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, - 3, 24, 7, 24, 219, 10, 24, 12, 24, 14, 24, 222, 11, 24, 3, 24, 3, 24, 3, - 25, 3, 25, 3, 25, 3, 25, 3, 25, 7, 25, 231, 10, 25, 12, 25, 14, 25, 234, - 11, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 7, 26, 243, 10, - 26, 12, 26, 14, 26, 246, 11, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, - 27, 3, 27, 7, 27, 255, 10, 27, 12, 27, 14, 27, 258, 11, 27, 3, 27, 3, 27, - 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 267, 10, 28, 12, 28, 14, 28, - 270, 11, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, - 29, 3, 29, 3, 29, 5, 29, 283, 10, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, - 5, 29, 290, 10, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 5, 30, 297, 10, - 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 3, 33, 3, 34, 3, 34, 3, 35, 3, 35, - 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 39, 3, 39, 3, 40, 3, 40, 3, - 40, 3, 40, 3, 41, 3, 41, 5, 41, 323, 10, 41, 3, 42, 3, 42, 3, 43, 3, 43, - 5, 43, 329, 10, 43, 3, 43, 3, 43, 3, 43, 3, 43, 3, 43, 7, 43, 336, 10, - 43, 12, 43, 14, 43, 339, 11, 43, 3, 43, 3, 43, 3, 43, 7, 43, 344, 10, 43, - 12, 43, 14, 43, 347, 11, 43, 5, 43, 349, 10, 43, 3, 43, 3, 43, 3, 43, 2, - 4, 4, 6, 44, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, - 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, - 70, 72, 74, 76, 78, 80, 82, 84, 2, 4, 3, 2, 14, 15, 4, 2, 3, 3, 24, 24, - 2, 346, 2, 86, 3, 2, 2, 2, 4, 89, 3, 2, 2, 2, 6, 100, 3, 2, 2, 2, 8, 112, - 3, 2, 2, 2, 10, 121, 3, 2, 2, 2, 12, 128, 3, 2, 2, 2, 14, 130, 3, 2, 2, - 2, 16, 134, 3, 2, 2, 2, 18, 141, 3, 2, 2, 2, 20, 150, 3, 2, 2, 2, 22, 161, - 3, 2, 2, 2, 24, 163, 3, 2, 2, 2, 26, 165, 3, 2, 2, 2, 28, 167, 3, 2, 2, - 2, 30, 169, 3, 2, 2, 2, 32, 171, 3, 2, 2, 2, 34, 180, 3, 2, 2, 2, 36, 190, - 3, 2, 2, 2, 38, 192, 3, 2, 2, 2, 40, 197, 3, 2, 2, 2, 42, 200, 3, 2, 2, - 2, 44, 211, 3, 2, 2, 2, 46, 214, 3, 2, 2, 2, 48, 225, 3, 2, 2, 2, 50, 237, - 3, 2, 2, 2, 52, 249, 3, 2, 2, 2, 54, 261, 3, 2, 2, 2, 56, 273, 3, 2, 2, - 2, 58, 293, 3, 2, 2, 2, 60, 298, 3, 2, 2, 2, 62, 300, 3, 2, 2, 2, 64, 302, - 3, 2, 2, 2, 66, 304, 3, 2, 2, 2, 68, 306, 3, 2, 2, 2, 70, 308, 3, 2, 2, - 2, 72, 310, 3, 2, 2, 2, 74, 312, 3, 2, 2, 2, 76, 314, 3, 2, 2, 2, 78, 316, - 3, 2, 2, 2, 80, 322, 3, 2, 2, 2, 82, 324, 3, 2, 2, 2, 84, 326, 3, 2, 2, - 2, 86, 87, 5, 4, 3, 2, 87, 88, 7, 2, 2, 3, 88, 3, 3, 2, 2, 2, 89, 90, 8, - 3, 1, 2, 90, 91, 5, 6, 4, 2, 91, 97, 3, 2, 2, 2, 92, 93, 12, 3, 2, 2, 93, - 94, 7, 12, 2, 2, 94, 96, 5, 6, 4, 2, 95, 92, 3, 2, 2, 2, 96, 99, 3, 2, - 2, 2, 97, 95, 3, 2, 2, 2, 97, 98, 3, 2, 2, 2, 98, 5, 3, 2, 2, 2, 99, 97, - 3, 2, 2, 2, 100, 101, 8, 4, 1, 2, 101, 102, 5, 8, 5, 2, 102, 108, 3, 2, - 2, 2, 103, 104, 12, 3, 2, 2, 104, 105, 7, 11, 2, 2, 105, 107, 5, 8, 5, - 2, 106, 103, 3, 2, 2, 2, 107, 110, 3, 2, 2, 2, 108, 106, 3, 2, 2, 2, 108, - 109, 3, 2, 2, 2, 109, 7, 3, 2, 2, 2, 110, 108, 3, 2, 2, 2, 111, 113, 7, - 13, 2, 2, 112, 111, 3, 2, 2, 2, 112, 113, 3, 2, 2, 2, 113, 114, 3, 2, 2, - 2, 114, 115, 5, 10, 6, 2, 115, 9, 3, 2, 2, 2, 116, 122, 5, 12, 7, 2, 117, - 118, 7, 51, 2, 2, 118, 119, 5, 4, 3, 2, 119, 120, 7, 52, 2, 2, 120, 122, - 3, 2, 2, 2, 121, 116, 3, 2, 2, 2, 121, 117, 3, 2, 2, 2, 122, 11, 3, 2, - 2, 2, 123, 129, 5, 14, 8, 2, 124, 129, 5, 16, 9, 2, 125, 129, 5, 18, 10, - 2, 126, 129, 5, 20, 11, 2, 127, 129, 5, 84, 43, 2, 128, 123, 3, 2, 2, 2, - 128, 124, 3, 2, 2, 2, 128, 125, 3, 2, 2, 2, 128, 126, 3, 2, 2, 2, 128, - 127, 3, 2, 2, 2, 129, 13, 3, 2, 2, 2, 130, 131, 5, 22, 12, 2, 131, 132, - 7, 3, 2, 2, 132, 133, 5, 22, 12, 2, 133, 15, 3, 2, 2, 2, 134, 136, 5, 24, - 13, 2, 135, 137, 7, 13, 2, 2, 136, 135, 3, 2, 2, 2, 136, 137, 3, 2, 2, - 2, 137, 138, 3, 2, 2, 2, 138, 139, 9, 2, 2, 2, 139, 140, 5, 26, 14, 2, - 140, 17, 3, 2, 2, 2, 141, 143, 5, 24, 13, 2, 142, 144, 7, 13, 2, 2, 143, - 142, 3, 2, 2, 2, 143, 144, 3, 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 146, - 7, 16, 2, 2, 146, 147, 5, 22, 12, 2, 147, 148, 7, 11, 2, 2, 148, 149, 5, - 22, 12, 2, 149, 19, 3, 2, 2, 2, 150, 151, 5, 24, 13, 2, 151, 153, 7, 17, - 2, 2, 152, 154, 7, 13, 2, 2, 153, 152, 3, 2, 2, 2, 153, 154, 3, 2, 2, 2, - 154, 155, 3, 2, 2, 2, 155, 156, 7, 18, 2, 2, 156, 21, 3, 2, 2, 2, 157, - 162, 5, 24, 13, 2, 158, 162, 5, 26, 14, 2, 159, 162, 5, 28, 15, 2, 160, - 162, 5, 30, 16, 2, 161, 157, 3, 2, 2, 2, 161, 158, 3, 2, 2, 2, 161, 159, - 3, 2, 2, 2, 161, 160, 3, 2, 2, 2, 162, 23, 3, 2, 2, 2, 163, 164, 7, 39, - 2, 2, 164, 25, 3, 2, 2, 2, 165, 166, 7, 91, 2, 2, 166, 27, 3, 2, 2, 2, - 167, 168, 7, 38, 2, 2, 168, 29, 3, 2, 2, 2, 169, 170, 7, 10, 2, 2, 170, - 31, 3, 2, 2, 2, 171, 172, 7, 23, 2, 2, 172, 173, 7, 51, 2, 2, 173, 174, - 5, 34, 18, 2, 174, 175, 7, 57, 2, 2, 175, 176, 5, 34, 18, 2, 176, 177, - 7, 52, 2, 2, 177, 33, 3, 2, 2, 2, 178, 181, 5, 24, 13, 2, 179, 181, 5, - 36, 19, 2, 180, 178, 3, 2, 2, 2, 180, 179, 3, 2, 2, 2, 181, 35, 3, 2, 2, - 2, 182, 191, 5, 38, 20, 2, 183, 191, 5, 40, 21, 2, 184, 191, 5, 44, 23, - 2, 185, 191, 5, 48, 25, 2, 186, 191, 5, 50, 26, 2, 187, 191, 5, 52, 27, - 2, 188, 191, 5, 54, 28, 2, 189, 191, 5, 56, 29, 2, 190, 182, 3, 2, 2, 2, - 190, 183, 3, 2, 2, 2, 190, 184, 3, 2, 2, 2, 190, 185, 3, 2, 2, 2, 190, - 186, 3, 2, 2, 2, 190, 187, 3, 2, 2, 2, 190, 188, 3, 2, 2, 2, 190, 189, - 3, 2, 2, 2, 191, 37, 3, 2, 2, 2, 192, 193, 7, 30, 2, 2, 193, 194, 7, 51, - 2, 2, 194, 195, 5, 58, 30, 2, 195, 196, 7, 52, 2, 2, 196, 39, 3, 2, 2, - 2, 197, 198, 7, 31, 2, 2, 198, 199, 5, 42, 22, 2, 199, 41, 3, 2, 2, 2, - 200, 201, 7, 51, 2, 2, 201, 206, 5, 58, 30, 2, 202, 203, 7, 57, 2, 2, 203, - 205, 5, 58, 30, 2, 204, 202, 3, 2, 2, 2, 205, 208, 3, 2, 2, 2, 206, 204, - 3, 2, 2, 2, 206, 207, 3, 2, 2, 2, 207, 209, 3, 2, 2, 2, 208, 206, 3, 2, - 2, 2, 209, 210, 7, 52, 2, 2, 210, 43, 3, 2, 2, 2, 211, 212, 7, 32, 2, 2, - 212, 213, 5, 46, 24, 2, 213, 45, 3, 2, 2, 2, 214, 215, 7, 51, 2, 2, 215, - 220, 5, 42, 22, 2, 216, 217, 7, 57, 2, 2, 217, 219, 5, 42, 22, 2, 218, - 216, 3, 2, 2, 2, 219, 222, 3, 2, 2, 2, 220, 218, 3, 2, 2, 2, 220, 221, - 3, 2, 2, 2, 221, 223, 3, 2, 2, 2, 222, 220, 3, 2, 2, 2, 223, 224, 7, 52, - 2, 2, 224, 47, 3, 2, 2, 2, 225, 226, 7, 33, 2, 2, 226, 227, 7, 51, 2, 2, - 227, 232, 5, 58, 30, 2, 228, 229, 7, 57, 2, 2, 229, 231, 5, 58, 30, 2, - 230, 228, 3, 2, 2, 2, 231, 234, 3, 2, 2, 2, 232, 230, 3, 2, 2, 2, 232, - 233, 3, 2, 2, 2, 233, 235, 3, 2, 2, 2, 234, 232, 3, 2, 2, 2, 235, 236, - 7, 52, 2, 2, 236, 49, 3, 2, 2, 2, 237, 238, 7, 34, 2, 2, 238, 239, 7, 51, - 2, 2, 239, 244, 5, 42, 22, 2, 240, 241, 7, 57, 2, 2, 241, 243, 5, 42, 22, - 2, 242, 240, 3, 2, 2, 2, 243, 246, 3, 2, 2, 2, 244, 242, 3, 2, 2, 2, 244, - 245, 3, 2, 2, 2, 245, 247, 3, 2, 2, 2, 246, 244, 3, 2, 2, 2, 247, 248, - 7, 52, 2, 2, 248, 51, 3, 2, 2, 2, 249, 250, 7, 35, 2, 2, 250, 251, 7, 51, - 2, 2, 251, 256, 5, 46, 24, 2, 252, 253, 7, 57, 2, 2, 253, 255, 5, 46, 24, - 2, 254, 252, 3, 2, 2, 2, 255, 258, 3, 2, 2, 2, 256, 254, 3, 2, 2, 2, 256, - 257, 3, 2, 2, 2, 257, 259, 3, 2, 2, 2, 258, 256, 3, 2, 2, 2, 259, 260, - 7, 52, 2, 2, 260, 53, 3, 2, 2, 2, 261, 262, 7, 36, 2, 2, 262, 263, 7, 51, - 2, 2, 263, 268, 5, 36, 19, 2, 264, 265, 7, 57, 2, 2, 265, 267, 5, 36, 19, - 2, 266, 264, 3, 2, 2, 2, 267, 270, 3, 2, 2, 2, 268, 266, 3, 2, 2, 2, 268, - 269, 3, 2, 2, 2, 269, 271, 3, 2, 2, 2, 270, 268, 3, 2, 2, 2, 271, 272, - 7, 52, 2, 2, 272, 55, 3, 2, 2, 2, 273, 274, 7, 37, 2, 2, 274, 275, 7, 51, - 2, 2, 275, 276, 5, 66, 34, 2, 276, 277, 7, 57, 2, 2, 277, 278, 5, 72, 37, - 2, 278, 282, 7, 57, 2, 2, 279, 280, 5, 74, 38, 2, 280, 281, 7, 57, 2, 2, - 281, 283, 3, 2, 2, 2, 282, 279, 3, 2, 2, 2, 282, 283, 3, 2, 2, 2, 283, - 284, 3, 2, 2, 2, 284, 285, 5, 68, 35, 2, 285, 286, 7, 57, 2, 2, 286, 289, - 5, 70, 36, 2, 287, 288, 7, 57, 2, 2, 288, 290, 5, 76, 39, 2, 289, 287, - 3, 2, 2, 2, 289, 290, 3, 2, 2, 2, 290, 291, 3, 2, 2, 2, 291, 292, 7, 52, - 2, 2, 292, 57, 3, 2, 2, 2, 293, 294, 5, 60, 31, 2, 294, 296, 5, 62, 32, - 2, 295, 297, 5, 64, 33, 2, 296, 295, 3, 2, 2, 2, 296, 297, 3, 2, 2, 2, - 297, 59, 3, 2, 2, 2, 298, 299, 7, 38, 2, 2, 299, 61, 3, 2, 2, 2, 300, 301, - 7, 38, 2, 2, 301, 63, 3, 2, 2, 2, 302, 303, 7, 38, 2, 2, 303, 65, 3, 2, - 2, 2, 304, 305, 7, 38, 2, 2, 305, 67, 3, 2, 2, 2, 306, 307, 7, 38, 2, 2, - 307, 69, 3, 2, 2, 2, 308, 309, 7, 38, 2, 2, 309, 71, 3, 2, 2, 2, 310, 311, - 7, 38, 2, 2, 311, 73, 3, 2, 2, 2, 312, 313, 7, 38, 2, 2, 313, 75, 3, 2, - 2, 2, 314, 315, 7, 38, 2, 2, 315, 77, 3, 2, 2, 2, 316, 317, 5, 80, 41, - 2, 317, 318, 9, 3, 2, 2, 318, 319, 5, 80, 41, 2, 319, 79, 3, 2, 2, 2, 320, - 323, 5, 24, 13, 2, 321, 323, 5, 82, 42, 2, 322, 320, 3, 2, 2, 2, 322, 321, - 3, 2, 2, 2, 323, 81, 3, 2, 2, 2, 324, 325, 7, 76, 2, 2, 325, 83, 3, 2, - 2, 2, 326, 328, 5, 24, 13, 2, 327, 329, 7, 13, 2, 2, 328, 327, 3, 2, 2, - 2, 328, 329, 3, 2, 2, 2, 329, 330, 3, 2, 2, 2, 330, 331, 7, 29, 2, 2, 331, - 348, 7, 51, 2, 2, 332, 337, 5, 26, 14, 2, 333, 334, 7, 57, 2, 2, 334, 336, - 5, 26, 14, 2, 335, 333, 3, 2, 2, 2, 336, 339, 3, 2, 2, 2, 337, 335, 3, - 2, 2, 2, 337, 338, 3, 2, 2, 2, 338, 349, 3, 2, 2, 2, 339, 337, 3, 2, 2, - 2, 340, 345, 5, 28, 15, 2, 341, 342, 7, 57, 2, 2, 342, 344, 5, 28, 15, - 2, 343, 341, 3, 2, 2, 2, 344, 347, 3, 2, 2, 2, 345, 343, 3, 2, 2, 2, 345, - 346, 3, 2, 2, 2, 346, 349, 3, 2, 2, 2, 347, 345, 3, 2, 2, 2, 348, 332, - 3, 2, 2, 2, 348, 340, 3, 2, 2, 2, 349, 350, 3, 2, 2, 2, 350, 351, 7, 52, - 2, 2, 351, 85, 3, 2, 2, 2, 27, 97, 108, 112, 121, 128, 136, 143, 153, 161, - 180, 190, 206, 220, 232, 244, 256, 268, 282, 289, 296, 322, 328, 337, 345, - 348, + 9, 34, 4, 35, 9, 35, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 7, 3, 80, 10, 3, 12, 3, 14, 3, 83, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, + 4, 3, 4, 7, 4, 91, 10, 4, 12, 4, 14, 4, 94, 11, 4, 3, 5, 5, 5, 97, 10, + 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 106, 10, 6, 3, 7, 3, + 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 115, 10, 7, 3, 8, 3, 8, 3, 8, 3, + 8, 3, 9, 3, 9, 5, 9, 123, 10, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 5, 10, + 130, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 5, + 11, 140, 10, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 148, + 10, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, + 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, + 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 176, 10, 19, 3, 20, + 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 186, 10, 20, 3, + 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, + 3, 23, 7, 23, 200, 10, 23, 12, 23, 14, 23, 203, 11, 23, 3, 23, 3, 23, 3, + 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 7, 25, 214, 10, 25, 12, 25, + 14, 25, 217, 11, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 7, + 26, 226, 10, 26, 12, 26, 14, 26, 229, 11, 26, 3, 26, 3, 26, 3, 27, 3, 27, + 3, 27, 3, 27, 3, 27, 7, 27, 238, 10, 27, 12, 27, 14, 27, 241, 11, 27, 3, + 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 250, 10, 28, 12, 28, + 14, 28, 253, 11, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 7, + 29, 262, 10, 29, 12, 29, 14, 29, 265, 11, 29, 3, 29, 3, 29, 3, 30, 3, 30, + 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, + 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 289, 10, 33, + 3, 34, 3, 34, 3, 35, 3, 35, 5, 35, 295, 10, 35, 3, 35, 3, 35, 3, 35, 3, + 35, 3, 35, 7, 35, 302, 10, 35, 12, 35, 14, 35, 305, 11, 35, 3, 35, 3, 35, + 3, 35, 7, 35, 310, 10, 35, 12, 35, 14, 35, 313, 11, 35, 5, 35, 315, 10, + 35, 3, 35, 3, 35, 3, 35, 2, 4, 4, 6, 36, 2, 4, 6, 8, 10, 12, 14, 16, 18, + 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, + 56, 58, 60, 62, 64, 66, 68, 2, 4, 3, 2, 14, 15, 4, 2, 3, 3, 25, 25, 2, + 319, 2, 70, 3, 2, 2, 2, 4, 73, 3, 2, 2, 2, 6, 84, 3, 2, 2, 2, 8, 96, 3, + 2, 2, 2, 10, 105, 3, 2, 2, 2, 12, 114, 3, 2, 2, 2, 14, 116, 3, 2, 2, 2, + 16, 120, 3, 2, 2, 2, 18, 127, 3, 2, 2, 2, 20, 136, 3, 2, 2, 2, 22, 147, + 3, 2, 2, 2, 24, 149, 3, 2, 2, 2, 26, 151, 3, 2, 2, 2, 28, 153, 3, 2, 2, + 2, 30, 155, 3, 2, 2, 2, 32, 157, 3, 2, 2, 2, 34, 164, 3, 2, 2, 2, 36, 175, + 3, 2, 2, 2, 38, 185, 3, 2, 2, 2, 40, 187, 3, 2, 2, 2, 42, 192, 3, 2, 2, + 2, 44, 195, 3, 2, 2, 2, 46, 206, 3, 2, 2, 2, 48, 209, 3, 2, 2, 2, 50, 220, + 3, 2, 2, 2, 52, 232, 3, 2, 2, 2, 54, 244, 3, 2, 2, 2, 56, 256, 3, 2, 2, + 2, 58, 268, 3, 2, 2, 2, 60, 279, 3, 2, 2, 2, 62, 282, 3, 2, 2, 2, 64, 288, + 3, 2, 2, 2, 66, 290, 3, 2, 2, 2, 68, 292, 3, 2, 2, 2, 70, 71, 5, 4, 3, + 2, 71, 72, 7, 2, 2, 3, 72, 3, 3, 2, 2, 2, 73, 74, 8, 3, 1, 2, 74, 75, 5, + 6, 4, 2, 75, 81, 3, 2, 2, 2, 76, 77, 12, 3, 2, 2, 77, 78, 7, 12, 2, 2, + 78, 80, 5, 6, 4, 2, 79, 76, 3, 2, 2, 2, 80, 83, 3, 2, 2, 2, 81, 79, 3, + 2, 2, 2, 81, 82, 3, 2, 2, 2, 82, 5, 3, 2, 2, 2, 83, 81, 3, 2, 2, 2, 84, + 85, 8, 4, 1, 2, 85, 86, 5, 8, 5, 2, 86, 92, 3, 2, 2, 2, 87, 88, 12, 3, + 2, 2, 88, 89, 7, 11, 2, 2, 89, 91, 5, 8, 5, 2, 90, 87, 3, 2, 2, 2, 91, + 94, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 92, 93, 3, 2, 2, 2, 93, 7, 3, 2, 2, + 2, 94, 92, 3, 2, 2, 2, 95, 97, 7, 13, 2, 2, 96, 95, 3, 2, 2, 2, 96, 97, + 3, 2, 2, 2, 97, 98, 3, 2, 2, 2, 98, 99, 5, 10, 6, 2, 99, 9, 3, 2, 2, 2, + 100, 106, 5, 12, 7, 2, 101, 102, 7, 52, 2, 2, 102, 103, 5, 4, 3, 2, 103, + 104, 7, 53, 2, 2, 104, 106, 3, 2, 2, 2, 105, 100, 3, 2, 2, 2, 105, 101, + 3, 2, 2, 2, 106, 11, 3, 2, 2, 2, 107, 115, 5, 14, 8, 2, 108, 115, 5, 16, + 9, 2, 109, 115, 5, 18, 10, 2, 110, 115, 5, 20, 11, 2, 111, 115, 5, 68, + 35, 2, 112, 115, 5, 32, 17, 2, 113, 115, 5, 34, 18, 2, 114, 107, 3, 2, + 2, 2, 114, 108, 3, 2, 2, 2, 114, 109, 3, 2, 2, 2, 114, 110, 3, 2, 2, 2, + 114, 111, 3, 2, 2, 2, 114, 112, 3, 2, 2, 2, 114, 113, 3, 2, 2, 2, 115, + 13, 3, 2, 2, 2, 116, 117, 5, 22, 12, 2, 117, 118, 7, 3, 2, 2, 118, 119, + 5, 22, 12, 2, 119, 15, 3, 2, 2, 2, 120, 122, 5, 24, 13, 2, 121, 123, 7, + 13, 2, 2, 122, 121, 3, 2, 2, 2, 122, 123, 3, 2, 2, 2, 123, 124, 3, 2, 2, + 2, 124, 125, 9, 2, 2, 2, 125, 126, 5, 26, 14, 2, 126, 17, 3, 2, 2, 2, 127, + 129, 5, 24, 13, 2, 128, 130, 7, 13, 2, 2, 129, 128, 3, 2, 2, 2, 129, 130, + 3, 2, 2, 2, 130, 131, 3, 2, 2, 2, 131, 132, 7, 16, 2, 2, 132, 133, 5, 22, + 12, 2, 133, 134, 7, 11, 2, 2, 134, 135, 5, 22, 12, 2, 135, 19, 3, 2, 2, + 2, 136, 137, 5, 24, 13, 2, 137, 139, 7, 17, 2, 2, 138, 140, 7, 13, 2, 2, + 139, 138, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 141, 3, 2, 2, 2, 141, + 142, 7, 18, 2, 2, 142, 21, 3, 2, 2, 2, 143, 148, 5, 24, 13, 2, 144, 148, + 5, 26, 14, 2, 145, 148, 5, 28, 15, 2, 146, 148, 5, 30, 16, 2, 147, 143, + 3, 2, 2, 2, 147, 144, 3, 2, 2, 2, 147, 145, 3, 2, 2, 2, 147, 146, 3, 2, + 2, 2, 148, 23, 3, 2, 2, 2, 149, 150, 7, 40, 2, 2, 150, 25, 3, 2, 2, 2, + 151, 152, 7, 92, 2, 2, 152, 27, 3, 2, 2, 2, 153, 154, 7, 39, 2, 2, 154, + 29, 3, 2, 2, 2, 155, 156, 7, 10, 2, 2, 156, 31, 3, 2, 2, 2, 157, 158, 7, + 23, 2, 2, 158, 159, 7, 52, 2, 2, 159, 160, 5, 36, 19, 2, 160, 161, 7, 58, + 2, 2, 161, 162, 5, 36, 19, 2, 162, 163, 7, 53, 2, 2, 163, 33, 3, 2, 2, + 2, 164, 165, 7, 24, 2, 2, 165, 166, 7, 52, 2, 2, 166, 167, 5, 36, 19, 2, + 167, 168, 7, 58, 2, 2, 168, 169, 5, 36, 19, 2, 169, 170, 7, 58, 2, 2, 170, + 171, 7, 39, 2, 2, 171, 172, 7, 53, 2, 2, 172, 35, 3, 2, 2, 2, 173, 176, + 5, 24, 13, 2, 174, 176, 5, 38, 20, 2, 175, 173, 3, 2, 2, 2, 175, 174, 3, + 2, 2, 2, 176, 37, 3, 2, 2, 2, 177, 186, 5, 40, 21, 2, 178, 186, 5, 42, + 22, 2, 179, 186, 5, 46, 24, 2, 180, 186, 5, 50, 26, 2, 181, 186, 5, 52, + 27, 2, 182, 186, 5, 54, 28, 2, 183, 186, 5, 56, 29, 2, 184, 186, 5, 58, + 30, 2, 185, 177, 3, 2, 2, 2, 185, 178, 3, 2, 2, 2, 185, 179, 3, 2, 2, 2, + 185, 180, 3, 2, 2, 2, 185, 181, 3, 2, 2, 2, 185, 182, 3, 2, 2, 2, 185, + 183, 3, 2, 2, 2, 185, 184, 3, 2, 2, 2, 186, 39, 3, 2, 2, 2, 187, 188, 7, + 31, 2, 2, 188, 189, 7, 52, 2, 2, 189, 190, 5, 60, 31, 2, 190, 191, 7, 53, + 2, 2, 191, 41, 3, 2, 2, 2, 192, 193, 7, 32, 2, 2, 193, 194, 5, 44, 23, + 2, 194, 43, 3, 2, 2, 2, 195, 196, 7, 52, 2, 2, 196, 201, 5, 60, 31, 2, + 197, 198, 7, 58, 2, 2, 198, 200, 5, 60, 31, 2, 199, 197, 3, 2, 2, 2, 200, + 203, 3, 2, 2, 2, 201, 199, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 204, + 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 204, 205, 7, 53, 2, 2, 205, 45, 3, 2, + 2, 2, 206, 207, 7, 33, 2, 2, 207, 208, 5, 48, 25, 2, 208, 47, 3, 2, 2, + 2, 209, 210, 7, 52, 2, 2, 210, 215, 5, 44, 23, 2, 211, 212, 7, 58, 2, 2, + 212, 214, 5, 44, 23, 2, 213, 211, 3, 2, 2, 2, 214, 217, 3, 2, 2, 2, 215, + 213, 3, 2, 2, 2, 215, 216, 3, 2, 2, 2, 216, 218, 3, 2, 2, 2, 217, 215, + 3, 2, 2, 2, 218, 219, 7, 53, 2, 2, 219, 49, 3, 2, 2, 2, 220, 221, 7, 34, + 2, 2, 221, 222, 7, 52, 2, 2, 222, 227, 5, 60, 31, 2, 223, 224, 7, 58, 2, + 2, 224, 226, 5, 60, 31, 2, 225, 223, 3, 2, 2, 2, 226, 229, 3, 2, 2, 2, + 227, 225, 3, 2, 2, 2, 227, 228, 3, 2, 2, 2, 228, 230, 3, 2, 2, 2, 229, + 227, 3, 2, 2, 2, 230, 231, 7, 53, 2, 2, 231, 51, 3, 2, 2, 2, 232, 233, + 7, 35, 2, 2, 233, 234, 7, 52, 2, 2, 234, 239, 5, 44, 23, 2, 235, 236, 7, + 58, 2, 2, 236, 238, 5, 44, 23, 2, 237, 235, 3, 2, 2, 2, 238, 241, 3, 2, + 2, 2, 239, 237, 3, 2, 2, 2, 239, 240, 3, 2, 2, 2, 240, 242, 3, 2, 2, 2, + 241, 239, 3, 2, 2, 2, 242, 243, 7, 53, 2, 2, 243, 53, 3, 2, 2, 2, 244, + 245, 7, 36, 2, 2, 245, 246, 7, 52, 2, 2, 246, 251, 5, 48, 25, 2, 247, 248, + 7, 58, 2, 2, 248, 250, 5, 48, 25, 2, 249, 247, 3, 2, 2, 2, 250, 253, 3, + 2, 2, 2, 251, 249, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 254, 3, 2, 2, + 2, 253, 251, 3, 2, 2, 2, 254, 255, 7, 53, 2, 2, 255, 55, 3, 2, 2, 2, 256, + 257, 7, 37, 2, 2, 257, 258, 7, 52, 2, 2, 258, 263, 5, 38, 20, 2, 259, 260, + 7, 58, 2, 2, 260, 262, 5, 38, 20, 2, 261, 259, 3, 2, 2, 2, 262, 265, 3, + 2, 2, 2, 263, 261, 3, 2, 2, 2, 263, 264, 3, 2, 2, 2, 264, 266, 3, 2, 2, + 2, 265, 263, 3, 2, 2, 2, 266, 267, 7, 53, 2, 2, 267, 57, 3, 2, 2, 2, 268, + 269, 7, 38, 2, 2, 269, 270, 7, 52, 2, 2, 270, 271, 7, 39, 2, 2, 271, 272, + 7, 58, 2, 2, 272, 273, 7, 39, 2, 2, 273, 274, 7, 58, 2, 2, 274, 275, 7, + 39, 2, 2, 275, 276, 7, 58, 2, 2, 276, 277, 7, 39, 2, 2, 277, 278, 7, 53, + 2, 2, 278, 59, 3, 2, 2, 2, 279, 280, 7, 39, 2, 2, 280, 281, 7, 39, 2, 2, + 281, 61, 3, 2, 2, 2, 282, 283, 5, 64, 33, 2, 283, 284, 9, 3, 2, 2, 284, + 285, 5, 64, 33, 2, 285, 63, 3, 2, 2, 2, 286, 289, 5, 24, 13, 2, 287, 289, + 5, 66, 34, 2, 288, 286, 3, 2, 2, 2, 288, 287, 3, 2, 2, 2, 289, 65, 3, 2, + 2, 2, 290, 291, 7, 77, 2, 2, 291, 67, 3, 2, 2, 2, 292, 294, 5, 24, 13, + 2, 293, 295, 7, 13, 2, 2, 294, 293, 3, 2, 2, 2, 294, 295, 3, 2, 2, 2, 295, + 296, 3, 2, 2, 2, 296, 297, 7, 30, 2, 2, 297, 314, 7, 52, 2, 2, 298, 303, + 5, 26, 14, 2, 299, 300, 7, 58, 2, 2, 300, 302, 5, 26, 14, 2, 301, 299, + 3, 2, 2, 2, 302, 305, 3, 2, 2, 2, 303, 301, 3, 2, 2, 2, 303, 304, 3, 2, + 2, 2, 304, 315, 3, 2, 2, 2, 305, 303, 3, 2, 2, 2, 306, 311, 5, 28, 15, + 2, 307, 308, 7, 58, 2, 2, 308, 310, 5, 28, 15, 2, 309, 307, 3, 2, 2, 2, + 310, 313, 3, 2, 2, 2, 311, 309, 3, 2, 2, 2, 311, 312, 3, 2, 2, 2, 312, + 315, 3, 2, 2, 2, 313, 311, 3, 2, 2, 2, 314, 298, 3, 2, 2, 2, 314, 306, + 3, 2, 2, 2, 315, 316, 3, 2, 2, 2, 316, 317, 7, 53, 2, 2, 317, 69, 3, 2, + 2, 2, 24, 81, 92, 96, 105, 114, 122, 129, 139, 147, 175, 185, 201, 215, + 227, 239, 251, 263, 288, 294, 303, 311, 314, } var deserializer = antlr.NewATNDeserializer(nil) var deserializedATN = deserializer.DeserializeFromUInt16(parserATN) @@ -170,27 +157,29 @@ var deserializedATN = deserializer.DeserializeFromUInt16(parserATN) var literalNames = []string{ "", "", "'<'", "'='", "'>'", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "'#'", "'$'", "'_'", "'\"'", "'%'", "'&'", - "", "'('", "')'", "'['", "']'", "'*'", "'+'", "','", "'-'", "'.'", "'/'", - "':'", "';'", "'?'", "'|'", "", "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "''''", + "", "", "", "", "", "", "", "", "", "'#'", "'$'", "'_'", "'\"'", "'%'", + "'&'", "", "'('", "')'", "'['", "']'", "'*'", "'+'", "','", "'-'", "'.'", + "'/'", "':'", "';'", "'?'", "'|'", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", + "''''", } var symbolicNames = []string{ "", "ComparisonOperator", "LT", "EQ", "GT", "NEQ", "GTEQ", "LTEQ", "BooleanLiteral", "AND", "OR", "NOT", "LIKE", "ILIKE", "BETWEEN", "IS", "NULL", "WILDCARD", - "SINGLECHAR", "ESCAPECHAR", "NOCASE", "SpatialOperator", "TemporalOperator", - "ArrayOperator", "EXISTS", "EXIST", "DOES", "IN", "POINT", "LINESTRING", - "POLYGON", "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", "GEOMETRYCOLLECTION", - "ENVELOPE", "NumericLiteral", "Identifier", "IdentifierStart", "IdentifierPart", - "ALPHA", "DIGIT", "OCTOTHORP", "DOLLAR", "UNDERSCORE", "DOUBLEQUOTE", "PERCENT", - "AMPERSAND", "QUOTE", "LEFTPAREN", "RIGHTPAREN", "LEFTSQUAREBRACKET", "RIGHTSQUAREBRACKET", - "ASTERISK", "PLUS", "COMMA", "MINUS", "PERIOD", "SOLIDUS", "COLON", "SEMICOLON", - "QUESTIONMARK", "VERTICALBAR", "BIT", "HEXIT", "UnsignedNumericLiteral", - "SignedNumericLiteral", "ExactNumericLiteral", "ApproximateNumericLiteral", - "Mantissa", "Exponent", "SignedInteger", "UnsignedInteger", "Sign", "TemporalLiteral", - "Instant", "Interval", "InstantInInterval", "FullDate", "DateYear", "DateMonth", - "DateDay", "UtcTime", "TimeZoneOffset", "TimeHour", "TimeMinute", "TimeSecond", - "NOW", "WS", "CharacterStringLiteral", "QuotedQuote", + "SINGLECHAR", "ESCAPECHAR", "NOCASE", "SpatialOperator", "DistanceOperator", + "TemporalOperator", "ArrayOperator", "EXISTS", "EXIST", "DOES", "IN", "POINT", + "LINESTRING", "POLYGON", "MULTIPOINT", "MULTILINESTRING", "MULTIPOLYGON", + "GEOMETRYCOLLECTION", "ENVELOPE", "NumericLiteral", "Identifier", "IdentifierStart", + "IdentifierPart", "ALPHA", "DIGIT", "OCTOTHORP", "DOLLAR", "UNDERSCORE", + "DOUBLEQUOTE", "PERCENT", "AMPERSAND", "QUOTE", "LEFTPAREN", "RIGHTPAREN", + "LEFTSQUAREBRACKET", "RIGHTSQUAREBRACKET", "ASTERISK", "PLUS", "COMMA", + "MINUS", "PERIOD", "SOLIDUS", "COLON", "SEMICOLON", "QUESTIONMARK", "VERTICALBAR", + "BIT", "HEXIT", "UnsignedNumericLiteral", "SignedNumericLiteral", "ExactNumericLiteral", + "ApproximateNumericLiteral", "Mantissa", "Exponent", "SignedInteger", "UnsignedInteger", + "Sign", "TemporalLiteral", "Instant", "Interval", "InstantInInterval", + "FullDate", "DateYear", "DateMonth", "DateDay", "UtcTime", "TimeZoneOffset", + "TimeHour", "TimeMinute", "TimeSecond", "NOW", "WS", "CharacterStringLiteral", + "QuotedQuote", } var ruleNames = []string{ @@ -198,12 +187,10 @@ var ruleNames = []string{ "booleanPrimary", "predicate", "binaryComparisonPredicate", "likePredicate", "betweenPredicate", "isNullPredicate", "scalarExpression", "propertyName", "characterLiteral", "numericLiteral", "booleanLiteral", "spatialPredicate", - "geomExpression", "geomLiteral", "point", "linestring", "linestringDef", - "polygon", "polygonDef", "multiPoint", "multiLinestring", "multiPolygon", - "geometryCollection", "envelope", "coordinate", "xCoord", "yCoord", "zCoord", - "westBoundLon", "eastBoundLon", "northBoundLat", "southBoundLat", "minElev", - "maxElev", "temporalPredicate", "temporalExpression", "temporalLiteral", - "inPredicate", + "distancePredicate", "geomExpression", "geomLiteral", "point", "linestring", + "coordList", "polygon", "polygonDef", "multiPoint", "multiLinestring", + "multiPolygon", "geometryCollection", "envelope", "coordinate", "temporalPredicate", + "temporalExpression", "temporalLiteral", "inPredicate", } var decisionToDFA = make([]*antlr.DFA, len(deserializedATN.DecisionToState)) @@ -255,75 +242,76 @@ const ( CQLESCAPECHAR = 19 CQLNOCASE = 20 CQLSpatialOperator = 21 - CQLTemporalOperator = 22 - CQLArrayOperator = 23 - CQLEXISTS = 24 - CQLEXIST = 25 - CQLDOES = 26 - CQLIN = 27 - CQLPOINT = 28 - CQLLINESTRING = 29 - CQLPOLYGON = 30 - CQLMULTIPOINT = 31 - CQLMULTILINESTRING = 32 - CQLMULTIPOLYGON = 33 - CQLGEOMETRYCOLLECTION = 34 - CQLENVELOPE = 35 - CQLNumericLiteral = 36 - CQLIdentifier = 37 - CQLIdentifierStart = 38 - CQLIdentifierPart = 39 - CQLALPHA = 40 - CQLDIGIT = 41 - CQLOCTOTHORP = 42 - CQLDOLLAR = 43 - CQLUNDERSCORE = 44 - CQLDOUBLEQUOTE = 45 - CQLPERCENT = 46 - CQLAMPERSAND = 47 - CQLQUOTE = 48 - CQLLEFTPAREN = 49 - CQLRIGHTPAREN = 50 - CQLLEFTSQUAREBRACKET = 51 - CQLRIGHTSQUAREBRACKET = 52 - CQLASTERISK = 53 - CQLPLUS = 54 - CQLCOMMA = 55 - CQLMINUS = 56 - CQLPERIOD = 57 - CQLSOLIDUS = 58 - CQLCOLON = 59 - CQLSEMICOLON = 60 - CQLQUESTIONMARK = 61 - CQLVERTICALBAR = 62 - CQLBIT = 63 - CQLHEXIT = 64 - CQLUnsignedNumericLiteral = 65 - CQLSignedNumericLiteral = 66 - CQLExactNumericLiteral = 67 - CQLApproximateNumericLiteral = 68 - CQLMantissa = 69 - CQLExponent = 70 - CQLSignedInteger = 71 - CQLUnsignedInteger = 72 - CQLSign = 73 - CQLTemporalLiteral = 74 - CQLInstant = 75 - CQLInterval = 76 - CQLInstantInInterval = 77 - CQLFullDate = 78 - CQLDateYear = 79 - CQLDateMonth = 80 - CQLDateDay = 81 - CQLUtcTime = 82 - CQLTimeZoneOffset = 83 - CQLTimeHour = 84 - CQLTimeMinute = 85 - CQLTimeSecond = 86 - CQLNOW = 87 - CQLWS = 88 - CQLCharacterStringLiteral = 89 - CQLQuotedQuote = 90 + CQLDistanceOperator = 22 + CQLTemporalOperator = 23 + CQLArrayOperator = 24 + CQLEXISTS = 25 + CQLEXIST = 26 + CQLDOES = 27 + CQLIN = 28 + CQLPOINT = 29 + CQLLINESTRING = 30 + CQLPOLYGON = 31 + CQLMULTIPOINT = 32 + CQLMULTILINESTRING = 33 + CQLMULTIPOLYGON = 34 + CQLGEOMETRYCOLLECTION = 35 + CQLENVELOPE = 36 + CQLNumericLiteral = 37 + CQLIdentifier = 38 + CQLIdentifierStart = 39 + CQLIdentifierPart = 40 + CQLALPHA = 41 + CQLDIGIT = 42 + CQLOCTOTHORP = 43 + CQLDOLLAR = 44 + CQLUNDERSCORE = 45 + CQLDOUBLEQUOTE = 46 + CQLPERCENT = 47 + CQLAMPERSAND = 48 + CQLQUOTE = 49 + CQLLEFTPAREN = 50 + CQLRIGHTPAREN = 51 + CQLLEFTSQUAREBRACKET = 52 + CQLRIGHTSQUAREBRACKET = 53 + CQLASTERISK = 54 + CQLPLUS = 55 + CQLCOMMA = 56 + CQLMINUS = 57 + CQLPERIOD = 58 + CQLSOLIDUS = 59 + CQLCOLON = 60 + CQLSEMICOLON = 61 + CQLQUESTIONMARK = 62 + CQLVERTICALBAR = 63 + CQLBIT = 64 + CQLHEXIT = 65 + CQLUnsignedNumericLiteral = 66 + CQLSignedNumericLiteral = 67 + CQLExactNumericLiteral = 68 + CQLApproximateNumericLiteral = 69 + CQLMantissa = 70 + CQLExponent = 71 + CQLSignedInteger = 72 + CQLUnsignedInteger = 73 + CQLSign = 74 + CQLTemporalLiteral = 75 + CQLInstant = 76 + CQLInterval = 77 + CQLInstantInInterval = 78 + CQLFullDate = 79 + CQLDateYear = 80 + CQLDateMonth = 81 + CQLDateDay = 82 + CQLUtcTime = 83 + CQLTimeZoneOffset = 84 + CQLTimeHour = 85 + CQLTimeMinute = 86 + CQLTimeSecond = 87 + CQLNOW = 88 + CQLWS = 89 + CQLCharacterStringLiteral = 90 + CQLQuotedQuote = 91 ) // CQL rules. @@ -344,32 +332,24 @@ const ( CQLRULE_numericLiteral = 13 CQLRULE_booleanLiteral = 14 CQLRULE_spatialPredicate = 15 - CQLRULE_geomExpression = 16 - CQLRULE_geomLiteral = 17 - CQLRULE_point = 18 - CQLRULE_linestring = 19 - CQLRULE_linestringDef = 20 - CQLRULE_polygon = 21 - CQLRULE_polygonDef = 22 - CQLRULE_multiPoint = 23 - CQLRULE_multiLinestring = 24 - CQLRULE_multiPolygon = 25 - CQLRULE_geometryCollection = 26 - CQLRULE_envelope = 27 - CQLRULE_coordinate = 28 - CQLRULE_xCoord = 29 - CQLRULE_yCoord = 30 - CQLRULE_zCoord = 31 - CQLRULE_westBoundLon = 32 - CQLRULE_eastBoundLon = 33 - CQLRULE_northBoundLat = 34 - CQLRULE_southBoundLat = 35 - CQLRULE_minElev = 36 - CQLRULE_maxElev = 37 - CQLRULE_temporalPredicate = 38 - CQLRULE_temporalExpression = 39 - CQLRULE_temporalLiteral = 40 - CQLRULE_inPredicate = 41 + CQLRULE_distancePredicate = 16 + CQLRULE_geomExpression = 17 + CQLRULE_geomLiteral = 18 + CQLRULE_point = 19 + CQLRULE_linestring = 20 + CQLRULE_coordList = 21 + CQLRULE_polygon = 22 + CQLRULE_polygonDef = 23 + CQLRULE_multiPoint = 24 + CQLRULE_multiLinestring = 25 + CQLRULE_multiPolygon = 26 + CQLRULE_geometryCollection = 27 + CQLRULE_envelope = 28 + CQLRULE_coordinate = 29 + CQLRULE_temporalPredicate = 30 + CQLRULE_temporalExpression = 31 + CQLRULE_temporalLiteral = 32 + CQLRULE_inPredicate = 33 ) // ICqlFilterContext is an interface to support dynamic dispatch. @@ -466,11 +446,11 @@ func (p *CQL) CqlFilter() (localctx ICqlFilterContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(84) + p.SetState(68) p.booleanValueExpression(0) } { - p.SetState(85) + p.SetState(69) p.Match(CQLEOF) } @@ -592,12 +572,12 @@ func (p *CQL) booleanValueExpression(_p int) (localctx IBooleanValueExpressionCo p.EnterOuterAlt(localctx, 1) { - p.SetState(88) + p.SetState(72) p.booleanTerm(0) } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(95) + p.SetState(79) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) @@ -609,22 +589,22 @@ func (p *CQL) booleanValueExpression(_p int) (localctx IBooleanValueExpressionCo _prevctx = localctx localctx = NewBooleanValueExpressionContext(p, _parentctx, _parentState) p.PushNewRecursionContext(localctx, _startState, CQLRULE_booleanValueExpression) - p.SetState(90) + p.SetState(74) if !(p.Precpred(p.GetParserRuleContext(), 1)) { panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) } { - p.SetState(91) + p.SetState(75) p.Match(CQLOR) } { - p.SetState(92) + p.SetState(76) p.booleanTerm(0) } } - p.SetState(97) + p.SetState(81) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) } @@ -747,12 +727,12 @@ func (p *CQL) booleanTerm(_p int) (localctx IBooleanTermContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(99) + p.SetState(83) p.BooleanFactor() } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(106) + p.SetState(90) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) @@ -764,22 +744,22 @@ func (p *CQL) booleanTerm(_p int) (localctx IBooleanTermContext) { _prevctx = localctx localctx = NewBooleanTermContext(p, _parentctx, _parentState) p.PushNewRecursionContext(localctx, _startState, CQLRULE_booleanTerm) - p.SetState(101) + p.SetState(85) if !(p.Precpred(p.GetParserRuleContext(), 1)) { panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) } { - p.SetState(102) + p.SetState(86) p.Match(CQLAND) } { - p.SetState(103) + p.SetState(87) p.BooleanFactor() } } - p.SetState(108) + p.SetState(92) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) } @@ -881,19 +861,19 @@ func (p *CQL) BooleanFactor() (localctx IBooleanFactorContext) { }() p.EnterOuterAlt(localctx, 1) - p.SetState(110) + p.SetState(94) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(109) + p.SetState(93) p.Match(CQLNOT) } } { - p.SetState(112) + p.SetState(96) p.BooleanPrimary() } @@ -1006,29 +986,29 @@ func (p *CQL) BooleanPrimary() (localctx IBooleanPrimaryContext) { } }() - p.SetState(119) + p.SetState(103) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { - case CQLBooleanLiteral, CQLNumericLiteral, CQLIdentifier, CQLCharacterStringLiteral: + case CQLBooleanLiteral, CQLSpatialOperator, CQLDistanceOperator, CQLNumericLiteral, CQLIdentifier, CQLCharacterStringLiteral: p.EnterOuterAlt(localctx, 1) { - p.SetState(114) + p.SetState(98) p.Predicate() } case CQLLEFTPAREN: p.EnterOuterAlt(localctx, 2) { - p.SetState(115) + p.SetState(99) p.Match(CQLLEFTPAREN) } { - p.SetState(116) + p.SetState(100) p.booleanValueExpression(0) } { - p.SetState(117) + p.SetState(101) p.Match(CQLRIGHTPAREN) } @@ -1127,6 +1107,26 @@ func (s *PredicateContext) InPredicate() IInPredicateContext { return t.(IInPredicateContext) } +func (s *PredicateContext) SpatialPredicate() ISpatialPredicateContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*ISpatialPredicateContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(ISpatialPredicateContext) +} + +func (s *PredicateContext) DistancePredicate() IDistancePredicateContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IDistancePredicateContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(IDistancePredicateContext) +} + func (s *PredicateContext) GetRuleContext() antlr.RuleContext { return s } @@ -1167,44 +1167,58 @@ func (p *CQL) Predicate() (localctx IPredicateContext) { } }() - p.SetState(126) + p.SetState(112) p.GetErrorHandler().Sync(p) switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { - p.SetState(121) + p.SetState(105) p.BinaryComparisonPredicate() } case 2: p.EnterOuterAlt(localctx, 2) { - p.SetState(122) + p.SetState(106) p.LikePredicate() } case 3: p.EnterOuterAlt(localctx, 3) { - p.SetState(123) + p.SetState(107) p.BetweenPredicate() } case 4: p.EnterOuterAlt(localctx, 4) { - p.SetState(124) + p.SetState(108) p.IsNullPredicate() } case 5: p.EnterOuterAlt(localctx, 5) { - p.SetState(125) + p.SetState(109) p.InPredicate() } + case 6: + p.EnterOuterAlt(localctx, 6) + { + p.SetState(110) + p.SpatialPredicate() + } + + case 7: + p.EnterOuterAlt(localctx, 7) + { + p.SetState(111) + p.DistancePredicate() + } + } return localctx @@ -1317,15 +1331,15 @@ func (p *CQL) BinaryComparisonPredicate() (localctx IBinaryComparisonPredicateCo p.EnterOuterAlt(localctx, 1) { - p.SetState(128) + p.SetState(114) p.ScalarExpression() } { - p.SetState(129) + p.SetState(115) p.Match(CQLComparisonOperator) } { - p.SetState(130) + p.SetState(116) p.ScalarExpression() } @@ -1445,21 +1459,21 @@ func (p *CQL) LikePredicate() (localctx ILikePredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(132) + p.SetState(118) p.PropertyName() } - p.SetState(134) + p.SetState(120) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(133) + p.SetState(119) p.Match(CQLNOT) } } - p.SetState(136) + p.SetState(122) _la = p.GetTokenStream().LA(1) if !(_la == CQLLIKE || _la == CQLILIKE) { @@ -1469,7 +1483,7 @@ func (p *CQL) LikePredicate() (localctx ILikePredicateContext) { p.Consume() } { - p.SetState(137) + p.SetState(123) p.CharacterLiteral() } @@ -1602,34 +1616,34 @@ func (p *CQL) BetweenPredicate() (localctx IBetweenPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(139) + p.SetState(125) p.PropertyName() } - p.SetState(141) + p.SetState(127) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(140) + p.SetState(126) p.Match(CQLNOT) } } { - p.SetState(143) + p.SetState(129) p.Match(CQLBETWEEN) } { - p.SetState(144) + p.SetState(130) p.ScalarExpression() } { - p.SetState(145) + p.SetState(131) p.Match(CQLAND) } { - p.SetState(146) + p.SetState(132) p.ScalarExpression() } @@ -1739,26 +1753,26 @@ func (p *CQL) IsNullPredicate() (localctx IIsNullPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(148) + p.SetState(134) p.PropertyName() } { - p.SetState(149) + p.SetState(135) p.Match(CQLIS) } - p.SetState(151) + p.SetState(137) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(150) + p.SetState(136) p.Match(CQLNOT) } } { - p.SetState(153) + p.SetState(139) p.Match(CQLNULL) } @@ -1883,35 +1897,35 @@ func (p *CQL) ScalarExpression() (localctx IScalarExpressionContext) { } }() - p.SetState(159) + p.SetState(145) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLIdentifier: p.EnterOuterAlt(localctx, 1) { - p.SetState(155) + p.SetState(141) p.PropertyName() } case CQLCharacterStringLiteral: p.EnterOuterAlt(localctx, 2) { - p.SetState(156) + p.SetState(142) p.CharacterLiteral() } case CQLNumericLiteral: p.EnterOuterAlt(localctx, 3) { - p.SetState(157) + p.SetState(143) p.NumericLiteral() } case CQLBooleanLiteral: p.EnterOuterAlt(localctx, 4) { - p.SetState(158) + p.SetState(144) p.BooleanLiteral() } @@ -2006,7 +2020,7 @@ func (p *CQL) PropertyName() (localctx IPropertyNameContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(161) + p.SetState(147) p.Match(CQLIdentifier) } @@ -2097,7 +2111,7 @@ func (p *CQL) CharacterLiteral() (localctx ICharacterLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(163) + p.SetState(149) p.Match(CQLCharacterStringLiteral) } @@ -2188,7 +2202,7 @@ func (p *CQL) NumericLiteral() (localctx INumericLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(165) + p.SetState(151) p.Match(CQLNumericLiteral) } @@ -2279,7 +2293,7 @@ func (p *CQL) BooleanLiteral() (localctx IBooleanLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(167) + p.SetState(153) p.Match(CQLBooleanLiteral) } @@ -2405,27 +2419,189 @@ func (p *CQL) SpatialPredicate() (localctx ISpatialPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(169) + p.SetState(155) p.Match(CQLSpatialOperator) } { - p.SetState(170) + p.SetState(156) + p.Match(CQLLEFTPAREN) + } + { + p.SetState(157) + p.GeomExpression() + } + { + p.SetState(158) + p.Match(CQLCOMMA) + } + { + p.SetState(159) + p.GeomExpression() + } + { + p.SetState(160) + p.Match(CQLRIGHTPAREN) + } + + return localctx +} + +// IDistancePredicateContext is an interface to support dynamic dispatch. +type IDistancePredicateContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsDistancePredicateContext differentiates from other interfaces. + IsDistancePredicateContext() +} + +type DistancePredicateContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyDistancePredicateContext() *DistancePredicateContext { + var p = new(DistancePredicateContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CQLRULE_distancePredicate + return p +} + +func (*DistancePredicateContext) IsDistancePredicateContext() {} + +func NewDistancePredicateContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *DistancePredicateContext { + var p = new(DistancePredicateContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CQLRULE_distancePredicate + + return p +} + +func (s *DistancePredicateContext) GetParser() antlr.Parser { return s.parser } + +func (s *DistancePredicateContext) DistanceOperator() antlr.TerminalNode { + return s.GetToken(CQLDistanceOperator, 0) +} + +func (s *DistancePredicateContext) LEFTPAREN() antlr.TerminalNode { + return s.GetToken(CQLLEFTPAREN, 0) +} + +func (s *DistancePredicateContext) AllGeomExpression() []IGeomExpressionContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IGeomExpressionContext)(nil)).Elem()) + var tst = make([]IGeomExpressionContext, len(ts)) + + for i, t := range ts { + if t != nil { + tst[i] = t.(IGeomExpressionContext) + } + } + + return tst +} + +func (s *DistancePredicateContext) GeomExpression(i int) IGeomExpressionContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IGeomExpressionContext)(nil)).Elem(), i) + + if t == nil { + return nil + } + + return t.(IGeomExpressionContext) +} + +func (s *DistancePredicateContext) AllCOMMA() []antlr.TerminalNode { + return s.GetTokens(CQLCOMMA) +} + +func (s *DistancePredicateContext) COMMA(i int) antlr.TerminalNode { + return s.GetToken(CQLCOMMA, i) +} + +func (s *DistancePredicateContext) NumericLiteral() antlr.TerminalNode { + return s.GetToken(CQLNumericLiteral, 0) +} + +func (s *DistancePredicateContext) RIGHTPAREN() antlr.TerminalNode { + return s.GetToken(CQLRIGHTPAREN, 0) +} + +func (s *DistancePredicateContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *DistancePredicateContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *DistancePredicateContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CQLListener); ok { + listenerT.EnterDistancePredicate(s) + } +} + +func (s *DistancePredicateContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CQLListener); ok { + listenerT.ExitDistancePredicate(s) + } +} + +func (p *CQL) DistancePredicate() (localctx IDistancePredicateContext) { + localctx = NewDistancePredicateContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 32, CQLRULE_distancePredicate) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(162) + p.Match(CQLDistanceOperator) + } + { + p.SetState(163) p.Match(CQLLEFTPAREN) } { - p.SetState(171) + p.SetState(164) p.GeomExpression() } { - p.SetState(172) + p.SetState(165) p.Match(CQLCOMMA) } { - p.SetState(173) + p.SetState(166) p.GeomExpression() } { - p.SetState(174) + p.SetState(167) + p.Match(CQLCOMMA) + } + { + p.SetState(168) + p.Match(CQLNumericLiteral) + } + { + p.SetState(169) p.Match(CQLRIGHTPAREN) } @@ -2512,7 +2688,7 @@ func (s *GeomExpressionContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) GeomExpression() (localctx IGeomExpressionContext) { localctx = NewGeomExpressionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 32, CQLRULE_geomExpression) + p.EnterRule(localctx, 34, CQLRULE_geomExpression) defer func() { p.ExitRule() @@ -2530,21 +2706,21 @@ func (p *CQL) GeomExpression() (localctx IGeomExpressionContext) { } }() - p.SetState(178) + p.SetState(173) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLIdentifier: p.EnterOuterAlt(localctx, 1) { - p.SetState(176) + p.SetState(171) p.PropertyName() } case CQLPOINT, CQLLINESTRING, CQLPOLYGON, CQLMULTIPOINT, CQLMULTILINESTRING, CQLMULTIPOLYGON, CQLGEOMETRYCOLLECTION, CQLENVELOPE: p.EnterOuterAlt(localctx, 2) { - p.SetState(177) + p.SetState(172) p.GeomLiteral() } @@ -2695,7 +2871,7 @@ func (s *GeomLiteralContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) GeomLiteral() (localctx IGeomLiteralContext) { localctx = NewGeomLiteralContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 34, CQLRULE_geomLiteral) + p.EnterRule(localctx, 36, CQLRULE_geomLiteral) defer func() { p.ExitRule() @@ -2713,63 +2889,63 @@ func (p *CQL) GeomLiteral() (localctx IGeomLiteralContext) { } }() - p.SetState(188) + p.SetState(183) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLPOINT: p.EnterOuterAlt(localctx, 1) { - p.SetState(180) + p.SetState(175) p.Point() } case CQLLINESTRING: p.EnterOuterAlt(localctx, 2) { - p.SetState(181) + p.SetState(176) p.Linestring() } case CQLPOLYGON: p.EnterOuterAlt(localctx, 3) { - p.SetState(182) + p.SetState(177) p.Polygon() } case CQLMULTIPOINT: p.EnterOuterAlt(localctx, 4) { - p.SetState(183) + p.SetState(178) p.MultiPoint() } case CQLMULTILINESTRING: p.EnterOuterAlt(localctx, 5) { - p.SetState(184) + p.SetState(179) p.MultiLinestring() } case CQLMULTIPOLYGON: p.EnterOuterAlt(localctx, 6) { - p.SetState(185) + p.SetState(180) p.MultiPolygon() } case CQLGEOMETRYCOLLECTION: p.EnterOuterAlt(localctx, 7) { - p.SetState(186) + p.SetState(181) p.GeometryCollection() } case CQLENVELOPE: p.EnterOuterAlt(localctx, 8) { - p.SetState(187) + p.SetState(182) p.Envelope() } @@ -2862,7 +3038,7 @@ func (s *PointContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Point() (localctx IPointContext) { localctx = NewPointContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 36, CQLRULE_point) + p.EnterRule(localctx, 38, CQLRULE_point) defer func() { p.ExitRule() @@ -2882,19 +3058,19 @@ func (p *CQL) Point() (localctx IPointContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(190) + p.SetState(185) p.Match(CQLPOINT) } { - p.SetState(191) + p.SetState(186) p.Match(CQLLEFTPAREN) } { - p.SetState(192) + p.SetState(187) p.Coordinate() } { - p.SetState(193) + p.SetState(188) p.Match(CQLRIGHTPAREN) } @@ -2943,14 +3119,14 @@ func (s *LinestringContext) LINESTRING() antlr.TerminalNode { return s.GetToken(CQLLINESTRING, 0) } -func (s *LinestringContext) LinestringDef() ILinestringDefContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ILinestringDefContext)(nil)).Elem(), 0) +func (s *LinestringContext) CoordList() ICoordListContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordListContext)(nil)).Elem(), 0) if t == nil { return nil } - return t.(ILinestringDefContext) + return t.(ICoordListContext) } func (s *LinestringContext) GetRuleContext() antlr.RuleContext { @@ -2975,7 +3151,7 @@ func (s *LinestringContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Linestring() (localctx ILinestringContext) { localctx = NewLinestringContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 38, CQLRULE_linestring) + p.EnterRule(localctx, 40, CQLRULE_linestring) defer func() { p.ExitRule() @@ -2995,60 +3171,60 @@ func (p *CQL) Linestring() (localctx ILinestringContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(195) + p.SetState(190) p.Match(CQLLINESTRING) } { - p.SetState(196) - p.LinestringDef() + p.SetState(191) + p.CoordList() } return localctx } -// ILinestringDefContext is an interface to support dynamic dispatch. -type ILinestringDefContext interface { +// ICoordListContext is an interface to support dynamic dispatch. +type ICoordListContext interface { antlr.ParserRuleContext // GetParser returns the parser. GetParser() antlr.Parser - // IsLinestringDefContext differentiates from other interfaces. - IsLinestringDefContext() + // IsCoordListContext differentiates from other interfaces. + IsCoordListContext() } -type LinestringDefContext struct { +type CoordListContext struct { *antlr.BaseParserRuleContext parser antlr.Parser } -func NewEmptyLinestringDefContext() *LinestringDefContext { - var p = new(LinestringDefContext) +func NewEmptyCoordListContext() *CoordListContext { + var p = new(CoordListContext) p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_linestringDef + p.RuleIndex = CQLRULE_coordList return p } -func (*LinestringDefContext) IsLinestringDefContext() {} +func (*CoordListContext) IsCoordListContext() {} -func NewLinestringDefContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LinestringDefContext { - var p = new(LinestringDefContext) +func NewCoordListContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CoordListContext { + var p = new(CoordListContext) p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) p.parser = parser - p.RuleIndex = CQLRULE_linestringDef + p.RuleIndex = CQLRULE_coordList return p } -func (s *LinestringDefContext) GetParser() antlr.Parser { return s.parser } +func (s *CoordListContext) GetParser() antlr.Parser { return s.parser } -func (s *LinestringDefContext) LEFTPAREN() antlr.TerminalNode { +func (s *CoordListContext) LEFTPAREN() antlr.TerminalNode { return s.GetToken(CQLLEFTPAREN, 0) } -func (s *LinestringDefContext) AllCoordinate() []ICoordinateContext { +func (s *CoordListContext) AllCoordinate() []ICoordinateContext { var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ICoordinateContext)(nil)).Elem()) var tst = make([]ICoordinateContext, len(ts)) @@ -3061,7 +3237,7 @@ func (s *LinestringDefContext) AllCoordinate() []ICoordinateContext { return tst } -func (s *LinestringDefContext) Coordinate(i int) ICoordinateContext { +func (s *CoordListContext) Coordinate(i int) ICoordinateContext { var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordinateContext)(nil)).Elem(), i) if t == nil { @@ -3071,41 +3247,41 @@ func (s *LinestringDefContext) Coordinate(i int) ICoordinateContext { return t.(ICoordinateContext) } -func (s *LinestringDefContext) RIGHTPAREN() antlr.TerminalNode { +func (s *CoordListContext) RIGHTPAREN() antlr.TerminalNode { return s.GetToken(CQLRIGHTPAREN, 0) } -func (s *LinestringDefContext) AllCOMMA() []antlr.TerminalNode { +func (s *CoordListContext) AllCOMMA() []antlr.TerminalNode { return s.GetTokens(CQLCOMMA) } -func (s *LinestringDefContext) COMMA(i int) antlr.TerminalNode { +func (s *CoordListContext) COMMA(i int) antlr.TerminalNode { return s.GetToken(CQLCOMMA, i) } -func (s *LinestringDefContext) GetRuleContext() antlr.RuleContext { +func (s *CoordListContext) GetRuleContext() antlr.RuleContext { return s } -func (s *LinestringDefContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { +func (s *CoordListContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { return antlr.TreesStringTree(s, ruleNames, recog) } -func (s *LinestringDefContext) EnterRule(listener antlr.ParseTreeListener) { +func (s *CoordListContext) EnterRule(listener antlr.ParseTreeListener) { if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterLinestringDef(s) + listenerT.EnterCoordList(s) } } -func (s *LinestringDefContext) ExitRule(listener antlr.ParseTreeListener) { +func (s *CoordListContext) ExitRule(listener antlr.ParseTreeListener) { if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitLinestringDef(s) + listenerT.ExitCoordList(s) } } -func (p *CQL) LinestringDef() (localctx ILinestringDefContext) { - localctx = NewLinestringDefContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 40, CQLRULE_linestringDef) +func (p *CQL) CoordList() (localctx ICoordListContext) { + localctx = NewCoordListContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 42, CQLRULE_coordList) var _la int defer func() { @@ -3126,33 +3302,33 @@ func (p *CQL) LinestringDef() (localctx ILinestringDefContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(198) + p.SetState(193) p.Match(CQLLEFTPAREN) } { - p.SetState(199) + p.SetState(194) p.Coordinate() } - p.SetState(204) + p.SetState(199) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(200) + p.SetState(195) p.Match(CQLCOMMA) } { - p.SetState(201) + p.SetState(196) p.Coordinate() } - p.SetState(206) + p.SetState(201) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(207) + p.SetState(202) p.Match(CQLRIGHTPAREN) } @@ -3233,7 +3409,7 @@ func (s *PolygonContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Polygon() (localctx IPolygonContext) { localctx = NewPolygonContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 42, CQLRULE_polygon) + p.EnterRule(localctx, 44, CQLRULE_polygon) defer func() { p.ExitRule() @@ -3253,11 +3429,11 @@ func (p *CQL) Polygon() (localctx IPolygonContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(209) + p.SetState(204) p.Match(CQLPOLYGON) } { - p.SetState(210) + p.SetState(205) p.PolygonDef() } @@ -3306,27 +3482,27 @@ func (s *PolygonDefContext) LEFTPAREN() antlr.TerminalNode { return s.GetToken(CQLLEFTPAREN, 0) } -func (s *PolygonDefContext) AllLinestringDef() []ILinestringDefContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ILinestringDefContext)(nil)).Elem()) - var tst = make([]ILinestringDefContext, len(ts)) +func (s *PolygonDefContext) AllCoordList() []ICoordListContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ICoordListContext)(nil)).Elem()) + var tst = make([]ICoordListContext, len(ts)) for i, t := range ts { if t != nil { - tst[i] = t.(ILinestringDefContext) + tst[i] = t.(ICoordListContext) } } return tst } -func (s *PolygonDefContext) LinestringDef(i int) ILinestringDefContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ILinestringDefContext)(nil)).Elem(), i) +func (s *PolygonDefContext) CoordList(i int) ICoordListContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordListContext)(nil)).Elem(), i) if t == nil { return nil } - return t.(ILinestringDefContext) + return t.(ICoordListContext) } func (s *PolygonDefContext) RIGHTPAREN() antlr.TerminalNode { @@ -3363,7 +3539,7 @@ func (s *PolygonDefContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) PolygonDef() (localctx IPolygonDefContext) { localctx = NewPolygonDefContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 44, CQLRULE_polygonDef) + p.EnterRule(localctx, 46, CQLRULE_polygonDef) var _la int defer func() { @@ -3384,33 +3560,33 @@ func (p *CQL) PolygonDef() (localctx IPolygonDefContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(212) + p.SetState(207) p.Match(CQLLEFTPAREN) } { - p.SetState(213) - p.LinestringDef() + p.SetState(208) + p.CoordList() } - p.SetState(218) + p.SetState(213) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(214) + p.SetState(209) p.Match(CQLCOMMA) } { - p.SetState(215) - p.LinestringDef() + p.SetState(210) + p.CoordList() } - p.SetState(220) + p.SetState(215) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(221) + p.SetState(216) p.Match(CQLRIGHTPAREN) } @@ -3520,7 +3696,7 @@ func (s *MultiPointContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) MultiPoint() (localctx IMultiPointContext) { localctx = NewMultiPointContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 46, CQLRULE_multiPoint) + p.EnterRule(localctx, 48, CQLRULE_multiPoint) var _la int defer func() { @@ -3541,37 +3717,37 @@ func (p *CQL) MultiPoint() (localctx IMultiPointContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(223) + p.SetState(218) p.Match(CQLMULTIPOINT) } { - p.SetState(224) + p.SetState(219) p.Match(CQLLEFTPAREN) } { - p.SetState(225) + p.SetState(220) p.Coordinate() } - p.SetState(230) + p.SetState(225) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(226) + p.SetState(221) p.Match(CQLCOMMA) } { - p.SetState(227) + p.SetState(222) p.Coordinate() } - p.SetState(232) + p.SetState(227) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(233) + p.SetState(228) p.Match(CQLRIGHTPAREN) } @@ -3624,27 +3800,27 @@ func (s *MultiLinestringContext) LEFTPAREN() antlr.TerminalNode { return s.GetToken(CQLLEFTPAREN, 0) } -func (s *MultiLinestringContext) AllLinestringDef() []ILinestringDefContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ILinestringDefContext)(nil)).Elem()) - var tst = make([]ILinestringDefContext, len(ts)) +func (s *MultiLinestringContext) AllCoordList() []ICoordListContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ICoordListContext)(nil)).Elem()) + var tst = make([]ICoordListContext, len(ts)) for i, t := range ts { if t != nil { - tst[i] = t.(ILinestringDefContext) + tst[i] = t.(ICoordListContext) } } return tst } -func (s *MultiLinestringContext) LinestringDef(i int) ILinestringDefContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ILinestringDefContext)(nil)).Elem(), i) +func (s *MultiLinestringContext) CoordList(i int) ICoordListContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordListContext)(nil)).Elem(), i) if t == nil { return nil } - return t.(ILinestringDefContext) + return t.(ICoordListContext) } func (s *MultiLinestringContext) RIGHTPAREN() antlr.TerminalNode { @@ -3681,7 +3857,7 @@ func (s *MultiLinestringContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) MultiLinestring() (localctx IMultiLinestringContext) { localctx = NewMultiLinestringContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 48, CQLRULE_multiLinestring) + p.EnterRule(localctx, 50, CQLRULE_multiLinestring) var _la int defer func() { @@ -3702,37 +3878,37 @@ func (p *CQL) MultiLinestring() (localctx IMultiLinestringContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(235) + p.SetState(230) p.Match(CQLMULTILINESTRING) } { - p.SetState(236) + p.SetState(231) p.Match(CQLLEFTPAREN) } { - p.SetState(237) - p.LinestringDef() + p.SetState(232) + p.CoordList() } - p.SetState(242) + p.SetState(237) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(238) + p.SetState(233) p.Match(CQLCOMMA) } { - p.SetState(239) - p.LinestringDef() + p.SetState(234) + p.CoordList() } - p.SetState(244) + p.SetState(239) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(245) + p.SetState(240) p.Match(CQLRIGHTPAREN) } @@ -3842,7 +4018,7 @@ func (s *MultiPolygonContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) MultiPolygon() (localctx IMultiPolygonContext) { localctx = NewMultiPolygonContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 50, CQLRULE_multiPolygon) + p.EnterRule(localctx, 52, CQLRULE_multiPolygon) var _la int defer func() { @@ -3863,37 +4039,37 @@ func (p *CQL) MultiPolygon() (localctx IMultiPolygonContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(247) + p.SetState(242) p.Match(CQLMULTIPOLYGON) } { - p.SetState(248) + p.SetState(243) p.Match(CQLLEFTPAREN) } { - p.SetState(249) + p.SetState(244) p.PolygonDef() } - p.SetState(254) + p.SetState(249) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(250) + p.SetState(245) p.Match(CQLCOMMA) } { - p.SetState(251) + p.SetState(246) p.PolygonDef() } - p.SetState(256) + p.SetState(251) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(257) + p.SetState(252) p.Match(CQLRIGHTPAREN) } @@ -4003,7 +4179,7 @@ func (s *GeometryCollectionContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) GeometryCollection() (localctx IGeometryCollectionContext) { localctx = NewGeometryCollectionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 52, CQLRULE_geometryCollection) + p.EnterRule(localctx, 54, CQLRULE_geometryCollection) var _la int defer func() { @@ -4024,37 +4200,37 @@ func (p *CQL) GeometryCollection() (localctx IGeometryCollectionContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(259) + p.SetState(254) p.Match(CQLGEOMETRYCOLLECTION) } { - p.SetState(260) + p.SetState(255) p.Match(CQLLEFTPAREN) } { - p.SetState(261) + p.SetState(256) p.GeomLiteral() } - p.SetState(266) + p.SetState(261) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(262) + p.SetState(257) p.Match(CQLCOMMA) } { - p.SetState(263) + p.SetState(258) p.GeomLiteral() } - p.SetState(268) + p.SetState(263) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(269) + p.SetState(264) p.Match(CQLRIGHTPAREN) } @@ -4107,14 +4283,12 @@ func (s *EnvelopeContext) LEFTPAREN() antlr.TerminalNode { return s.GetToken(CQLLEFTPAREN, 0) } -func (s *EnvelopeContext) WestBoundLon() IWestBoundLonContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IWestBoundLonContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } +func (s *EnvelopeContext) AllNumericLiteral() []antlr.TerminalNode { + return s.GetTokens(CQLNumericLiteral) +} - return t.(IWestBoundLonContext) +func (s *EnvelopeContext) NumericLiteral(i int) antlr.TerminalNode { + return s.GetToken(CQLNumericLiteral, i) } func (s *EnvelopeContext) AllCOMMA() []antlr.TerminalNode { @@ -4125,60 +4299,10 @@ func (s *EnvelopeContext) COMMA(i int) antlr.TerminalNode { return s.GetToken(CQLCOMMA, i) } -func (s *EnvelopeContext) SouthBoundLat() ISouthBoundLatContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ISouthBoundLatContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(ISouthBoundLatContext) -} - -func (s *EnvelopeContext) EastBoundLon() IEastBoundLonContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IEastBoundLonContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(IEastBoundLonContext) -} - -func (s *EnvelopeContext) NorthBoundLat() INorthBoundLatContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*INorthBoundLatContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(INorthBoundLatContext) -} - func (s *EnvelopeContext) RIGHTPAREN() antlr.TerminalNode { return s.GetToken(CQLRIGHTPAREN, 0) } -func (s *EnvelopeContext) MinElev() IMinElevContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMinElevContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(IMinElevContext) -} - -func (s *EnvelopeContext) MaxElev() IMaxElevContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IMaxElevContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(IMaxElevContext) -} - func (s *EnvelopeContext) GetRuleContext() antlr.RuleContext { return s } @@ -4201,8 +4325,7 @@ func (s *EnvelopeContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Envelope() (localctx IEnvelopeContext) { localctx = NewEnvelopeContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 54, CQLRULE_envelope) - var _la int + p.EnterRule(localctx, 56, CQLRULE_envelope) defer func() { p.ExitRule() @@ -4222,913 +4345,118 @@ func (p *CQL) Envelope() (localctx IEnvelopeContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(271) + p.SetState(266) p.Match(CQLENVELOPE) } { - p.SetState(272) + p.SetState(267) p.Match(CQLLEFTPAREN) } { - p.SetState(273) - p.WestBoundLon() + p.SetState(268) + p.Match(CQLNumericLiteral) } { - p.SetState(274) + p.SetState(269) p.Match(CQLCOMMA) } { - p.SetState(275) - p.SouthBoundLat() + p.SetState(270) + p.Match(CQLNumericLiteral) } { - p.SetState(276) + p.SetState(271) p.Match(CQLCOMMA) } - p.SetState(280) - p.GetErrorHandler().Sync(p) - - if p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 17, p.GetParserRuleContext()) == 1 { - { - p.SetState(277) - p.MinElev() - } - { - p.SetState(278) - p.Match(CQLCOMMA) - } - - } - { - p.SetState(282) - p.EastBoundLon() - } - { - p.SetState(283) - p.Match(CQLCOMMA) - } - { - p.SetState(284) - p.NorthBoundLat() - } - p.SetState(287) - p.GetErrorHandler().Sync(p) - _la = p.GetTokenStream().LA(1) - - if _la == CQLCOMMA { - { - p.SetState(285) - p.Match(CQLCOMMA) - } - { - p.SetState(286) - p.MaxElev() - } - - } - { - p.SetState(289) - p.Match(CQLRIGHTPAREN) - } - - return localctx -} - -// ICoordinateContext is an interface to support dynamic dispatch. -type ICoordinateContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsCoordinateContext differentiates from other interfaces. - IsCoordinateContext() -} - -type CoordinateContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyCoordinateContext() *CoordinateContext { - var p = new(CoordinateContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_coordinate - return p -} - -func (*CoordinateContext) IsCoordinateContext() {} - -func NewCoordinateContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CoordinateContext { - var p = new(CoordinateContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_coordinate - - return p -} - -func (s *CoordinateContext) GetParser() antlr.Parser { return s.parser } - -func (s *CoordinateContext) XCoord() IXCoordContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IXCoordContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(IXCoordContext) -} - -func (s *CoordinateContext) YCoord() IYCoordContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IYCoordContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(IYCoordContext) -} - -func (s *CoordinateContext) ZCoord() IZCoordContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*IZCoordContext)(nil)).Elem(), 0) - - if t == nil { - return nil - } - - return t.(IZCoordContext) -} - -func (s *CoordinateContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *CoordinateContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *CoordinateContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterCoordinate(s) - } -} - -func (s *CoordinateContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitCoordinate(s) - } -} - -func (p *CQL) Coordinate() (localctx ICoordinateContext) { - localctx = NewCoordinateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 56, CQLRULE_coordinate) - var _la int - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(291) - p.XCoord() - } - { - p.SetState(292) - p.YCoord() - } - p.SetState(294) - p.GetErrorHandler().Sync(p) - _la = p.GetTokenStream().LA(1) - - if _la == CQLNumericLiteral { - { - p.SetState(293) - p.ZCoord() - } - - } - - return localctx -} - -// IXCoordContext is an interface to support dynamic dispatch. -type IXCoordContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsXCoordContext differentiates from other interfaces. - IsXCoordContext() -} - -type XCoordContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyXCoordContext() *XCoordContext { - var p = new(XCoordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_xCoord - return p -} - -func (*XCoordContext) IsXCoordContext() {} - -func NewXCoordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *XCoordContext { - var p = new(XCoordContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_xCoord - - return p -} - -func (s *XCoordContext) GetParser() antlr.Parser { return s.parser } - -func (s *XCoordContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *XCoordContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *XCoordContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *XCoordContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterXCoord(s) - } -} - -func (s *XCoordContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitXCoord(s) - } -} - -func (p *CQL) XCoord() (localctx IXCoordContext) { - localctx = NewXCoordContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 58, CQLRULE_xCoord) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(296) - p.Match(CQLNumericLiteral) - } - - return localctx -} - -// IYCoordContext is an interface to support dynamic dispatch. -type IYCoordContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsYCoordContext differentiates from other interfaces. - IsYCoordContext() -} - -type YCoordContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyYCoordContext() *YCoordContext { - var p = new(YCoordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_yCoord - return p -} - -func (*YCoordContext) IsYCoordContext() {} - -func NewYCoordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *YCoordContext { - var p = new(YCoordContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_yCoord - - return p -} - -func (s *YCoordContext) GetParser() antlr.Parser { return s.parser } - -func (s *YCoordContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *YCoordContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *YCoordContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *YCoordContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterYCoord(s) - } -} - -func (s *YCoordContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitYCoord(s) - } -} - -func (p *CQL) YCoord() (localctx IYCoordContext) { - localctx = NewYCoordContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 60, CQLRULE_yCoord) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(298) - p.Match(CQLNumericLiteral) - } - - return localctx -} - -// IZCoordContext is an interface to support dynamic dispatch. -type IZCoordContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsZCoordContext differentiates from other interfaces. - IsZCoordContext() -} - -type ZCoordContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyZCoordContext() *ZCoordContext { - var p = new(ZCoordContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_zCoord - return p -} - -func (*ZCoordContext) IsZCoordContext() {} - -func NewZCoordContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ZCoordContext { - var p = new(ZCoordContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_zCoord - - return p -} - -func (s *ZCoordContext) GetParser() antlr.Parser { return s.parser } - -func (s *ZCoordContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *ZCoordContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *ZCoordContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *ZCoordContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterZCoord(s) - } -} - -func (s *ZCoordContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitZCoord(s) - } -} - -func (p *CQL) ZCoord() (localctx IZCoordContext) { - localctx = NewZCoordContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 62, CQLRULE_zCoord) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(300) - p.Match(CQLNumericLiteral) - } - - return localctx -} - -// IWestBoundLonContext is an interface to support dynamic dispatch. -type IWestBoundLonContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsWestBoundLonContext differentiates from other interfaces. - IsWestBoundLonContext() -} - -type WestBoundLonContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyWestBoundLonContext() *WestBoundLonContext { - var p = new(WestBoundLonContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_westBoundLon - return p -} - -func (*WestBoundLonContext) IsWestBoundLonContext() {} - -func NewWestBoundLonContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *WestBoundLonContext { - var p = new(WestBoundLonContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_westBoundLon - - return p -} - -func (s *WestBoundLonContext) GetParser() antlr.Parser { return s.parser } - -func (s *WestBoundLonContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *WestBoundLonContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *WestBoundLonContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *WestBoundLonContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterWestBoundLon(s) - } -} - -func (s *WestBoundLonContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitWestBoundLon(s) - } -} - -func (p *CQL) WestBoundLon() (localctx IWestBoundLonContext) { - localctx = NewWestBoundLonContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 64, CQLRULE_westBoundLon) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) - { - p.SetState(302) - p.Match(CQLNumericLiteral) - } - - return localctx -} - -// IEastBoundLonContext is an interface to support dynamic dispatch. -type IEastBoundLonContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsEastBoundLonContext differentiates from other interfaces. - IsEastBoundLonContext() -} - -type EastBoundLonContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyEastBoundLonContext() *EastBoundLonContext { - var p = new(EastBoundLonContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_eastBoundLon - return p -} - -func (*EastBoundLonContext) IsEastBoundLonContext() {} - -func NewEastBoundLonContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *EastBoundLonContext { - var p = new(EastBoundLonContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_eastBoundLon - - return p -} - -func (s *EastBoundLonContext) GetParser() antlr.Parser { return s.parser } - -func (s *EastBoundLonContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *EastBoundLonContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *EastBoundLonContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *EastBoundLonContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterEastBoundLon(s) - } -} - -func (s *EastBoundLonContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitEastBoundLon(s) - } -} - -func (p *CQL) EastBoundLon() (localctx IEastBoundLonContext) { - localctx = NewEastBoundLonContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 66, CQLRULE_eastBoundLon) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) { - p.SetState(304) + p.SetState(272) p.Match(CQLNumericLiteral) } - - return localctx -} - -// INorthBoundLatContext is an interface to support dynamic dispatch. -type INorthBoundLatContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsNorthBoundLatContext differentiates from other interfaces. - IsNorthBoundLatContext() -} - -type NorthBoundLatContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyNorthBoundLatContext() *NorthBoundLatContext { - var p = new(NorthBoundLatContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_northBoundLat - return p -} - -func (*NorthBoundLatContext) IsNorthBoundLatContext() {} - -func NewNorthBoundLatContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *NorthBoundLatContext { - var p = new(NorthBoundLatContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_northBoundLat - - return p -} - -func (s *NorthBoundLatContext) GetParser() antlr.Parser { return s.parser } - -func (s *NorthBoundLatContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *NorthBoundLatContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *NorthBoundLatContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *NorthBoundLatContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterNorthBoundLat(s) - } -} - -func (s *NorthBoundLatContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitNorthBoundLat(s) + { + p.SetState(273) + p.Match(CQLCOMMA) } -} - -func (p *CQL) NorthBoundLat() (localctx INorthBoundLatContext) { - localctx = NewNorthBoundLatContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 68, CQLRULE_northBoundLat) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) { - p.SetState(306) + p.SetState(274) p.Match(CQLNumericLiteral) } - - return localctx -} - -// ISouthBoundLatContext is an interface to support dynamic dispatch. -type ISouthBoundLatContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsSouthBoundLatContext differentiates from other interfaces. - IsSouthBoundLatContext() -} - -type SouthBoundLatContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptySouthBoundLatContext() *SouthBoundLatContext { - var p = new(SouthBoundLatContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_southBoundLat - return p -} - -func (*SouthBoundLatContext) IsSouthBoundLatContext() {} - -func NewSouthBoundLatContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *SouthBoundLatContext { - var p = new(SouthBoundLatContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_southBoundLat - - return p -} - -func (s *SouthBoundLatContext) GetParser() antlr.Parser { return s.parser } - -func (s *SouthBoundLatContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *SouthBoundLatContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *SouthBoundLatContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *SouthBoundLatContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterSouthBoundLat(s) - } -} - -func (s *SouthBoundLatContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitSouthBoundLat(s) - } -} - -func (p *CQL) SouthBoundLat() (localctx ISouthBoundLatContext) { - localctx = NewSouthBoundLatContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 70, CQLRULE_southBoundLat) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) { - p.SetState(308) - p.Match(CQLNumericLiteral) + p.SetState(275) + p.Match(CQLRIGHTPAREN) } return localctx } -// IMinElevContext is an interface to support dynamic dispatch. -type IMinElevContext interface { +// ICoordinateContext is an interface to support dynamic dispatch. +type ICoordinateContext interface { antlr.ParserRuleContext // GetParser returns the parser. GetParser() antlr.Parser - // IsMinElevContext differentiates from other interfaces. - IsMinElevContext() + // IsCoordinateContext differentiates from other interfaces. + IsCoordinateContext() } -type MinElevContext struct { +type CoordinateContext struct { *antlr.BaseParserRuleContext parser antlr.Parser } -func NewEmptyMinElevContext() *MinElevContext { - var p = new(MinElevContext) +func NewEmptyCoordinateContext() *CoordinateContext { + var p = new(CoordinateContext) p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_minElev + p.RuleIndex = CQLRULE_coordinate return p } -func (*MinElevContext) IsMinElevContext() {} +func (*CoordinateContext) IsCoordinateContext() {} -func NewMinElevContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MinElevContext { - var p = new(MinElevContext) +func NewCoordinateContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *CoordinateContext { + var p = new(CoordinateContext) p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) p.parser = parser - p.RuleIndex = CQLRULE_minElev + p.RuleIndex = CQLRULE_coordinate return p } -func (s *MinElevContext) GetParser() antlr.Parser { return s.parser } +func (s *CoordinateContext) GetParser() antlr.Parser { return s.parser } -func (s *MinElevContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) +func (s *CoordinateContext) AllNumericLiteral() []antlr.TerminalNode { + return s.GetTokens(CQLNumericLiteral) +} + +func (s *CoordinateContext) NumericLiteral(i int) antlr.TerminalNode { + return s.GetToken(CQLNumericLiteral, i) } -func (s *MinElevContext) GetRuleContext() antlr.RuleContext { +func (s *CoordinateContext) GetRuleContext() antlr.RuleContext { return s } -func (s *MinElevContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { +func (s *CoordinateContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { return antlr.TreesStringTree(s, ruleNames, recog) } -func (s *MinElevContext) EnterRule(listener antlr.ParseTreeListener) { +func (s *CoordinateContext) EnterRule(listener antlr.ParseTreeListener) { if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterMinElev(s) + listenerT.EnterCoordinate(s) } } -func (s *MinElevContext) ExitRule(listener antlr.ParseTreeListener) { +func (s *CoordinateContext) ExitRule(listener antlr.ParseTreeListener) { if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitMinElev(s) + listenerT.ExitCoordinate(s) } } -func (p *CQL) MinElev() (localctx IMinElevContext) { - localctx = NewMinElevContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 72, CQLRULE_minElev) +func (p *CQL) Coordinate() (localctx ICoordinateContext) { + localctx = NewCoordinateContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 58, CQLRULE_coordinate) defer func() { p.ExitRule() @@ -5148,98 +4476,11 @@ func (p *CQL) MinElev() (localctx IMinElevContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(310) + p.SetState(277) p.Match(CQLNumericLiteral) } - - return localctx -} - -// IMaxElevContext is an interface to support dynamic dispatch. -type IMaxElevContext interface { - antlr.ParserRuleContext - - // GetParser returns the parser. - GetParser() antlr.Parser - - // IsMaxElevContext differentiates from other interfaces. - IsMaxElevContext() -} - -type MaxElevContext struct { - *antlr.BaseParserRuleContext - parser antlr.Parser -} - -func NewEmptyMaxElevContext() *MaxElevContext { - var p = new(MaxElevContext) - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) - p.RuleIndex = CQLRULE_maxElev - return p -} - -func (*MaxElevContext) IsMaxElevContext() {} - -func NewMaxElevContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MaxElevContext { - var p = new(MaxElevContext) - - p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) - - p.parser = parser - p.RuleIndex = CQLRULE_maxElev - - return p -} - -func (s *MaxElevContext) GetParser() antlr.Parser { return s.parser } - -func (s *MaxElevContext) NumericLiteral() antlr.TerminalNode { - return s.GetToken(CQLNumericLiteral, 0) -} - -func (s *MaxElevContext) GetRuleContext() antlr.RuleContext { - return s -} - -func (s *MaxElevContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { - return antlr.TreesStringTree(s, ruleNames, recog) -} - -func (s *MaxElevContext) EnterRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.EnterMaxElev(s) - } -} - -func (s *MaxElevContext) ExitRule(listener antlr.ParseTreeListener) { - if listenerT, ok := listener.(CQLListener); ok { - listenerT.ExitMaxElev(s) - } -} - -func (p *CQL) MaxElev() (localctx IMaxElevContext) { - localctx = NewMaxElevContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 74, CQLRULE_maxElev) - - defer func() { - p.ExitRule() - }() - - defer func() { - if err := recover(); err != nil { - if v, ok := err.(antlr.RecognitionException); ok { - localctx.SetException(v) - p.GetErrorHandler().ReportError(p, v) - p.GetErrorHandler().Recover(p, v) - } else { - panic(err) - } - } - }() - - p.EnterOuterAlt(localctx, 1) { - p.SetState(312) + p.SetState(278) p.Match(CQLNumericLiteral) } @@ -5337,7 +4578,7 @@ func (s *TemporalPredicateContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) TemporalPredicate() (localctx ITemporalPredicateContext) { localctx = NewTemporalPredicateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 76, CQLRULE_temporalPredicate) + p.EnterRule(localctx, 60, CQLRULE_temporalPredicate) var _la int defer func() { @@ -5358,10 +4599,10 @@ func (p *CQL) TemporalPredicate() (localctx ITemporalPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(314) + p.SetState(280) p.TemporalExpression() } - p.SetState(315) + p.SetState(281) _la = p.GetTokenStream().LA(1) if !(_la == CQLComparisonOperator || _la == CQLTemporalOperator) { @@ -5371,7 +4612,7 @@ func (p *CQL) TemporalPredicate() (localctx ITemporalPredicateContext) { p.Consume() } { - p.SetState(316) + p.SetState(282) p.TemporalExpression() } @@ -5458,7 +4699,7 @@ func (s *TemporalExpressionContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) TemporalExpression() (localctx ITemporalExpressionContext) { localctx = NewTemporalExpressionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 78, CQLRULE_temporalExpression) + p.EnterRule(localctx, 62, CQLRULE_temporalExpression) defer func() { p.ExitRule() @@ -5476,21 +4717,21 @@ func (p *CQL) TemporalExpression() (localctx ITemporalExpressionContext) { } }() - p.SetState(320) + p.SetState(286) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLIdentifier: p.EnterOuterAlt(localctx, 1) { - p.SetState(318) + p.SetState(284) p.PropertyName() } case CQLTemporalLiteral: p.EnterOuterAlt(localctx, 2) { - p.SetState(319) + p.SetState(285) p.TemporalLiteral() } @@ -5565,7 +4806,7 @@ func (s *TemporalLiteralContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) TemporalLiteral() (localctx ITemporalLiteralContext) { localctx = NewTemporalLiteralContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 80, CQLRULE_temporalLiteral) + p.EnterRule(localctx, 64, CQLRULE_temporalLiteral) defer func() { p.ExitRule() @@ -5585,7 +4826,7 @@ func (p *CQL) TemporalLiteral() (localctx ITemporalLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(322) + p.SetState(288) p.Match(CQLTemporalLiteral) } @@ -5732,7 +4973,7 @@ func (s *InPredicateContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) InPredicate() (localctx IInPredicateContext) { localctx = NewInPredicateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 82, CQLRULE_inPredicate) + p.EnterRule(localctx, 66, CQLRULE_inPredicate) var _la int defer func() { @@ -5753,76 +4994,76 @@ func (p *CQL) InPredicate() (localctx IInPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(324) + p.SetState(290) p.PropertyName() } - p.SetState(326) + p.SetState(292) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(325) + p.SetState(291) p.Match(CQLNOT) } } { - p.SetState(328) + p.SetState(294) p.Match(CQLIN) } { - p.SetState(329) + p.SetState(295) p.Match(CQLLEFTPAREN) } - p.SetState(346) + p.SetState(312) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLCharacterStringLiteral: { - p.SetState(330) + p.SetState(296) p.CharacterLiteral() } - p.SetState(335) + p.SetState(301) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(331) + p.SetState(297) p.Match(CQLCOMMA) } { - p.SetState(332) + p.SetState(298) p.CharacterLiteral() } - p.SetState(337) + p.SetState(303) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } case CQLNumericLiteral: { - p.SetState(338) + p.SetState(304) p.NumericLiteral() } - p.SetState(343) + p.SetState(309) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(339) + p.SetState(305) p.Match(CQLCOMMA) } { - p.SetState(340) + p.SetState(306) p.NumericLiteral() } - p.SetState(345) + p.SetState(311) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } @@ -5831,7 +5072,7 @@ func (p *CQL) InPredicate() (localctx IInPredicateContext) { panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) } { - p.SetState(348) + p.SetState(314) p.Match(CQLRIGHTPAREN) } diff --git a/internal/cql/cql_test.go b/internal/cql/cql_test.go index d74df808..53328d8c 100644 --- a/internal/cql/cql_test.go +++ b/internal/cql/cql_test.go @@ -49,6 +49,47 @@ func TestPredicate(t *testing.T) { checkCQL(t, "id IS NULL", "\"id\" IS NULL") checkCQL(t, "id IS NOT NULL", "\"id\" IS NOT NULL") } +func TestSpatialPredicate(t *testing.T) { + checkCQL(t, "crosses(geom, POINT(0 0))", "ST_Crosses(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "Contains(geom, POINT(0 0))", "ST_Contains(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "DISJOINT(geom, POINT(0 0))", "ST_Disjoint(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "EQUALS(geom, POINT(0 0))", "ST_Equals(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "INTERSECTS(geom, POINT(0 0))", "ST_Intersects(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "OVERLAPS(geom, POINT(0 0))", "ST_Overlaps(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "TOUCHES(geom, POINT(0 0))", "ST_Touches(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "within(geom, POINT(0 0))", "ST_Within(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + + checkCQL(t, "Dwithin(geom, POINT(0 0), 100)", "ST_DWithin(\"geom\",'SRID=4326;POINT(0 0)'::geometry,100)") +} + +func TestGeometryLiteral(t *testing.T) { + checkCQL(t, "equals(geom, POINT(0 0))", + "ST_Equals(\"geom\",'SRID=4326;POINT(0 0)'::geometry)") + checkCQL(t, "equals(geom, LINESTRING(0 0, 1 1))", + "ST_Equals(\"geom\",'SRID=4326;LINESTRING(0 0,1 1)'::geometry)") + checkCQL(t, "equals(geom, POLYGON((0 0, 0 9, 9 0, 0 0)))", + "ST_Equals(\"geom\",'SRID=4326;POLYGON((0 0,0 9,9 0,0 0))'::geometry)") + checkCQL(t, "equals(geom, POLYGON((0 0, 0 9, 9 0, 0 0),(1 1, 1 8, 8 1, 1 1)))", + "ST_Equals(\"geom\",'SRID=4326;POLYGON((0 0,0 9,9 0,0 0),(1 1,1 8,8 1,1 1))'::geometry)") + checkCQL(t, "equals(geom, MULTIPOINT(0 0, 0 9))", + "ST_Equals(\"geom\",'SRID=4326;MULTIPOINT(0 0,0 9)'::geometry)") + checkCQL(t, "equals(geom, MULTILINESTRING((0 0, 1 1),(1 1, 2 2)))", + "ST_Equals(\"geom\",'SRID=4326;MULTILINESTRING((0 0,1 1),(1 1,2 2))'::geometry)") + checkCQL(t, "equals(geom, MULTIPOLYGON(((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))))", + "ST_Equals(\"geom\",'SRID=4326;MULTIPOLYGON(((1 4,4 1,1 1,1 4)),((1 9,4 9,1 6,1 9)))'::geometry)") + checkCQL(t, "equals(geom, GEOMETRYCOLLECTION(POLYGON((1 4, 4 1, 1 1, 1 4)),LINESTRING (3 3, 5 5), POINT (1 5)))", + "ST_Equals(\"geom\",'SRID=4326;GEOMETRYCOLLECTION(POLYGON((1 4,4 1,1 1,1 4)),LINESTRING(3 3,5 5),POINT(1 5))'::geometry)") + checkCQL(t, "equals(geom, ENVELOPE(1,2,3,4))", + "ST_Equals(\"geom\",ST_MakeEnvelope(1,2,3,4,4326))") +} + +func TestGeometryLiteralWithSRID(t *testing.T) { + checkCQLWithSRID(t, "equals(geom, POINT(0 0))", 1111, 2222, + "ST_Equals(\"geom\",ST_Transform('SRID=1111;POINT(0 0)'::geometry,2222))") + checkCQLWithSRID(t, "equals(geom, ENVELOPE(1,2,3,4))", 1111, 2222, + "ST_Equals(\"geom\",ST_Transform(ST_MakeEnvelope(1,2,3,4,1111),2222))") +} + func TestBooleanExpression(t *testing.T) { checkCQL(t, "x > 1 AND x < 9", "\"x\" > 1 AND \"x\" < 9") checkCQL(t, "x = 1 OR x = 2", "\"x\" = 1 OR \"x\" = 2") @@ -64,13 +105,25 @@ func TestErrors(t *testing.T) { } func checkCQL(t *testing.T, cqlStr string, sql string) { - actual, _ := TranspileToSQL(cqlStr) + actual, err := TranspileToSQL(cqlStr, 4326, 4326) + if err != nil { + fmt.Printf("%v\n", err) + } + actual = strings.TrimSpace(actual) + equals(t, sql, actual, "") +} + +func checkCQLWithSRID(t *testing.T, cqlStr string, filterSRID int, sourceSRID int, sql string) { + actual, err := TranspileToSQL(cqlStr, filterSRID, sourceSRID) + if err != nil { + fmt.Printf("%v\n", err) + } actual = strings.TrimSpace(actual) equals(t, sql, actual, "") } func checkCQLError(t *testing.T, cqlStr string) { - _, err := TranspileToSQL(cqlStr) + _, err := TranspileToSQL(cqlStr, 4326, 4326) isError(t, err, "") } diff --git a/internal/data/db_sql.go b/internal/data/db_sql.go index 9950fa44..877960bf 100644 --- a/internal/data/db_sql.go +++ b/internal/data/db_sql.go @@ -320,6 +320,7 @@ func sqlGeomFunction(fn *Function, args map[string]string, propCols []string, pa sqlArgs, argVals := sqlFunctionArgs(fn, args) sqlGeomCol := sqlGeomCol(fn.GeometryColumn, param) sqlPropCols := sqlColList(propCols, fn.Types, true) + //-- SRS of function output is unknown, so have to assume 4326 bboxFilter := sqlBBoxFilter(fn.GeometryColumn, SRID_4326, param.Bbox, param.BboxCrs) cqlFilter := sqlCqlFilter(param.FilterSql) sqlWhere := sqlWhere(bboxFilter, cqlFilter, "") diff --git a/internal/service/handler.go b/internal/service/handler.go index 9c9deaf8..755e8b5d 100644 --- a/internal/service/handler.go +++ b/internal/service/handler.go @@ -273,7 +273,7 @@ func handleCollectionItems(w http.ResponseWriter, r *http.Request) *appError { if tbl == nil { return appErrorNotFoundFmt(err1, api.ErrMsgCollectionNotFound, name) } - param, err := createQueryParams(&reqParam, tbl.Columns) + param, err := createQueryParams(&reqParam, tbl.Columns, tbl.Srid) if err != nil { return appErrorBadRequest(err, err.Error()) } @@ -356,7 +356,7 @@ func handleItem(w http.ResponseWriter, r *http.Request) *appError { if tbl == nil { return appErrorNotFoundFmt(err1, api.ErrMsgCollectionNotFound, name) } - param, err := createQueryParams(&reqParam, tbl.Columns) + param, err := createQueryParams(&reqParam, tbl.Columns, tbl.Srid) ctx := r.Context() switch format { @@ -586,7 +586,7 @@ func handleFunctionItems(w http.ResponseWriter, r *http.Request) *appError { if fn == nil && err == nil { return appErrorNotFoundFmt(err, api.ErrMsgFunctionNotFound, name) } - param, err := createQueryParams(&reqParam, fn.OutNames) + param, err := createQueryParams(&reqParam, fn.OutNames, data.SRID_4326) if err != nil { return appErrorBadRequest(err, err.Error()) } diff --git a/internal/service/param.go b/internal/service/param.go index 6a41b376..64765e56 100644 --- a/internal/service/param.go +++ b/internal/service/param.go @@ -78,6 +78,13 @@ func parseRequestParams(r *http.Request) (api.RequestParam, error) { // --- filter parameter param.Filter = parseString(paramValues, api.ParamFilter) + // --- filter-crs parameter + filterCrs, err := parseInt(paramValues, api.ParamFilterCrs, 0, 99999999, data.SRID_4326) + if err != nil { + return param, err + } + param.FilterCrs = filterCrs + // --- properties parameter props, err := parseProperties(paramValues) if err != nil { @@ -415,7 +422,7 @@ func parseFilter(paramMap map[string]string, colNameMap map[string]string) []*da } // createQueryParams applies any cross-parameter logic -func createQueryParams(param *api.RequestParam, colNames []string) (*data.QueryParam, error) { +func createQueryParams(param *api.RequestParam, colNames []string, sourceSRID int) (*data.QueryParam, error) { query := data.QueryParam{ Crs: param.Crs, Limit: param.Limit, @@ -445,7 +452,7 @@ func createQueryParams(param *api.RequestParam, colNames []string) (*data.QueryP } query.Columns = normalizePropNames(cols, colNames) //-- convert filter CQL - sql, err := cql.TranspileToSQL(param.Filter) + sql, err := cql.TranspileToSQL(param.Filter, param.FilterCrs, sourceSRID) if err != nil { return &query, err } diff --git a/testing/pgfs_test.md b/testing/pgfs_test.md index 195b95e5..25233332 100644 --- a/testing/pgfs_test.md +++ b/testing/pgfs_test.md @@ -1,4 +1,4 @@ -# pg_fetaureserv Test Queries +# pg_featureserv Test Queries ## CRS handling @@ -21,6 +21,33 @@ http://localhost:9000/collections/ne.admin_0_countries/items.json?properties=nam http://localhost:9000/collections/pgfs_test.test_crs/items.json?filter=NOT%20id%20In%20(1,2,3) ``` +### Spatial Operators +``` +http://localhost:9000/collections/ne.admin_0_countries/items.json?properties=name,pop_est&filter=INTERSECTS(geom, POINT(1 1)) + +http://localhost:9000/collections/ne.admin_0_countries/items.json?properties=name,pop_est&filter=INTERSECTS(geom, LineString(1 1, 2 2)) + +http://localhost:9000/collections/ne.admin_0_countries/items.html?properties=name,pop_est&filter=crosses(geom,%20LineString(-5 35,48 -20)) +``` + +### Distance Operators +``` +http://localhost:9000/collections/ne.admin_0_countries/items.html?properties=name,pop_est&filter=dwithin(geom,Point(0%2050),10) + +http://localhost:9000/collections/public.geonames/items.html?filter=dwithin(geom,Point(-100 40),0.5)&limit=1000 + +http://localhost:9000/collections/public.geonames/items.html?filter=dwithin(geom,Linestring(-100%2040,-98%2042),0.1)&limit=1000 +``` + +### Filter-Crs +``` +http://localhost:9000/collections/pgfs_test.test_crs/items.html?filter=DWITHIN(geom,POINT(-124.6 49.3),40000)&limit=100 + +http://localhost:9000/collections/pgfs_test.test_crs/items.html?filter=DWITHIN(geom,POINT(1000000 400000),60000)&filter-crs=3005&limit=100 + +http://localhost:9000/collections/pgfs_test.test_crs/items.html?filter=intersects(geom,%20ENVELOPE(1000000,400000,1100000,500000))&filter-crs=3005&limit=100 +``` + ### Functions ``` http://localhost:9000/functions/postgisftw.countries_name/items.json?name_prefix=C&filter=continent%20ILIKE%20%27%25america%27 From 1b1bd4886d90b73e8afcc6477fd1743c0f0ad119 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Mon, 28 Feb 2022 21:20:28 -0800 Subject: [PATCH 02/14] Add some doc --- FEATURES.md | 9 +++++++-- hugo/content/usage/cql.md | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/FEATURES.md b/FEATURES.md index 840c0df2..f6160f26 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -64,9 +64,11 @@ It includes [*OGC API - Features*](http://docs.opengeospatial.org/is/17-069r3/17 - [x] property names - [x] character literals - [x] numeric literals -- [x] spatial literals +- [x] geometry literals + - `POINT`,`LINESTRING`,`POLYGON`,`MULTIPOINT`,`MULTILINESTRING`,`MULTIPOLYGON`,`GEOMETRYCOLLECTION`,`ENVELOPE` - [ ] temporal literals -- [x] binary comparisons (`<`,`<=`,`>`,`>=`,`=`,`<>`) +- [x] binary comparisons + - `<`,`<=`,`>`,`>=`,`=`,`<>` - [x] `property [NOT] BETWEEN a AND B` - [x] `property [NOT] IN ( value-list )` - [x] `property [NOT] (LIKE | ILIKE) pattern` @@ -74,6 +76,9 @@ It includes [*OGC API - Features*](http://docs.opengeospatial.org/is/17-069r3/17 - [x] `property [NOT] IS NULL` - [x] boolean combinations (`AND`,`OR`,`NOT`) - [x] spatial predicates + - `INTERSECTS`,`DISJOINT`,`CONTAINS`,`WITHIN`,`EQUALS`,`CROSSES`,`OVERLAPS`,`TOUCHES` +- [x] distance predicate + - `DWITHIN` - [ ] temporal predicates - [ ] functions diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index 154243a9..d9e6b8f7 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -115,7 +115,7 @@ and **spatial predicates**. ### Geometry Literals Geometry literals use Well-Known Text (WKT) to describe -values for points, lines, polygons, and collections: +values for points, lines, polygons (with holes), and collections: ``` POINT (1 2) From c9d1101661d5b931daa4e8257ecd3c6a28db282e Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Mon, 28 Feb 2022 21:24:10 -0800 Subject: [PATCH 03/14] Fix CQL MultiPoint syntax --- hugo/content/usage/cql.md | 2 +- internal/cql/CQL.g4 | 6 +- internal/cql/cql_base_listener.go | 6 + internal/cql/cql_listener.go | 6 + internal/cql/cql_parser.go | 807 +++++++++++++++++------------- internal/cql/cql_test.go | 4 +- 6 files changed, 472 insertions(+), 359 deletions(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index d9e6b8f7..a2bbd471 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -122,7 +122,7 @@ POINT (1 2) LINESTRING(0 0, 1 1) POLYGON((0 0, 0 9, 9 0, 0 0)) POLYGON((0 0, 0 9, 9 0, 0 0),(1 1, 1 8, 8 1, 1 1)) -MULTIPOINT(0 0, 0 9) +MULTIPOINT((0 0), (0 9)) MULTILINESTRING((0 0, 1 1),(1 1, 2 2)) MULTIPOLYGON(((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))) GEOMETRYCOLLECTION(POLYGON((1 4, 4 1, 1 1, 1 4)),LINESTRING (3 3, 5 5), POINT (1 5)) diff --git a/internal/cql/CQL.g4 b/internal/cql/CQL.g4 index ee05e3b6..ad0009f3 100644 --- a/internal/cql/CQL.g4 +++ b/internal/cql/CQL.g4 @@ -113,7 +113,9 @@ geomLiteral: point | geometryCollection | envelope; -point : POINT LEFTPAREN coordinate RIGHTPAREN; +point : POINT pointList; + +pointList : LEFTPAREN coordinate RIGHTPAREN; linestring : LINESTRING coordList; @@ -123,7 +125,7 @@ polygon : POLYGON polygonDef; polygonDef : LEFTPAREN coordList (COMMA coordList)* RIGHTPAREN; -multiPoint : MULTIPOINT LEFTPAREN coordinate (COMMA coordinate)* RIGHTPAREN; +multiPoint : MULTIPOINT LEFTPAREN pointList (COMMA pointList)* RIGHTPAREN; multiLinestring : MULTILINESTRING LEFTPAREN coordList (COMMA coordList)* RIGHTPAREN; diff --git a/internal/cql/cql_base_listener.go b/internal/cql/cql_base_listener.go index aef0ac67..38db5653 100644 --- a/internal/cql/cql_base_listener.go +++ b/internal/cql/cql_base_listener.go @@ -140,6 +140,12 @@ func (s *BaseCQLListener) EnterPoint(ctx *PointContext) {} // ExitPoint is called when production point is exited. func (s *BaseCQLListener) ExitPoint(ctx *PointContext) {} +// EnterPointList is called when production pointList is entered. +func (s *BaseCQLListener) EnterPointList(ctx *PointListContext) {} + +// ExitPointList is called when production pointList is exited. +func (s *BaseCQLListener) ExitPointList(ctx *PointListContext) {} + // EnterLinestring is called when production linestring is entered. func (s *BaseCQLListener) EnterLinestring(ctx *LinestringContext) {} diff --git a/internal/cql/cql_listener.go b/internal/cql/cql_listener.go index 3bdb4a97..2c7de2ba 100644 --- a/internal/cql/cql_listener.go +++ b/internal/cql/cql_listener.go @@ -67,6 +67,9 @@ type CQLListener interface { // EnterPoint is called when entering the point production. EnterPoint(c *PointContext) + // EnterPointList is called when entering the pointList production. + EnterPointList(c *PointListContext) + // EnterLinestring is called when entering the linestring production. EnterLinestring(c *LinestringContext) @@ -169,6 +172,9 @@ type CQLListener interface { // ExitPoint is called when exiting the point production. ExitPoint(c *PointContext) + // ExitPointList is called when exiting the pointList production. + ExitPointList(c *PointListContext) + // ExitLinestring is called when exiting the linestring production. ExitLinestring(c *LinestringContext) diff --git a/internal/cql/cql_parser.go b/internal/cql/cql_parser.go index 96a6758b..29e9a3d0 100644 --- a/internal/cql/cql_parser.go +++ b/internal/cql/cql_parser.go @@ -15,141 +15,142 @@ var _ = reflect.Copy var _ = strconv.Itoa var parserATN = []uint16{ - 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 93, 319, + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 93, 323, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, - 9, 34, 4, 35, 9, 35, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 7, 3, 80, 10, 3, 12, 3, 14, 3, 83, 11, 3, 3, 4, 3, 4, 3, 4, 3, 4, 3, - 4, 3, 4, 7, 4, 91, 10, 4, 12, 4, 14, 4, 94, 11, 4, 3, 5, 5, 5, 97, 10, - 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 106, 10, 6, 3, 7, 3, - 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 115, 10, 7, 3, 8, 3, 8, 3, 8, 3, - 8, 3, 9, 3, 9, 5, 9, 123, 10, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 5, 10, - 130, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 5, - 11, 140, 10, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 148, - 10, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, - 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, - 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 176, 10, 19, 3, 20, - 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 186, 10, 20, 3, - 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, - 3, 23, 7, 23, 200, 10, 23, 12, 23, 14, 23, 203, 11, 23, 3, 23, 3, 23, 3, - 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 25, 7, 25, 214, 10, 25, 12, 25, - 14, 25, 217, 11, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 7, - 26, 226, 10, 26, 12, 26, 14, 26, 229, 11, 26, 3, 26, 3, 26, 3, 27, 3, 27, - 3, 27, 3, 27, 3, 27, 7, 27, 238, 10, 27, 12, 27, 14, 27, 241, 11, 27, 3, - 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 250, 10, 28, 12, 28, - 14, 28, 253, 11, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 7, - 29, 262, 10, 29, 12, 29, 14, 29, 265, 11, 29, 3, 29, 3, 29, 3, 30, 3, 30, - 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 3, 31, 3, - 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 5, 33, 289, 10, 33, - 3, 34, 3, 34, 3, 35, 3, 35, 5, 35, 295, 10, 35, 3, 35, 3, 35, 3, 35, 3, - 35, 3, 35, 7, 35, 302, 10, 35, 12, 35, 14, 35, 305, 11, 35, 3, 35, 3, 35, - 3, 35, 7, 35, 310, 10, 35, 12, 35, 14, 35, 313, 11, 35, 5, 35, 315, 10, - 35, 3, 35, 3, 35, 3, 35, 2, 4, 4, 6, 36, 2, 4, 6, 8, 10, 12, 14, 16, 18, - 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, - 56, 58, 60, 62, 64, 66, 68, 2, 4, 3, 2, 14, 15, 4, 2, 3, 3, 25, 25, 2, - 319, 2, 70, 3, 2, 2, 2, 4, 73, 3, 2, 2, 2, 6, 84, 3, 2, 2, 2, 8, 96, 3, - 2, 2, 2, 10, 105, 3, 2, 2, 2, 12, 114, 3, 2, 2, 2, 14, 116, 3, 2, 2, 2, - 16, 120, 3, 2, 2, 2, 18, 127, 3, 2, 2, 2, 20, 136, 3, 2, 2, 2, 22, 147, - 3, 2, 2, 2, 24, 149, 3, 2, 2, 2, 26, 151, 3, 2, 2, 2, 28, 153, 3, 2, 2, - 2, 30, 155, 3, 2, 2, 2, 32, 157, 3, 2, 2, 2, 34, 164, 3, 2, 2, 2, 36, 175, - 3, 2, 2, 2, 38, 185, 3, 2, 2, 2, 40, 187, 3, 2, 2, 2, 42, 192, 3, 2, 2, - 2, 44, 195, 3, 2, 2, 2, 46, 206, 3, 2, 2, 2, 48, 209, 3, 2, 2, 2, 50, 220, - 3, 2, 2, 2, 52, 232, 3, 2, 2, 2, 54, 244, 3, 2, 2, 2, 56, 256, 3, 2, 2, - 2, 58, 268, 3, 2, 2, 2, 60, 279, 3, 2, 2, 2, 62, 282, 3, 2, 2, 2, 64, 288, - 3, 2, 2, 2, 66, 290, 3, 2, 2, 2, 68, 292, 3, 2, 2, 2, 70, 71, 5, 4, 3, - 2, 71, 72, 7, 2, 2, 3, 72, 3, 3, 2, 2, 2, 73, 74, 8, 3, 1, 2, 74, 75, 5, - 6, 4, 2, 75, 81, 3, 2, 2, 2, 76, 77, 12, 3, 2, 2, 77, 78, 7, 12, 2, 2, - 78, 80, 5, 6, 4, 2, 79, 76, 3, 2, 2, 2, 80, 83, 3, 2, 2, 2, 81, 79, 3, - 2, 2, 2, 81, 82, 3, 2, 2, 2, 82, 5, 3, 2, 2, 2, 83, 81, 3, 2, 2, 2, 84, - 85, 8, 4, 1, 2, 85, 86, 5, 8, 5, 2, 86, 92, 3, 2, 2, 2, 87, 88, 12, 3, - 2, 2, 88, 89, 7, 11, 2, 2, 89, 91, 5, 8, 5, 2, 90, 87, 3, 2, 2, 2, 91, - 94, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 92, 93, 3, 2, 2, 2, 93, 7, 3, 2, 2, - 2, 94, 92, 3, 2, 2, 2, 95, 97, 7, 13, 2, 2, 96, 95, 3, 2, 2, 2, 96, 97, - 3, 2, 2, 2, 97, 98, 3, 2, 2, 2, 98, 99, 5, 10, 6, 2, 99, 9, 3, 2, 2, 2, - 100, 106, 5, 12, 7, 2, 101, 102, 7, 52, 2, 2, 102, 103, 5, 4, 3, 2, 103, - 104, 7, 53, 2, 2, 104, 106, 3, 2, 2, 2, 105, 100, 3, 2, 2, 2, 105, 101, - 3, 2, 2, 2, 106, 11, 3, 2, 2, 2, 107, 115, 5, 14, 8, 2, 108, 115, 5, 16, - 9, 2, 109, 115, 5, 18, 10, 2, 110, 115, 5, 20, 11, 2, 111, 115, 5, 68, - 35, 2, 112, 115, 5, 32, 17, 2, 113, 115, 5, 34, 18, 2, 114, 107, 3, 2, - 2, 2, 114, 108, 3, 2, 2, 2, 114, 109, 3, 2, 2, 2, 114, 110, 3, 2, 2, 2, - 114, 111, 3, 2, 2, 2, 114, 112, 3, 2, 2, 2, 114, 113, 3, 2, 2, 2, 115, - 13, 3, 2, 2, 2, 116, 117, 5, 22, 12, 2, 117, 118, 7, 3, 2, 2, 118, 119, - 5, 22, 12, 2, 119, 15, 3, 2, 2, 2, 120, 122, 5, 24, 13, 2, 121, 123, 7, - 13, 2, 2, 122, 121, 3, 2, 2, 2, 122, 123, 3, 2, 2, 2, 123, 124, 3, 2, 2, - 2, 124, 125, 9, 2, 2, 2, 125, 126, 5, 26, 14, 2, 126, 17, 3, 2, 2, 2, 127, - 129, 5, 24, 13, 2, 128, 130, 7, 13, 2, 2, 129, 128, 3, 2, 2, 2, 129, 130, - 3, 2, 2, 2, 130, 131, 3, 2, 2, 2, 131, 132, 7, 16, 2, 2, 132, 133, 5, 22, - 12, 2, 133, 134, 7, 11, 2, 2, 134, 135, 5, 22, 12, 2, 135, 19, 3, 2, 2, - 2, 136, 137, 5, 24, 13, 2, 137, 139, 7, 17, 2, 2, 138, 140, 7, 13, 2, 2, - 139, 138, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 141, 3, 2, 2, 2, 141, - 142, 7, 18, 2, 2, 142, 21, 3, 2, 2, 2, 143, 148, 5, 24, 13, 2, 144, 148, - 5, 26, 14, 2, 145, 148, 5, 28, 15, 2, 146, 148, 5, 30, 16, 2, 147, 143, - 3, 2, 2, 2, 147, 144, 3, 2, 2, 2, 147, 145, 3, 2, 2, 2, 147, 146, 3, 2, - 2, 2, 148, 23, 3, 2, 2, 2, 149, 150, 7, 40, 2, 2, 150, 25, 3, 2, 2, 2, - 151, 152, 7, 92, 2, 2, 152, 27, 3, 2, 2, 2, 153, 154, 7, 39, 2, 2, 154, - 29, 3, 2, 2, 2, 155, 156, 7, 10, 2, 2, 156, 31, 3, 2, 2, 2, 157, 158, 7, - 23, 2, 2, 158, 159, 7, 52, 2, 2, 159, 160, 5, 36, 19, 2, 160, 161, 7, 58, - 2, 2, 161, 162, 5, 36, 19, 2, 162, 163, 7, 53, 2, 2, 163, 33, 3, 2, 2, - 2, 164, 165, 7, 24, 2, 2, 165, 166, 7, 52, 2, 2, 166, 167, 5, 36, 19, 2, - 167, 168, 7, 58, 2, 2, 168, 169, 5, 36, 19, 2, 169, 170, 7, 58, 2, 2, 170, - 171, 7, 39, 2, 2, 171, 172, 7, 53, 2, 2, 172, 35, 3, 2, 2, 2, 173, 176, - 5, 24, 13, 2, 174, 176, 5, 38, 20, 2, 175, 173, 3, 2, 2, 2, 175, 174, 3, - 2, 2, 2, 176, 37, 3, 2, 2, 2, 177, 186, 5, 40, 21, 2, 178, 186, 5, 42, - 22, 2, 179, 186, 5, 46, 24, 2, 180, 186, 5, 50, 26, 2, 181, 186, 5, 52, - 27, 2, 182, 186, 5, 54, 28, 2, 183, 186, 5, 56, 29, 2, 184, 186, 5, 58, - 30, 2, 185, 177, 3, 2, 2, 2, 185, 178, 3, 2, 2, 2, 185, 179, 3, 2, 2, 2, - 185, 180, 3, 2, 2, 2, 185, 181, 3, 2, 2, 2, 185, 182, 3, 2, 2, 2, 185, - 183, 3, 2, 2, 2, 185, 184, 3, 2, 2, 2, 186, 39, 3, 2, 2, 2, 187, 188, 7, - 31, 2, 2, 188, 189, 7, 52, 2, 2, 189, 190, 5, 60, 31, 2, 190, 191, 7, 53, - 2, 2, 191, 41, 3, 2, 2, 2, 192, 193, 7, 32, 2, 2, 193, 194, 5, 44, 23, - 2, 194, 43, 3, 2, 2, 2, 195, 196, 7, 52, 2, 2, 196, 201, 5, 60, 31, 2, - 197, 198, 7, 58, 2, 2, 198, 200, 5, 60, 31, 2, 199, 197, 3, 2, 2, 2, 200, - 203, 3, 2, 2, 2, 201, 199, 3, 2, 2, 2, 201, 202, 3, 2, 2, 2, 202, 204, - 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 204, 205, 7, 53, 2, 2, 205, 45, 3, 2, - 2, 2, 206, 207, 7, 33, 2, 2, 207, 208, 5, 48, 25, 2, 208, 47, 3, 2, 2, - 2, 209, 210, 7, 52, 2, 2, 210, 215, 5, 44, 23, 2, 211, 212, 7, 58, 2, 2, - 212, 214, 5, 44, 23, 2, 213, 211, 3, 2, 2, 2, 214, 217, 3, 2, 2, 2, 215, - 213, 3, 2, 2, 2, 215, 216, 3, 2, 2, 2, 216, 218, 3, 2, 2, 2, 217, 215, - 3, 2, 2, 2, 218, 219, 7, 53, 2, 2, 219, 49, 3, 2, 2, 2, 220, 221, 7, 34, - 2, 2, 221, 222, 7, 52, 2, 2, 222, 227, 5, 60, 31, 2, 223, 224, 7, 58, 2, - 2, 224, 226, 5, 60, 31, 2, 225, 223, 3, 2, 2, 2, 226, 229, 3, 2, 2, 2, - 227, 225, 3, 2, 2, 2, 227, 228, 3, 2, 2, 2, 228, 230, 3, 2, 2, 2, 229, - 227, 3, 2, 2, 2, 230, 231, 7, 53, 2, 2, 231, 51, 3, 2, 2, 2, 232, 233, - 7, 35, 2, 2, 233, 234, 7, 52, 2, 2, 234, 239, 5, 44, 23, 2, 235, 236, 7, - 58, 2, 2, 236, 238, 5, 44, 23, 2, 237, 235, 3, 2, 2, 2, 238, 241, 3, 2, - 2, 2, 239, 237, 3, 2, 2, 2, 239, 240, 3, 2, 2, 2, 240, 242, 3, 2, 2, 2, - 241, 239, 3, 2, 2, 2, 242, 243, 7, 53, 2, 2, 243, 53, 3, 2, 2, 2, 244, - 245, 7, 36, 2, 2, 245, 246, 7, 52, 2, 2, 246, 251, 5, 48, 25, 2, 247, 248, - 7, 58, 2, 2, 248, 250, 5, 48, 25, 2, 249, 247, 3, 2, 2, 2, 250, 253, 3, - 2, 2, 2, 251, 249, 3, 2, 2, 2, 251, 252, 3, 2, 2, 2, 252, 254, 3, 2, 2, - 2, 253, 251, 3, 2, 2, 2, 254, 255, 7, 53, 2, 2, 255, 55, 3, 2, 2, 2, 256, - 257, 7, 37, 2, 2, 257, 258, 7, 52, 2, 2, 258, 263, 5, 38, 20, 2, 259, 260, - 7, 58, 2, 2, 260, 262, 5, 38, 20, 2, 261, 259, 3, 2, 2, 2, 262, 265, 3, - 2, 2, 2, 263, 261, 3, 2, 2, 2, 263, 264, 3, 2, 2, 2, 264, 266, 3, 2, 2, - 2, 265, 263, 3, 2, 2, 2, 266, 267, 7, 53, 2, 2, 267, 57, 3, 2, 2, 2, 268, - 269, 7, 38, 2, 2, 269, 270, 7, 52, 2, 2, 270, 271, 7, 39, 2, 2, 271, 272, - 7, 58, 2, 2, 272, 273, 7, 39, 2, 2, 273, 274, 7, 58, 2, 2, 274, 275, 7, - 39, 2, 2, 275, 276, 7, 58, 2, 2, 276, 277, 7, 39, 2, 2, 277, 278, 7, 53, - 2, 2, 278, 59, 3, 2, 2, 2, 279, 280, 7, 39, 2, 2, 280, 281, 7, 39, 2, 2, - 281, 61, 3, 2, 2, 2, 282, 283, 5, 64, 33, 2, 283, 284, 9, 3, 2, 2, 284, - 285, 5, 64, 33, 2, 285, 63, 3, 2, 2, 2, 286, 289, 5, 24, 13, 2, 287, 289, - 5, 66, 34, 2, 288, 286, 3, 2, 2, 2, 288, 287, 3, 2, 2, 2, 289, 65, 3, 2, - 2, 2, 290, 291, 7, 77, 2, 2, 291, 67, 3, 2, 2, 2, 292, 294, 5, 24, 13, - 2, 293, 295, 7, 13, 2, 2, 294, 293, 3, 2, 2, 2, 294, 295, 3, 2, 2, 2, 295, - 296, 3, 2, 2, 2, 296, 297, 7, 30, 2, 2, 297, 314, 7, 52, 2, 2, 298, 303, - 5, 26, 14, 2, 299, 300, 7, 58, 2, 2, 300, 302, 5, 26, 14, 2, 301, 299, - 3, 2, 2, 2, 302, 305, 3, 2, 2, 2, 303, 301, 3, 2, 2, 2, 303, 304, 3, 2, - 2, 2, 304, 315, 3, 2, 2, 2, 305, 303, 3, 2, 2, 2, 306, 311, 5, 28, 15, - 2, 307, 308, 7, 58, 2, 2, 308, 310, 5, 28, 15, 2, 309, 307, 3, 2, 2, 2, - 310, 313, 3, 2, 2, 2, 311, 309, 3, 2, 2, 2, 311, 312, 3, 2, 2, 2, 312, - 315, 3, 2, 2, 2, 313, 311, 3, 2, 2, 2, 314, 298, 3, 2, 2, 2, 314, 306, - 3, 2, 2, 2, 315, 316, 3, 2, 2, 2, 316, 317, 7, 53, 2, 2, 317, 69, 3, 2, - 2, 2, 24, 81, 92, 96, 105, 114, 122, 129, 139, 147, 175, 185, 201, 215, - 227, 239, 251, 263, 288, 294, 303, 311, 314, + 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 7, 3, 82, 10, 3, 12, 3, 14, 3, 85, 11, 3, 3, 4, 3, 4, + 3, 4, 3, 4, 3, 4, 3, 4, 7, 4, 93, 10, 4, 12, 4, 14, 4, 96, 11, 4, 3, 5, + 5, 5, 99, 10, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 108, 10, + 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 117, 10, 7, 3, 8, 3, + 8, 3, 8, 3, 8, 3, 9, 3, 9, 5, 9, 125, 10, 9, 3, 9, 3, 9, 3, 9, 3, 10, 3, + 10, 5, 10, 132, 10, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, + 3, 11, 5, 11, 142, 10, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 12, 5, + 12, 150, 10, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, + 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, + 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 19, 3, 19, 5, 19, 178, 10, 19, + 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 3, 20, 5, 20, 188, 10, + 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, + 3, 24, 3, 24, 3, 24, 3, 24, 7, 24, 204, 10, 24, 12, 24, 14, 24, 207, 11, + 24, 3, 24, 3, 24, 3, 25, 3, 25, 3, 25, 3, 26, 3, 26, 3, 26, 3, 26, 7, 26, + 218, 10, 26, 12, 26, 14, 26, 221, 11, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, + 27, 3, 27, 3, 27, 7, 27, 230, 10, 27, 12, 27, 14, 27, 233, 11, 27, 3, 27, + 3, 27, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 7, 28, 242, 10, 28, 12, 28, 14, + 28, 245, 11, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 7, 29, + 254, 10, 29, 12, 29, 14, 29, 257, 11, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, + 30, 3, 30, 3, 30, 7, 30, 266, 10, 30, 12, 30, 14, 30, 269, 11, 30, 3, 30, + 3, 30, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, 31, 3, + 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, + 5, 34, 293, 10, 34, 3, 35, 3, 35, 3, 36, 3, 36, 5, 36, 299, 10, 36, 3, + 36, 3, 36, 3, 36, 3, 36, 3, 36, 7, 36, 306, 10, 36, 12, 36, 14, 36, 309, + 11, 36, 3, 36, 3, 36, 3, 36, 7, 36, 314, 10, 36, 12, 36, 14, 36, 317, 11, + 36, 5, 36, 319, 10, 36, 3, 36, 3, 36, 3, 36, 2, 4, 4, 6, 37, 2, 4, 6, 8, + 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, + 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 2, 4, 3, 2, 14, 15, + 4, 2, 3, 3, 25, 25, 2, 322, 2, 72, 3, 2, 2, 2, 4, 75, 3, 2, 2, 2, 6, 86, + 3, 2, 2, 2, 8, 98, 3, 2, 2, 2, 10, 107, 3, 2, 2, 2, 12, 116, 3, 2, 2, 2, + 14, 118, 3, 2, 2, 2, 16, 122, 3, 2, 2, 2, 18, 129, 3, 2, 2, 2, 20, 138, + 3, 2, 2, 2, 22, 149, 3, 2, 2, 2, 24, 151, 3, 2, 2, 2, 26, 153, 3, 2, 2, + 2, 28, 155, 3, 2, 2, 2, 30, 157, 3, 2, 2, 2, 32, 159, 3, 2, 2, 2, 34, 166, + 3, 2, 2, 2, 36, 177, 3, 2, 2, 2, 38, 187, 3, 2, 2, 2, 40, 189, 3, 2, 2, + 2, 42, 192, 3, 2, 2, 2, 44, 196, 3, 2, 2, 2, 46, 199, 3, 2, 2, 2, 48, 210, + 3, 2, 2, 2, 50, 213, 3, 2, 2, 2, 52, 224, 3, 2, 2, 2, 54, 236, 3, 2, 2, + 2, 56, 248, 3, 2, 2, 2, 58, 260, 3, 2, 2, 2, 60, 272, 3, 2, 2, 2, 62, 283, + 3, 2, 2, 2, 64, 286, 3, 2, 2, 2, 66, 292, 3, 2, 2, 2, 68, 294, 3, 2, 2, + 2, 70, 296, 3, 2, 2, 2, 72, 73, 5, 4, 3, 2, 73, 74, 7, 2, 2, 3, 74, 3, + 3, 2, 2, 2, 75, 76, 8, 3, 1, 2, 76, 77, 5, 6, 4, 2, 77, 83, 3, 2, 2, 2, + 78, 79, 12, 3, 2, 2, 79, 80, 7, 12, 2, 2, 80, 82, 5, 6, 4, 2, 81, 78, 3, + 2, 2, 2, 82, 85, 3, 2, 2, 2, 83, 81, 3, 2, 2, 2, 83, 84, 3, 2, 2, 2, 84, + 5, 3, 2, 2, 2, 85, 83, 3, 2, 2, 2, 86, 87, 8, 4, 1, 2, 87, 88, 5, 8, 5, + 2, 88, 94, 3, 2, 2, 2, 89, 90, 12, 3, 2, 2, 90, 91, 7, 11, 2, 2, 91, 93, + 5, 8, 5, 2, 92, 89, 3, 2, 2, 2, 93, 96, 3, 2, 2, 2, 94, 92, 3, 2, 2, 2, + 94, 95, 3, 2, 2, 2, 95, 7, 3, 2, 2, 2, 96, 94, 3, 2, 2, 2, 97, 99, 7, 13, + 2, 2, 98, 97, 3, 2, 2, 2, 98, 99, 3, 2, 2, 2, 99, 100, 3, 2, 2, 2, 100, + 101, 5, 10, 6, 2, 101, 9, 3, 2, 2, 2, 102, 108, 5, 12, 7, 2, 103, 104, + 7, 52, 2, 2, 104, 105, 5, 4, 3, 2, 105, 106, 7, 53, 2, 2, 106, 108, 3, + 2, 2, 2, 107, 102, 3, 2, 2, 2, 107, 103, 3, 2, 2, 2, 108, 11, 3, 2, 2, + 2, 109, 117, 5, 14, 8, 2, 110, 117, 5, 16, 9, 2, 111, 117, 5, 18, 10, 2, + 112, 117, 5, 20, 11, 2, 113, 117, 5, 70, 36, 2, 114, 117, 5, 32, 17, 2, + 115, 117, 5, 34, 18, 2, 116, 109, 3, 2, 2, 2, 116, 110, 3, 2, 2, 2, 116, + 111, 3, 2, 2, 2, 116, 112, 3, 2, 2, 2, 116, 113, 3, 2, 2, 2, 116, 114, + 3, 2, 2, 2, 116, 115, 3, 2, 2, 2, 117, 13, 3, 2, 2, 2, 118, 119, 5, 22, + 12, 2, 119, 120, 7, 3, 2, 2, 120, 121, 5, 22, 12, 2, 121, 15, 3, 2, 2, + 2, 122, 124, 5, 24, 13, 2, 123, 125, 7, 13, 2, 2, 124, 123, 3, 2, 2, 2, + 124, 125, 3, 2, 2, 2, 125, 126, 3, 2, 2, 2, 126, 127, 9, 2, 2, 2, 127, + 128, 5, 26, 14, 2, 128, 17, 3, 2, 2, 2, 129, 131, 5, 24, 13, 2, 130, 132, + 7, 13, 2, 2, 131, 130, 3, 2, 2, 2, 131, 132, 3, 2, 2, 2, 132, 133, 3, 2, + 2, 2, 133, 134, 7, 16, 2, 2, 134, 135, 5, 22, 12, 2, 135, 136, 7, 11, 2, + 2, 136, 137, 5, 22, 12, 2, 137, 19, 3, 2, 2, 2, 138, 139, 5, 24, 13, 2, + 139, 141, 7, 17, 2, 2, 140, 142, 7, 13, 2, 2, 141, 140, 3, 2, 2, 2, 141, + 142, 3, 2, 2, 2, 142, 143, 3, 2, 2, 2, 143, 144, 7, 18, 2, 2, 144, 21, + 3, 2, 2, 2, 145, 150, 5, 24, 13, 2, 146, 150, 5, 26, 14, 2, 147, 150, 5, + 28, 15, 2, 148, 150, 5, 30, 16, 2, 149, 145, 3, 2, 2, 2, 149, 146, 3, 2, + 2, 2, 149, 147, 3, 2, 2, 2, 149, 148, 3, 2, 2, 2, 150, 23, 3, 2, 2, 2, + 151, 152, 7, 40, 2, 2, 152, 25, 3, 2, 2, 2, 153, 154, 7, 92, 2, 2, 154, + 27, 3, 2, 2, 2, 155, 156, 7, 39, 2, 2, 156, 29, 3, 2, 2, 2, 157, 158, 7, + 10, 2, 2, 158, 31, 3, 2, 2, 2, 159, 160, 7, 23, 2, 2, 160, 161, 7, 52, + 2, 2, 161, 162, 5, 36, 19, 2, 162, 163, 7, 58, 2, 2, 163, 164, 5, 36, 19, + 2, 164, 165, 7, 53, 2, 2, 165, 33, 3, 2, 2, 2, 166, 167, 7, 24, 2, 2, 167, + 168, 7, 52, 2, 2, 168, 169, 5, 36, 19, 2, 169, 170, 7, 58, 2, 2, 170, 171, + 5, 36, 19, 2, 171, 172, 7, 58, 2, 2, 172, 173, 7, 39, 2, 2, 173, 174, 7, + 53, 2, 2, 174, 35, 3, 2, 2, 2, 175, 178, 5, 24, 13, 2, 176, 178, 5, 38, + 20, 2, 177, 175, 3, 2, 2, 2, 177, 176, 3, 2, 2, 2, 178, 37, 3, 2, 2, 2, + 179, 188, 5, 40, 21, 2, 180, 188, 5, 44, 23, 2, 181, 188, 5, 48, 25, 2, + 182, 188, 5, 52, 27, 2, 183, 188, 5, 54, 28, 2, 184, 188, 5, 56, 29, 2, + 185, 188, 5, 58, 30, 2, 186, 188, 5, 60, 31, 2, 187, 179, 3, 2, 2, 2, 187, + 180, 3, 2, 2, 2, 187, 181, 3, 2, 2, 2, 187, 182, 3, 2, 2, 2, 187, 183, + 3, 2, 2, 2, 187, 184, 3, 2, 2, 2, 187, 185, 3, 2, 2, 2, 187, 186, 3, 2, + 2, 2, 188, 39, 3, 2, 2, 2, 189, 190, 7, 31, 2, 2, 190, 191, 5, 42, 22, + 2, 191, 41, 3, 2, 2, 2, 192, 193, 7, 52, 2, 2, 193, 194, 5, 62, 32, 2, + 194, 195, 7, 53, 2, 2, 195, 43, 3, 2, 2, 2, 196, 197, 7, 32, 2, 2, 197, + 198, 5, 46, 24, 2, 198, 45, 3, 2, 2, 2, 199, 200, 7, 52, 2, 2, 200, 205, + 5, 62, 32, 2, 201, 202, 7, 58, 2, 2, 202, 204, 5, 62, 32, 2, 203, 201, + 3, 2, 2, 2, 204, 207, 3, 2, 2, 2, 205, 203, 3, 2, 2, 2, 205, 206, 3, 2, + 2, 2, 206, 208, 3, 2, 2, 2, 207, 205, 3, 2, 2, 2, 208, 209, 7, 53, 2, 2, + 209, 47, 3, 2, 2, 2, 210, 211, 7, 33, 2, 2, 211, 212, 5, 50, 26, 2, 212, + 49, 3, 2, 2, 2, 213, 214, 7, 52, 2, 2, 214, 219, 5, 46, 24, 2, 215, 216, + 7, 58, 2, 2, 216, 218, 5, 46, 24, 2, 217, 215, 3, 2, 2, 2, 218, 221, 3, + 2, 2, 2, 219, 217, 3, 2, 2, 2, 219, 220, 3, 2, 2, 2, 220, 222, 3, 2, 2, + 2, 221, 219, 3, 2, 2, 2, 222, 223, 7, 53, 2, 2, 223, 51, 3, 2, 2, 2, 224, + 225, 7, 34, 2, 2, 225, 226, 7, 52, 2, 2, 226, 231, 5, 42, 22, 2, 227, 228, + 7, 58, 2, 2, 228, 230, 5, 42, 22, 2, 229, 227, 3, 2, 2, 2, 230, 233, 3, + 2, 2, 2, 231, 229, 3, 2, 2, 2, 231, 232, 3, 2, 2, 2, 232, 234, 3, 2, 2, + 2, 233, 231, 3, 2, 2, 2, 234, 235, 7, 53, 2, 2, 235, 53, 3, 2, 2, 2, 236, + 237, 7, 35, 2, 2, 237, 238, 7, 52, 2, 2, 238, 243, 5, 46, 24, 2, 239, 240, + 7, 58, 2, 2, 240, 242, 5, 46, 24, 2, 241, 239, 3, 2, 2, 2, 242, 245, 3, + 2, 2, 2, 243, 241, 3, 2, 2, 2, 243, 244, 3, 2, 2, 2, 244, 246, 3, 2, 2, + 2, 245, 243, 3, 2, 2, 2, 246, 247, 7, 53, 2, 2, 247, 55, 3, 2, 2, 2, 248, + 249, 7, 36, 2, 2, 249, 250, 7, 52, 2, 2, 250, 255, 5, 50, 26, 2, 251, 252, + 7, 58, 2, 2, 252, 254, 5, 50, 26, 2, 253, 251, 3, 2, 2, 2, 254, 257, 3, + 2, 2, 2, 255, 253, 3, 2, 2, 2, 255, 256, 3, 2, 2, 2, 256, 258, 3, 2, 2, + 2, 257, 255, 3, 2, 2, 2, 258, 259, 7, 53, 2, 2, 259, 57, 3, 2, 2, 2, 260, + 261, 7, 37, 2, 2, 261, 262, 7, 52, 2, 2, 262, 267, 5, 38, 20, 2, 263, 264, + 7, 58, 2, 2, 264, 266, 5, 38, 20, 2, 265, 263, 3, 2, 2, 2, 266, 269, 3, + 2, 2, 2, 267, 265, 3, 2, 2, 2, 267, 268, 3, 2, 2, 2, 268, 270, 3, 2, 2, + 2, 269, 267, 3, 2, 2, 2, 270, 271, 7, 53, 2, 2, 271, 59, 3, 2, 2, 2, 272, + 273, 7, 38, 2, 2, 273, 274, 7, 52, 2, 2, 274, 275, 7, 39, 2, 2, 275, 276, + 7, 58, 2, 2, 276, 277, 7, 39, 2, 2, 277, 278, 7, 58, 2, 2, 278, 279, 7, + 39, 2, 2, 279, 280, 7, 58, 2, 2, 280, 281, 7, 39, 2, 2, 281, 282, 7, 53, + 2, 2, 282, 61, 3, 2, 2, 2, 283, 284, 7, 39, 2, 2, 284, 285, 7, 39, 2, 2, + 285, 63, 3, 2, 2, 2, 286, 287, 5, 66, 34, 2, 287, 288, 9, 3, 2, 2, 288, + 289, 5, 66, 34, 2, 289, 65, 3, 2, 2, 2, 290, 293, 5, 24, 13, 2, 291, 293, + 5, 68, 35, 2, 292, 290, 3, 2, 2, 2, 292, 291, 3, 2, 2, 2, 293, 67, 3, 2, + 2, 2, 294, 295, 7, 77, 2, 2, 295, 69, 3, 2, 2, 2, 296, 298, 5, 24, 13, + 2, 297, 299, 7, 13, 2, 2, 298, 297, 3, 2, 2, 2, 298, 299, 3, 2, 2, 2, 299, + 300, 3, 2, 2, 2, 300, 301, 7, 30, 2, 2, 301, 318, 7, 52, 2, 2, 302, 307, + 5, 26, 14, 2, 303, 304, 7, 58, 2, 2, 304, 306, 5, 26, 14, 2, 305, 303, + 3, 2, 2, 2, 306, 309, 3, 2, 2, 2, 307, 305, 3, 2, 2, 2, 307, 308, 3, 2, + 2, 2, 308, 319, 3, 2, 2, 2, 309, 307, 3, 2, 2, 2, 310, 315, 5, 28, 15, + 2, 311, 312, 7, 58, 2, 2, 312, 314, 5, 28, 15, 2, 313, 311, 3, 2, 2, 2, + 314, 317, 3, 2, 2, 2, 315, 313, 3, 2, 2, 2, 315, 316, 3, 2, 2, 2, 316, + 319, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 318, 302, 3, 2, 2, 2, 318, 310, + 3, 2, 2, 2, 319, 320, 3, 2, 2, 2, 320, 321, 7, 53, 2, 2, 321, 71, 3, 2, + 2, 2, 24, 83, 94, 98, 107, 116, 124, 131, 141, 149, 177, 187, 205, 219, + 231, 243, 255, 267, 292, 298, 307, 315, 318, } var deserializer = antlr.NewATNDeserializer(nil) var deserializedATN = deserializer.DeserializeFromUInt16(parserATN) @@ -187,8 +188,8 @@ var ruleNames = []string{ "booleanPrimary", "predicate", "binaryComparisonPredicate", "likePredicate", "betweenPredicate", "isNullPredicate", "scalarExpression", "propertyName", "characterLiteral", "numericLiteral", "booleanLiteral", "spatialPredicate", - "distancePredicate", "geomExpression", "geomLiteral", "point", "linestring", - "coordList", "polygon", "polygonDef", "multiPoint", "multiLinestring", + "distancePredicate", "geomExpression", "geomLiteral", "point", "pointList", + "linestring", "coordList", "polygon", "polygonDef", "multiPoint", "multiLinestring", "multiPolygon", "geometryCollection", "envelope", "coordinate", "temporalPredicate", "temporalExpression", "temporalLiteral", "inPredicate", } @@ -336,20 +337,21 @@ const ( CQLRULE_geomExpression = 17 CQLRULE_geomLiteral = 18 CQLRULE_point = 19 - CQLRULE_linestring = 20 - CQLRULE_coordList = 21 - CQLRULE_polygon = 22 - CQLRULE_polygonDef = 23 - CQLRULE_multiPoint = 24 - CQLRULE_multiLinestring = 25 - CQLRULE_multiPolygon = 26 - CQLRULE_geometryCollection = 27 - CQLRULE_envelope = 28 - CQLRULE_coordinate = 29 - CQLRULE_temporalPredicate = 30 - CQLRULE_temporalExpression = 31 - CQLRULE_temporalLiteral = 32 - CQLRULE_inPredicate = 33 + CQLRULE_pointList = 20 + CQLRULE_linestring = 21 + CQLRULE_coordList = 22 + CQLRULE_polygon = 23 + CQLRULE_polygonDef = 24 + CQLRULE_multiPoint = 25 + CQLRULE_multiLinestring = 26 + CQLRULE_multiPolygon = 27 + CQLRULE_geometryCollection = 28 + CQLRULE_envelope = 29 + CQLRULE_coordinate = 30 + CQLRULE_temporalPredicate = 31 + CQLRULE_temporalExpression = 32 + CQLRULE_temporalLiteral = 33 + CQLRULE_inPredicate = 34 ) // ICqlFilterContext is an interface to support dynamic dispatch. @@ -446,11 +448,11 @@ func (p *CQL) CqlFilter() (localctx ICqlFilterContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(68) + p.SetState(70) p.booleanValueExpression(0) } { - p.SetState(69) + p.SetState(71) p.Match(CQLEOF) } @@ -572,12 +574,12 @@ func (p *CQL) booleanValueExpression(_p int) (localctx IBooleanValueExpressionCo p.EnterOuterAlt(localctx, 1) { - p.SetState(72) + p.SetState(74) p.booleanTerm(0) } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(79) + p.SetState(81) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) @@ -589,22 +591,22 @@ func (p *CQL) booleanValueExpression(_p int) (localctx IBooleanValueExpressionCo _prevctx = localctx localctx = NewBooleanValueExpressionContext(p, _parentctx, _parentState) p.PushNewRecursionContext(localctx, _startState, CQLRULE_booleanValueExpression) - p.SetState(74) + p.SetState(76) if !(p.Precpred(p.GetParserRuleContext(), 1)) { panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) } { - p.SetState(75) + p.SetState(77) p.Match(CQLOR) } { - p.SetState(76) + p.SetState(78) p.booleanTerm(0) } } - p.SetState(81) + p.SetState(83) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 0, p.GetParserRuleContext()) } @@ -727,12 +729,12 @@ func (p *CQL) booleanTerm(_p int) (localctx IBooleanTermContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(83) + p.SetState(85) p.BooleanFactor() } p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1)) - p.SetState(90) + p.SetState(92) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) @@ -744,22 +746,22 @@ func (p *CQL) booleanTerm(_p int) (localctx IBooleanTermContext) { _prevctx = localctx localctx = NewBooleanTermContext(p, _parentctx, _parentState) p.PushNewRecursionContext(localctx, _startState, CQLRULE_booleanTerm) - p.SetState(85) + p.SetState(87) if !(p.Precpred(p.GetParserRuleContext(), 1)) { panic(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 1)", "")) } { - p.SetState(86) + p.SetState(88) p.Match(CQLAND) } { - p.SetState(87) + p.SetState(89) p.BooleanFactor() } } - p.SetState(92) + p.SetState(94) p.GetErrorHandler().Sync(p) _alt = p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 1, p.GetParserRuleContext()) } @@ -861,19 +863,19 @@ func (p *CQL) BooleanFactor() (localctx IBooleanFactorContext) { }() p.EnterOuterAlt(localctx, 1) - p.SetState(94) + p.SetState(96) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(93) + p.SetState(95) p.Match(CQLNOT) } } { - p.SetState(96) + p.SetState(98) p.BooleanPrimary() } @@ -986,29 +988,29 @@ func (p *CQL) BooleanPrimary() (localctx IBooleanPrimaryContext) { } }() - p.SetState(103) + p.SetState(105) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLBooleanLiteral, CQLSpatialOperator, CQLDistanceOperator, CQLNumericLiteral, CQLIdentifier, CQLCharacterStringLiteral: p.EnterOuterAlt(localctx, 1) { - p.SetState(98) + p.SetState(100) p.Predicate() } case CQLLEFTPAREN: p.EnterOuterAlt(localctx, 2) { - p.SetState(99) + p.SetState(101) p.Match(CQLLEFTPAREN) } { - p.SetState(100) + p.SetState(102) p.booleanValueExpression(0) } { - p.SetState(101) + p.SetState(103) p.Match(CQLRIGHTPAREN) } @@ -1167,55 +1169,55 @@ func (p *CQL) Predicate() (localctx IPredicateContext) { } }() - p.SetState(112) + p.SetState(114) p.GetErrorHandler().Sync(p) switch p.GetInterpreter().AdaptivePredict(p.GetTokenStream(), 4, p.GetParserRuleContext()) { case 1: p.EnterOuterAlt(localctx, 1) { - p.SetState(105) + p.SetState(107) p.BinaryComparisonPredicate() } case 2: p.EnterOuterAlt(localctx, 2) { - p.SetState(106) + p.SetState(108) p.LikePredicate() } case 3: p.EnterOuterAlt(localctx, 3) { - p.SetState(107) + p.SetState(109) p.BetweenPredicate() } case 4: p.EnterOuterAlt(localctx, 4) { - p.SetState(108) + p.SetState(110) p.IsNullPredicate() } case 5: p.EnterOuterAlt(localctx, 5) { - p.SetState(109) + p.SetState(111) p.InPredicate() } case 6: p.EnterOuterAlt(localctx, 6) { - p.SetState(110) + p.SetState(112) p.SpatialPredicate() } case 7: p.EnterOuterAlt(localctx, 7) { - p.SetState(111) + p.SetState(113) p.DistancePredicate() } @@ -1331,15 +1333,15 @@ func (p *CQL) BinaryComparisonPredicate() (localctx IBinaryComparisonPredicateCo p.EnterOuterAlt(localctx, 1) { - p.SetState(114) + p.SetState(116) p.ScalarExpression() } { - p.SetState(115) + p.SetState(117) p.Match(CQLComparisonOperator) } { - p.SetState(116) + p.SetState(118) p.ScalarExpression() } @@ -1459,21 +1461,21 @@ func (p *CQL) LikePredicate() (localctx ILikePredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(118) + p.SetState(120) p.PropertyName() } - p.SetState(120) + p.SetState(122) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(119) + p.SetState(121) p.Match(CQLNOT) } } - p.SetState(122) + p.SetState(124) _la = p.GetTokenStream().LA(1) if !(_la == CQLLIKE || _la == CQLILIKE) { @@ -1483,7 +1485,7 @@ func (p *CQL) LikePredicate() (localctx ILikePredicateContext) { p.Consume() } { - p.SetState(123) + p.SetState(125) p.CharacterLiteral() } @@ -1616,34 +1618,34 @@ func (p *CQL) BetweenPredicate() (localctx IBetweenPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(125) + p.SetState(127) p.PropertyName() } - p.SetState(127) + p.SetState(129) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(126) + p.SetState(128) p.Match(CQLNOT) } } { - p.SetState(129) + p.SetState(131) p.Match(CQLBETWEEN) } { - p.SetState(130) + p.SetState(132) p.ScalarExpression() } { - p.SetState(131) + p.SetState(133) p.Match(CQLAND) } { - p.SetState(132) + p.SetState(134) p.ScalarExpression() } @@ -1753,26 +1755,26 @@ func (p *CQL) IsNullPredicate() (localctx IIsNullPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(134) + p.SetState(136) p.PropertyName() } { - p.SetState(135) + p.SetState(137) p.Match(CQLIS) } - p.SetState(137) + p.SetState(139) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(136) + p.SetState(138) p.Match(CQLNOT) } } { - p.SetState(139) + p.SetState(141) p.Match(CQLNULL) } @@ -1897,35 +1899,35 @@ func (p *CQL) ScalarExpression() (localctx IScalarExpressionContext) { } }() - p.SetState(145) + p.SetState(147) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLIdentifier: p.EnterOuterAlt(localctx, 1) { - p.SetState(141) + p.SetState(143) p.PropertyName() } case CQLCharacterStringLiteral: p.EnterOuterAlt(localctx, 2) { - p.SetState(142) + p.SetState(144) p.CharacterLiteral() } case CQLNumericLiteral: p.EnterOuterAlt(localctx, 3) { - p.SetState(143) + p.SetState(145) p.NumericLiteral() } case CQLBooleanLiteral: p.EnterOuterAlt(localctx, 4) { - p.SetState(144) + p.SetState(146) p.BooleanLiteral() } @@ -2020,7 +2022,7 @@ func (p *CQL) PropertyName() (localctx IPropertyNameContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(147) + p.SetState(149) p.Match(CQLIdentifier) } @@ -2111,7 +2113,7 @@ func (p *CQL) CharacterLiteral() (localctx ICharacterLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(149) + p.SetState(151) p.Match(CQLCharacterStringLiteral) } @@ -2202,7 +2204,7 @@ func (p *CQL) NumericLiteral() (localctx INumericLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(151) + p.SetState(153) p.Match(CQLNumericLiteral) } @@ -2293,7 +2295,7 @@ func (p *CQL) BooleanLiteral() (localctx IBooleanLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(153) + p.SetState(155) p.Match(CQLBooleanLiteral) } @@ -2419,27 +2421,27 @@ func (p *CQL) SpatialPredicate() (localctx ISpatialPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(155) + p.SetState(157) p.Match(CQLSpatialOperator) } { - p.SetState(156) + p.SetState(158) p.Match(CQLLEFTPAREN) } { - p.SetState(157) + p.SetState(159) p.GeomExpression() } { - p.SetState(158) + p.SetState(160) p.Match(CQLCOMMA) } { - p.SetState(159) + p.SetState(161) p.GeomExpression() } { - p.SetState(160) + p.SetState(162) p.Match(CQLRIGHTPAREN) } @@ -2573,35 +2575,35 @@ func (p *CQL) DistancePredicate() (localctx IDistancePredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(162) + p.SetState(164) p.Match(CQLDistanceOperator) } { - p.SetState(163) + p.SetState(165) p.Match(CQLLEFTPAREN) } { - p.SetState(164) + p.SetState(166) p.GeomExpression() } { - p.SetState(165) + p.SetState(167) p.Match(CQLCOMMA) } { - p.SetState(166) + p.SetState(168) p.GeomExpression() } { - p.SetState(167) + p.SetState(169) p.Match(CQLCOMMA) } { - p.SetState(168) + p.SetState(170) p.Match(CQLNumericLiteral) } { - p.SetState(169) + p.SetState(171) p.Match(CQLRIGHTPAREN) } @@ -2706,21 +2708,21 @@ func (p *CQL) GeomExpression() (localctx IGeomExpressionContext) { } }() - p.SetState(173) + p.SetState(175) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLIdentifier: p.EnterOuterAlt(localctx, 1) { - p.SetState(171) + p.SetState(173) p.PropertyName() } case CQLPOINT, CQLLINESTRING, CQLPOLYGON, CQLMULTIPOINT, CQLMULTILINESTRING, CQLMULTIPOLYGON, CQLGEOMETRYCOLLECTION, CQLENVELOPE: p.EnterOuterAlt(localctx, 2) { - p.SetState(172) + p.SetState(174) p.GeomLiteral() } @@ -2889,63 +2891,63 @@ func (p *CQL) GeomLiteral() (localctx IGeomLiteralContext) { } }() - p.SetState(183) + p.SetState(185) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLPOINT: p.EnterOuterAlt(localctx, 1) { - p.SetState(175) + p.SetState(177) p.Point() } case CQLLINESTRING: p.EnterOuterAlt(localctx, 2) { - p.SetState(176) + p.SetState(178) p.Linestring() } case CQLPOLYGON: p.EnterOuterAlt(localctx, 3) { - p.SetState(177) + p.SetState(179) p.Polygon() } case CQLMULTIPOINT: p.EnterOuterAlt(localctx, 4) { - p.SetState(178) + p.SetState(180) p.MultiPoint() } case CQLMULTILINESTRING: p.EnterOuterAlt(localctx, 5) { - p.SetState(179) + p.SetState(181) p.MultiLinestring() } case CQLMULTIPOLYGON: p.EnterOuterAlt(localctx, 6) { - p.SetState(180) + p.SetState(182) p.MultiPolygon() } case CQLGEOMETRYCOLLECTION: p.EnterOuterAlt(localctx, 7) { - p.SetState(181) + p.SetState(183) p.GeometryCollection() } case CQLENVELOPE: p.EnterOuterAlt(localctx, 8) { - p.SetState(182) + p.SetState(184) p.Envelope() } @@ -2998,22 +3000,14 @@ func (s *PointContext) POINT() antlr.TerminalNode { return s.GetToken(CQLPOINT, 0) } -func (s *PointContext) LEFTPAREN() antlr.TerminalNode { - return s.GetToken(CQLLEFTPAREN, 0) -} - -func (s *PointContext) Coordinate() ICoordinateContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordinateContext)(nil)).Elem(), 0) +func (s *PointContext) PointList() IPointListContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IPointListContext)(nil)).Elem(), 0) if t == nil { return nil } - return t.(ICoordinateContext) -} - -func (s *PointContext) RIGHTPAREN() antlr.TerminalNode { - return s.GetToken(CQLRIGHTPAREN, 0) + return t.(IPointListContext) } func (s *PointContext) GetRuleContext() antlr.RuleContext { @@ -3058,19 +3052,124 @@ func (p *CQL) Point() (localctx IPointContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(185) + p.SetState(187) p.Match(CQLPOINT) } { - p.SetState(186) + p.SetState(188) + p.PointList() + } + + return localctx +} + +// IPointListContext is an interface to support dynamic dispatch. +type IPointListContext interface { + antlr.ParserRuleContext + + // GetParser returns the parser. + GetParser() antlr.Parser + + // IsPointListContext differentiates from other interfaces. + IsPointListContext() +} + +type PointListContext struct { + *antlr.BaseParserRuleContext + parser antlr.Parser +} + +func NewEmptyPointListContext() *PointListContext { + var p = new(PointListContext) + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(nil, -1) + p.RuleIndex = CQLRULE_pointList + return p +} + +func (*PointListContext) IsPointListContext() {} + +func NewPointListContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PointListContext { + var p = new(PointListContext) + + p.BaseParserRuleContext = antlr.NewBaseParserRuleContext(parent, invokingState) + + p.parser = parser + p.RuleIndex = CQLRULE_pointList + + return p +} + +func (s *PointListContext) GetParser() antlr.Parser { return s.parser } + +func (s *PointListContext) LEFTPAREN() antlr.TerminalNode { + return s.GetToken(CQLLEFTPAREN, 0) +} + +func (s *PointListContext) Coordinate() ICoordinateContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordinateContext)(nil)).Elem(), 0) + + if t == nil { + return nil + } + + return t.(ICoordinateContext) +} + +func (s *PointListContext) RIGHTPAREN() antlr.TerminalNode { + return s.GetToken(CQLRIGHTPAREN, 0) +} + +func (s *PointListContext) GetRuleContext() antlr.RuleContext { + return s +} + +func (s *PointListContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string { + return antlr.TreesStringTree(s, ruleNames, recog) +} + +func (s *PointListContext) EnterRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CQLListener); ok { + listenerT.EnterPointList(s) + } +} + +func (s *PointListContext) ExitRule(listener antlr.ParseTreeListener) { + if listenerT, ok := listener.(CQLListener); ok { + listenerT.ExitPointList(s) + } +} + +func (p *CQL) PointList() (localctx IPointListContext) { + localctx = NewPointListContext(p, p.GetParserRuleContext(), p.GetState()) + p.EnterRule(localctx, 40, CQLRULE_pointList) + + defer func() { + p.ExitRule() + }() + + defer func() { + if err := recover(); err != nil { + if v, ok := err.(antlr.RecognitionException); ok { + localctx.SetException(v) + p.GetErrorHandler().ReportError(p, v) + p.GetErrorHandler().Recover(p, v) + } else { + panic(err) + } + } + }() + + p.EnterOuterAlt(localctx, 1) + { + p.SetState(190) p.Match(CQLLEFTPAREN) } { - p.SetState(187) + p.SetState(191) p.Coordinate() } { - p.SetState(188) + p.SetState(192) p.Match(CQLRIGHTPAREN) } @@ -3151,7 +3250,7 @@ func (s *LinestringContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Linestring() (localctx ILinestringContext) { localctx = NewLinestringContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 40, CQLRULE_linestring) + p.EnterRule(localctx, 42, CQLRULE_linestring) defer func() { p.ExitRule() @@ -3171,11 +3270,11 @@ func (p *CQL) Linestring() (localctx ILinestringContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(190) + p.SetState(194) p.Match(CQLLINESTRING) } { - p.SetState(191) + p.SetState(195) p.CoordList() } @@ -3281,7 +3380,7 @@ func (s *CoordListContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) CoordList() (localctx ICoordListContext) { localctx = NewCoordListContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 42, CQLRULE_coordList) + p.EnterRule(localctx, 44, CQLRULE_coordList) var _la int defer func() { @@ -3302,33 +3401,33 @@ func (p *CQL) CoordList() (localctx ICoordListContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(193) + p.SetState(197) p.Match(CQLLEFTPAREN) } { - p.SetState(194) + p.SetState(198) p.Coordinate() } - p.SetState(199) + p.SetState(203) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(195) + p.SetState(199) p.Match(CQLCOMMA) } { - p.SetState(196) + p.SetState(200) p.Coordinate() } - p.SetState(201) + p.SetState(205) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(202) + p.SetState(206) p.Match(CQLRIGHTPAREN) } @@ -3409,7 +3508,7 @@ func (s *PolygonContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Polygon() (localctx IPolygonContext) { localctx = NewPolygonContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 44, CQLRULE_polygon) + p.EnterRule(localctx, 46, CQLRULE_polygon) defer func() { p.ExitRule() @@ -3429,11 +3528,11 @@ func (p *CQL) Polygon() (localctx IPolygonContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(204) + p.SetState(208) p.Match(CQLPOLYGON) } { - p.SetState(205) + p.SetState(209) p.PolygonDef() } @@ -3539,7 +3638,7 @@ func (s *PolygonDefContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) PolygonDef() (localctx IPolygonDefContext) { localctx = NewPolygonDefContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 46, CQLRULE_polygonDef) + p.EnterRule(localctx, 48, CQLRULE_polygonDef) var _la int defer func() { @@ -3560,33 +3659,33 @@ func (p *CQL) PolygonDef() (localctx IPolygonDefContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(207) + p.SetState(211) p.Match(CQLLEFTPAREN) } { - p.SetState(208) + p.SetState(212) p.CoordList() } - p.SetState(213) + p.SetState(217) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(209) + p.SetState(213) p.Match(CQLCOMMA) } { - p.SetState(210) + p.SetState(214) p.CoordList() } - p.SetState(215) + p.SetState(219) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(216) + p.SetState(220) p.Match(CQLRIGHTPAREN) } @@ -3639,27 +3738,27 @@ func (s *MultiPointContext) LEFTPAREN() antlr.TerminalNode { return s.GetToken(CQLLEFTPAREN, 0) } -func (s *MultiPointContext) AllCoordinate() []ICoordinateContext { - var ts = s.GetTypedRuleContexts(reflect.TypeOf((*ICoordinateContext)(nil)).Elem()) - var tst = make([]ICoordinateContext, len(ts)) +func (s *MultiPointContext) AllPointList() []IPointListContext { + var ts = s.GetTypedRuleContexts(reflect.TypeOf((*IPointListContext)(nil)).Elem()) + var tst = make([]IPointListContext, len(ts)) for i, t := range ts { if t != nil { - tst[i] = t.(ICoordinateContext) + tst[i] = t.(IPointListContext) } } return tst } -func (s *MultiPointContext) Coordinate(i int) ICoordinateContext { - var t = s.GetTypedRuleContext(reflect.TypeOf((*ICoordinateContext)(nil)).Elem(), i) +func (s *MultiPointContext) PointList(i int) IPointListContext { + var t = s.GetTypedRuleContext(reflect.TypeOf((*IPointListContext)(nil)).Elem(), i) if t == nil { return nil } - return t.(ICoordinateContext) + return t.(IPointListContext) } func (s *MultiPointContext) RIGHTPAREN() antlr.TerminalNode { @@ -3696,7 +3795,7 @@ func (s *MultiPointContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) MultiPoint() (localctx IMultiPointContext) { localctx = NewMultiPointContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 48, CQLRULE_multiPoint) + p.EnterRule(localctx, 50, CQLRULE_multiPoint) var _la int defer func() { @@ -3717,37 +3816,37 @@ func (p *CQL) MultiPoint() (localctx IMultiPointContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(218) + p.SetState(222) p.Match(CQLMULTIPOINT) } { - p.SetState(219) + p.SetState(223) p.Match(CQLLEFTPAREN) } { - p.SetState(220) - p.Coordinate() + p.SetState(224) + p.PointList() } - p.SetState(225) + p.SetState(229) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(221) + p.SetState(225) p.Match(CQLCOMMA) } { - p.SetState(222) - p.Coordinate() + p.SetState(226) + p.PointList() } - p.SetState(227) + p.SetState(231) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(228) + p.SetState(232) p.Match(CQLRIGHTPAREN) } @@ -3857,7 +3956,7 @@ func (s *MultiLinestringContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) MultiLinestring() (localctx IMultiLinestringContext) { localctx = NewMultiLinestringContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 50, CQLRULE_multiLinestring) + p.EnterRule(localctx, 52, CQLRULE_multiLinestring) var _la int defer func() { @@ -3878,37 +3977,37 @@ func (p *CQL) MultiLinestring() (localctx IMultiLinestringContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(230) + p.SetState(234) p.Match(CQLMULTILINESTRING) } { - p.SetState(231) + p.SetState(235) p.Match(CQLLEFTPAREN) } { - p.SetState(232) + p.SetState(236) p.CoordList() } - p.SetState(237) + p.SetState(241) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(233) + p.SetState(237) p.Match(CQLCOMMA) } { - p.SetState(234) + p.SetState(238) p.CoordList() } - p.SetState(239) + p.SetState(243) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(240) + p.SetState(244) p.Match(CQLRIGHTPAREN) } @@ -4018,7 +4117,7 @@ func (s *MultiPolygonContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) MultiPolygon() (localctx IMultiPolygonContext) { localctx = NewMultiPolygonContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 52, CQLRULE_multiPolygon) + p.EnterRule(localctx, 54, CQLRULE_multiPolygon) var _la int defer func() { @@ -4039,37 +4138,37 @@ func (p *CQL) MultiPolygon() (localctx IMultiPolygonContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(242) + p.SetState(246) p.Match(CQLMULTIPOLYGON) } { - p.SetState(243) + p.SetState(247) p.Match(CQLLEFTPAREN) } { - p.SetState(244) + p.SetState(248) p.PolygonDef() } - p.SetState(249) + p.SetState(253) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(245) + p.SetState(249) p.Match(CQLCOMMA) } { - p.SetState(246) + p.SetState(250) p.PolygonDef() } - p.SetState(251) + p.SetState(255) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(252) + p.SetState(256) p.Match(CQLRIGHTPAREN) } @@ -4179,7 +4278,7 @@ func (s *GeometryCollectionContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) GeometryCollection() (localctx IGeometryCollectionContext) { localctx = NewGeometryCollectionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 54, CQLRULE_geometryCollection) + p.EnterRule(localctx, 56, CQLRULE_geometryCollection) var _la int defer func() { @@ -4200,37 +4299,37 @@ func (p *CQL) GeometryCollection() (localctx IGeometryCollectionContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(254) + p.SetState(258) p.Match(CQLGEOMETRYCOLLECTION) } { - p.SetState(255) + p.SetState(259) p.Match(CQLLEFTPAREN) } { - p.SetState(256) + p.SetState(260) p.GeomLiteral() } - p.SetState(261) + p.SetState(265) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(257) + p.SetState(261) p.Match(CQLCOMMA) } { - p.SetState(258) + p.SetState(262) p.GeomLiteral() } - p.SetState(263) + p.SetState(267) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } { - p.SetState(264) + p.SetState(268) p.Match(CQLRIGHTPAREN) } @@ -4325,7 +4424,7 @@ func (s *EnvelopeContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Envelope() (localctx IEnvelopeContext) { localctx = NewEnvelopeContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 56, CQLRULE_envelope) + p.EnterRule(localctx, 58, CQLRULE_envelope) defer func() { p.ExitRule() @@ -4345,43 +4444,43 @@ func (p *CQL) Envelope() (localctx IEnvelopeContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(266) + p.SetState(270) p.Match(CQLENVELOPE) } { - p.SetState(267) + p.SetState(271) p.Match(CQLLEFTPAREN) } { - p.SetState(268) + p.SetState(272) p.Match(CQLNumericLiteral) } { - p.SetState(269) + p.SetState(273) p.Match(CQLCOMMA) } { - p.SetState(270) + p.SetState(274) p.Match(CQLNumericLiteral) } { - p.SetState(271) + p.SetState(275) p.Match(CQLCOMMA) } { - p.SetState(272) + p.SetState(276) p.Match(CQLNumericLiteral) } { - p.SetState(273) + p.SetState(277) p.Match(CQLCOMMA) } { - p.SetState(274) + p.SetState(278) p.Match(CQLNumericLiteral) } { - p.SetState(275) + p.SetState(279) p.Match(CQLRIGHTPAREN) } @@ -4456,7 +4555,7 @@ func (s *CoordinateContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) Coordinate() (localctx ICoordinateContext) { localctx = NewCoordinateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 58, CQLRULE_coordinate) + p.EnterRule(localctx, 60, CQLRULE_coordinate) defer func() { p.ExitRule() @@ -4476,11 +4575,11 @@ func (p *CQL) Coordinate() (localctx ICoordinateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(277) + p.SetState(281) p.Match(CQLNumericLiteral) } { - p.SetState(278) + p.SetState(282) p.Match(CQLNumericLiteral) } @@ -4578,7 +4677,7 @@ func (s *TemporalPredicateContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) TemporalPredicate() (localctx ITemporalPredicateContext) { localctx = NewTemporalPredicateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 60, CQLRULE_temporalPredicate) + p.EnterRule(localctx, 62, CQLRULE_temporalPredicate) var _la int defer func() { @@ -4599,10 +4698,10 @@ func (p *CQL) TemporalPredicate() (localctx ITemporalPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(280) + p.SetState(284) p.TemporalExpression() } - p.SetState(281) + p.SetState(285) _la = p.GetTokenStream().LA(1) if !(_la == CQLComparisonOperator || _la == CQLTemporalOperator) { @@ -4612,7 +4711,7 @@ func (p *CQL) TemporalPredicate() (localctx ITemporalPredicateContext) { p.Consume() } { - p.SetState(282) + p.SetState(286) p.TemporalExpression() } @@ -4699,7 +4798,7 @@ func (s *TemporalExpressionContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) TemporalExpression() (localctx ITemporalExpressionContext) { localctx = NewTemporalExpressionContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 62, CQLRULE_temporalExpression) + p.EnterRule(localctx, 64, CQLRULE_temporalExpression) defer func() { p.ExitRule() @@ -4717,21 +4816,21 @@ func (p *CQL) TemporalExpression() (localctx ITemporalExpressionContext) { } }() - p.SetState(286) + p.SetState(290) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLIdentifier: p.EnterOuterAlt(localctx, 1) { - p.SetState(284) + p.SetState(288) p.PropertyName() } case CQLTemporalLiteral: p.EnterOuterAlt(localctx, 2) { - p.SetState(285) + p.SetState(289) p.TemporalLiteral() } @@ -4806,7 +4905,7 @@ func (s *TemporalLiteralContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) TemporalLiteral() (localctx ITemporalLiteralContext) { localctx = NewTemporalLiteralContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 64, CQLRULE_temporalLiteral) + p.EnterRule(localctx, 66, CQLRULE_temporalLiteral) defer func() { p.ExitRule() @@ -4826,7 +4925,7 @@ func (p *CQL) TemporalLiteral() (localctx ITemporalLiteralContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(288) + p.SetState(292) p.Match(CQLTemporalLiteral) } @@ -4973,7 +5072,7 @@ func (s *InPredicateContext) ExitRule(listener antlr.ParseTreeListener) { func (p *CQL) InPredicate() (localctx IInPredicateContext) { localctx = NewInPredicateContext(p, p.GetParserRuleContext(), p.GetState()) - p.EnterRule(localctx, 66, CQLRULE_inPredicate) + p.EnterRule(localctx, 68, CQLRULE_inPredicate) var _la int defer func() { @@ -4994,76 +5093,76 @@ func (p *CQL) InPredicate() (localctx IInPredicateContext) { p.EnterOuterAlt(localctx, 1) { - p.SetState(290) + p.SetState(294) p.PropertyName() } - p.SetState(292) + p.SetState(296) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) if _la == CQLNOT { { - p.SetState(291) + p.SetState(295) p.Match(CQLNOT) } } { - p.SetState(294) + p.SetState(298) p.Match(CQLIN) } { - p.SetState(295) + p.SetState(299) p.Match(CQLLEFTPAREN) } - p.SetState(312) + p.SetState(316) p.GetErrorHandler().Sync(p) switch p.GetTokenStream().LA(1) { case CQLCharacterStringLiteral: { - p.SetState(296) + p.SetState(300) p.CharacterLiteral() } - p.SetState(301) + p.SetState(305) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(297) + p.SetState(301) p.Match(CQLCOMMA) } { - p.SetState(298) + p.SetState(302) p.CharacterLiteral() } - p.SetState(303) + p.SetState(307) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } case CQLNumericLiteral: { - p.SetState(304) + p.SetState(308) p.NumericLiteral() } - p.SetState(309) + p.SetState(313) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) for _la == CQLCOMMA { { - p.SetState(305) + p.SetState(309) p.Match(CQLCOMMA) } { - p.SetState(306) + p.SetState(310) p.NumericLiteral() } - p.SetState(311) + p.SetState(315) p.GetErrorHandler().Sync(p) _la = p.GetTokenStream().LA(1) } @@ -5072,7 +5171,7 @@ func (p *CQL) InPredicate() (localctx IInPredicateContext) { panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) } { - p.SetState(314) + p.SetState(318) p.Match(CQLRIGHTPAREN) } diff --git a/internal/cql/cql_test.go b/internal/cql/cql_test.go index 53328d8c..08c22e85 100644 --- a/internal/cql/cql_test.go +++ b/internal/cql/cql_test.go @@ -71,8 +71,8 @@ func TestGeometryLiteral(t *testing.T) { "ST_Equals(\"geom\",'SRID=4326;POLYGON((0 0,0 9,9 0,0 0))'::geometry)") checkCQL(t, "equals(geom, POLYGON((0 0, 0 9, 9 0, 0 0),(1 1, 1 8, 8 1, 1 1)))", "ST_Equals(\"geom\",'SRID=4326;POLYGON((0 0,0 9,9 0,0 0),(1 1,1 8,8 1,1 1))'::geometry)") - checkCQL(t, "equals(geom, MULTIPOINT(0 0, 0 9))", - "ST_Equals(\"geom\",'SRID=4326;MULTIPOINT(0 0,0 9)'::geometry)") + checkCQL(t, "equals(geom, MULTIPOINT((0 0), (0 9)))", + "ST_Equals(\"geom\",'SRID=4326;MULTIPOINT((0 0),(0 9))'::geometry)") checkCQL(t, "equals(geom, MULTILINESTRING((0 0, 1 1),(1 1, 2 2)))", "ST_Equals(\"geom\",'SRID=4326;MULTILINESTRING((0 0,1 1),(1 1,2 2))'::geometry)") checkCQL(t, "equals(geom, MULTIPOLYGON(((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))))", From 301055709e54e62818dd9fb8057fb8d30814ea51 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Mon, 28 Feb 2022 21:31:14 -0800 Subject: [PATCH 04/14] Doc formatting --- hugo/content/usage/cql.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index a2bbd471..6c9683ad 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -119,18 +119,18 @@ values for points, lines, polygons (with holes), and collections: ``` POINT (1 2) -LINESTRING(0 0, 1 1) -POLYGON((0 0, 0 9, 9 0, 0 0)) -POLYGON((0 0, 0 9, 9 0, 0 0),(1 1, 1 8, 8 1, 1 1)) -MULTIPOINT((0 0), (0 9)) -MULTILINESTRING((0 0, 1 1),(1 1, 2 2)) -MULTIPOLYGON(((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))) -GEOMETRYCOLLECTION(POLYGON((1 4, 4 1, 1 1, 1 4)),LINESTRING (3 3, 5 5), POINT (1 5)) +LINESTRING (0 0, 1 1) +POLYGON ((0 0, 0 9, 9 0, 0 0)) +POLYGON ((0 0, 0 9, 9 0, 0 0),(1 1, 1 8, 8 1, 1 1)) +MULTIPOINT ((0 0), (0 9)) +MULTILINESTRING ((0 0, 1 1),(1 1, 2 2)) +MULTIPOLYGON (((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))) +GEOMETRYCOLLECTION(POLYGON ((1 4, 4 1, 1 1, 1 4)), LINESTRING (3 3, 5 5), POINT (1 5)) ``` CQL also provides a syntax for concisely defining a rectangular polygon: ``` -ENVELOPE(1, 2, 3, 4) +ENVELOPE (1, 2, 3, 4) ``` By default the coordinate system of geometry literal values is assumed to be geodetic (SRID = 4326). From 7d6de784de9d6ca05f0eb845a2316a61c4dfae92 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Mon, 28 Feb 2022 21:32:55 -0800 Subject: [PATCH 05/14] Improve doc for CQL --- hugo/content/usage/cql.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index 6c9683ad..bdf1d0d7 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -11,7 +11,8 @@ the [Common Query Language](https://portal.ogc.org/files/96288) (CQL). CQL expressions return a value of `true` or `false`. Only features which evaluate to `true` are returned. In `pg_featureserv` the filter expression is evaluated by the database, -so it can take advantage of indexes to make filter evaluation very efficient. +so it can take advantage of indexes (standard and spatial) +to make filter evaluation very efficient. This section describes the CQL query language subset supported by `pg_featureserv`. @@ -169,6 +170,3 @@ The `DWITHIN` predicate allows testing whether a geometry lies within a given di ``` filter=DWITHIN(geom, POINT(-100 49), 0.1) ``` - -Note that if a spatial index is defined on the table being queried, -PostGIS will use it to evaluate spatial conditions very efficiently. From 10ae3d7c7097b7a288304fc3dd23621f9224c3b6 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 10:29:45 -0800 Subject: [PATCH 06/14] Minor improvements --- internal/cql/cql.go | 105 ++++++++++++++++++++------------------- internal/cql/cql_test.go | 6 ++- 2 files changed, 58 insertions(+), 53 deletions(-) diff --git a/internal/cql/cql.go b/internal/cql/cql.go index c3549ac3..966cb4cf 100644 --- a/internal/cql/cql.go +++ b/internal/cql/cql.go @@ -101,8 +101,8 @@ type cqlListener struct { filterSRID int // SRID for source CRS sourceSRID int - // SQL strings for nodes - result map[*antlr.BaseRuleContext]string + // SQL fragments for parse tree nodes + sqlFrags map[*antlr.BaseRuleContext]string // result SQL sql string } @@ -111,37 +111,38 @@ func NewCqlListener(filterSRID int, sourceSRID int) *cqlListener { this := new(cqlListener) this.filterSRID = filterSRID this.sourceSRID = sourceSRID - this.result = make(map[*antlr.BaseRuleContext]string) + this.sqlFrags = make(map[*antlr.BaseRuleContext]string) return this } func (l *cqlListener) GetSQL() string { return l.sql } +// saveSql stores the SQL fragment for a parse tree node in the map +func (l *cqlListener) saveSql(ctx antlr.ParserRuleContext, sql string) { + l.sqlFrags[ctx.GetBaseRuleContext()] = sql +} + // helper function to avoid nil pointer problems -func (l *cqlListener) sqlFrag(ctx antlr.ParserRuleContext) string { +func (l *cqlListener) sqlFor(ctx antlr.ParserRuleContext) string { if ctx == nil { return "" } - frag := l.result[ctx.GetBaseRuleContext()] + frag := l.sqlFrags[ctx.GetBaseRuleContext()] //log.Debug("sqlFrag for " + ctx.GetText() + " -> " + frag) return frag } -func (l *cqlListener) saveFrag(ctx antlr.ParserRuleContext, sql string) { - l.result[ctx.GetBaseRuleContext()] = sql -} - func (l *cqlListener) sqlGeometryLiteral(wkt string) string { sql := fmt.Sprintf("'SRID=%d;%s'::geometry", l.filterSRID, wkt) return sql } -func (l *cqlListener) sqlEnvelopeLiteral(b1 string, b2 string, b3 string, b4 string) string { - return fmt.Sprintf("ST_MakeEnvelope(%s,%s,%s,%s,%d)", b1, b2, b3, b4, l.filterSRID) +func (l *cqlListener) sqlEnvelopeLiteral(xmin string, ymin string, xmax string, ymax string) string { + return fmt.Sprintf("ST_MakeEnvelope(%s,%s,%s,%s,%d)", xmin, ymin, xmax, ymax, l.filterSRID) } -func (l *cqlListener) sqlTransform(sql string) string { +func (l *cqlListener) sqlTransformCrs(sql string) string { if l.sourceSRID == l.filterSRID { return sql } @@ -171,71 +172,71 @@ func (l *cqlListener) EnterEveryRule(ctx antlr.ParserRuleContext) { */ func (l *cqlListener) ExitCqlFilter(ctx *CqlFilterContext) { - l.sql = l.sqlFrag(ctx.BooleanValueExpression()) + l.sql = l.sqlFor(ctx.BooleanValueExpression()) } func (l *cqlListener) ExitBooleanValueExpression(ctx *BooleanValueExpressionContext) { - sql := l.sqlFrag(ctx.BooleanTerm()) + sql := l.sqlFor(ctx.BooleanTerm()) if ctx.OR() != nil { - expr := l.sqlFrag(ctx.BooleanValueExpression()) + expr := l.sqlFor(ctx.BooleanValueExpression()) sql = expr + " OR " + sql } - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitBooleanTerm(ctx *BooleanTermContext) { - sql := l.sqlFrag(ctx.BooleanFactor()) + sql := l.sqlFor(ctx.BooleanFactor()) if ctx.AND() != nil { - expr := l.sqlFrag(ctx.BooleanTerm()) + expr := l.sqlFor(ctx.BooleanTerm()) sql = expr + " AND " + sql } - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitBooleanFactor(ctx *BooleanFactorContext) { - sql := l.sqlFrag(ctx.BooleanPrimary()) + sql := l.sqlFor(ctx.BooleanPrimary()) if ctx.NOT() != nil { sql = " NOT " + sql } - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitBooleanPrimary(ctx *BooleanPrimaryContext) { var sql string if ctx.LEFTPAREN() == nil { - sql = l.sqlFrag(ctx.Predicate()) + sql = l.sqlFor(ctx.Predicate()) } else { - sql = "(" + l.sqlFrag(ctx.BooleanValueExpression()) + ")" + sql = "(" + l.sqlFor(ctx.BooleanValueExpression()) + ")" } - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitPredicate(ctx *PredicateContext) { var sql string if ctx.BinaryComparisonPredicate() != nil { - sql = l.sqlFrag(ctx.BinaryComparisonPredicate()) + sql = l.sqlFor(ctx.BinaryComparisonPredicate()) } else if ctx.LikePredicate() != nil { - sql = l.sqlFrag(ctx.LikePredicate()) + sql = l.sqlFor(ctx.LikePredicate()) } else if ctx.BetweenPredicate() != nil { - sql = l.sqlFrag(ctx.BetweenPredicate()) + sql = l.sqlFor(ctx.BetweenPredicate()) } else if ctx.IsNullPredicate() != nil { - sql = l.sqlFrag(ctx.IsNullPredicate()) + sql = l.sqlFor(ctx.IsNullPredicate()) } else if ctx.InPredicate() != nil { - sql = l.sqlFrag(ctx.InPredicate()) + sql = l.sqlFor(ctx.InPredicate()) } else if ctx.SpatialPredicate() != nil { - sql = l.sqlFrag(ctx.SpatialPredicate()) + sql = l.sqlFor(ctx.SpatialPredicate()) } else if ctx.DistancePredicate() != nil { - sql = l.sqlFrag(ctx.DistancePredicate()) + sql = l.sqlFor(ctx.DistancePredicate()) } - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitBinaryComparisonPredicate(ctx *BinaryComparisonPredicateContext) { - expr1 := l.sqlFrag(ctx.ScalarExpression(0)) - expr2 := l.sqlFrag(ctx.ScalarExpression(1)) + expr1 := l.sqlFor(ctx.ScalarExpression(0)) + expr2 := l.sqlFor(ctx.ScalarExpression(1)) op := getNodeText(ctx.ComparisonOperator()) sql := expr1 + " " + op + " " + expr2 - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitScalarExpression(ctx *ScalarExpressionContext) { @@ -249,7 +250,7 @@ func (l *cqlListener) ExitScalarExpression(ctx *ScalarExpressionContext) { } else if ctx.BooleanLiteral() != nil { sql = getText(ctx.BooleanLiteral()) } - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitLikePredicate(ctx *LikePredicateContext) { @@ -264,7 +265,7 @@ func (l *cqlListener) ExitLikePredicate(ctx *LikePredicateContext) { } sb.WriteString(op) sb.WriteString(quotedText(getText(ctx.CharacterLiteral()))) - l.saveFrag(ctx, sb.String()) + l.saveSql(ctx, sb.String()) } func (l *cqlListener) ExitBetweenPredicate(ctx *BetweenPredicateContext) { @@ -273,10 +274,10 @@ func (l *cqlListener) ExitBetweenPredicate(ctx *BetweenPredicateContext) { if ctx.NOT() != nil { not = " NOT" } - expr1 := l.sqlFrag(ctx.ScalarExpression(0)) - expr2 := l.sqlFrag(ctx.ScalarExpression(1)) + expr1 := l.sqlFor(ctx.ScalarExpression(0)) + expr2 := l.sqlFor(ctx.ScalarExpression(1)) sql := " " + prop + not + " BETWEEN " + expr1 + " AND " + expr2 - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitIsNullPredicate(ctx *IsNullPredicateContext) { @@ -286,7 +287,7 @@ func (l *cqlListener) ExitIsNullPredicate(ctx *IsNullPredicateContext) { not = " NOT" } sql := " " + prop + " IS" + not + " NULL" - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func (l *cqlListener) ExitInPredicate(ctx *InPredicateContext) { @@ -299,7 +300,7 @@ func (l *cqlListener) ExitInPredicate(ctx *InPredicateContext) { inPredValueList(ctx, &sb) sb.WriteString(") ") sql := sb.String() - l.saveFrag(ctx, sql) + l.saveSql(ctx, sql) } func inPredValueList(ctx *InPredicateContext, sb *strings.Builder) { @@ -330,24 +331,24 @@ func (l *cqlListener) ExitSpatialPredicate(ctx *SpatialPredicateContext) { var sb strings.Builder sb.WriteString(toPostGISFunction(ctx.SpatialOperator().GetText())) sb.WriteString("(") - sb.WriteString(l.sqlFrag(ctx.GeomExpression(0))) + sb.WriteString(l.sqlFor(ctx.GeomExpression(0))) sb.WriteString(",") - sb.WriteString(l.sqlFrag(ctx.GeomExpression(1))) + sb.WriteString(l.sqlFor(ctx.GeomExpression(1))) sb.WriteString(")") - l.saveFrag(ctx, sb.String()) + l.saveSql(ctx, sb.String()) } func (l *cqlListener) ExitDistancePredicate(ctx *DistancePredicateContext) { var sb strings.Builder sb.WriteString(toPostGISFunction(ctx.DistanceOperator().GetText())) sb.WriteString("(") - sb.WriteString(l.sqlFrag(ctx.GeomExpression(0))) + sb.WriteString(l.sqlFor(ctx.GeomExpression(0))) sb.WriteString(",") - sb.WriteString(l.sqlFrag(ctx.GeomExpression(1))) + sb.WriteString(l.sqlFor(ctx.GeomExpression(1))) sb.WriteString(",") sb.WriteString(ctx.NumericLiteral().GetText()) sb.WriteString(")") - l.saveFrag(ctx, sb.String()) + l.saveSql(ctx, sb.String()) } func (l *cqlListener) ExitGeomExpression(ctx *GeomExpressionContext) { @@ -355,9 +356,9 @@ func (l *cqlListener) ExitGeomExpression(ctx *GeomExpressionContext) { if ctx.PropertyName() != nil { sb.WriteString(quotedName(getText(ctx.PropertyName()))) } else { - sb.WriteString(l.sqlFrag(ctx.GeomLiteral())) + sb.WriteString(l.sqlFor(ctx.GeomLiteral())) } - l.saveFrag(ctx, sb.String()) + l.saveSql(ctx, sb.String()) } func (l *cqlListener) ExitGeomLiteral(ctx *GeomLiteralContext) { @@ -374,8 +375,8 @@ func (l *cqlListener) ExitGeomLiteral(ctx *GeomLiteralContext) { wkt := getGeomText(ctx) sql = l.sqlGeometryLiteral(wkt) } - sql = l.sqlTransform(sql) - l.saveFrag(ctx, sql) + sql = l.sqlTransformCrs(sql) + l.saveSql(ctx, sql) } func getGeomText(ctx *GeomLiteralContext) string { diff --git a/internal/cql/cql_test.go b/internal/cql/cql_test.go index 08c22e85..d76836b8 100644 --- a/internal/cql/cql_test.go +++ b/internal/cql/cql_test.go @@ -97,11 +97,15 @@ func TestBooleanExpression(t *testing.T) { checkCQL(t, "NOT x IS NOT NULL", "NOT \"x\" IS NOT NULL") } -func TestErrors(t *testing.T) { +func TestSyntaxErrors(t *testing.T) { checkCQLError(t, "x y") checkCQLError(t, "x == y") checkCQLError(t, "x > 10y") checkCQLError(t, "NOT x IS > 3") + // extra paren + checkCQLError(t, "equals(geom, ENVELOPE(1,2,3,4)))") + // comma between ordinates + checkCQLError(t, "equals(geom, POINT(0,0))") } func checkCQL(t *testing.T, cqlStr string, sql string) { From 026d719048837c32c93fac40b7892ccb0e069152 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 11:07:26 -0800 Subject: [PATCH 07/14] Update NEWS --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 10bc695c..ebb9924f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -15,6 +15,7 @@ * Add configuration to set base path (#88) * Add standard query parameters `crs` and `bbox-crs` (#98) * Allow configuring published function schemas (#99) +* Add support for CQL filtering with `filter` and `filter-crs` query parameters (#101, #102) ### Performance Improvements From 70124be0b29c5e2d53a6df6be44fd23cf41a5a3a Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 11:31:22 -0800 Subject: [PATCH 08/14] Improve CQL doc --- hugo/content/usage/cql.md | 47 ++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index bdf1d0d7..daac038b 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -10,22 +10,26 @@ the `filter` query parameter with an expression written using the [Common Query Language](https://portal.ogc.org/files/96288) (CQL). CQL expressions return a value of `true` or `false`. Only features which evaluate to `true` are returned. + In `pg_featureserv` the filter expression is evaluated by the database, so it can take advantage of indexes (standard and spatial) to make filter evaluation very efficient. This section describes the CQL query language subset supported by `pg_featureserv`. -## Property and Scalar Literal Values +## Property and Literal Values The basic elements of filter expressions are values obtained from feature collection properties and literals. Properties are referred to by name. -Scalar literals can be numbers, boolean or text values. +Property names can be quoted, to support including special characters. +Literals can be numbers, boolean or text values. #### Example ``` propname +"quoted_name$" + 1.234 true 'a text value' @@ -38,7 +42,7 @@ Values can be compared using conditional operators: a = b a <> b a > b a >= b a < b a <= b ``` -### Example +#### Examples ``` pop_est >= 1000000 name = 'Finland' @@ -51,7 +55,7 @@ The `BETWEEN` predicate tests if a value lies in a range defined by start and en property [NOT] BETWEEN a AND b ``` -### Example +#### Examples ``` pop_est BETWEEN 100000 AND 1000000 name NOT BETWEEN 'Chile' AND 'Denmark' @@ -63,7 +67,7 @@ The `IN` predicate tests if a value lies in a list of constant values. property [NOT] IN ( val1, val2, ... ) ``` -### Example +#### Examples ``` id IN (1,2,3) name IN ('Chile', 'Kenya', 'Denmark') @@ -79,7 +83,7 @@ The character `%` is a wildcard. property [NOT] LIKE | ILIKE pattern ``` -### Example +#### Examples ``` name LIKE 'Ch%' continent ILIKE '%america' @@ -91,7 +95,7 @@ The `IS NULL` predicate tests if a property value is (or is not) null. property IS [NOT] NULL ``` -### Example +#### Example ``` name IS NULL ``` @@ -103,21 +107,23 @@ Operators are evaluated in the order NOT, AND, OR. Evaluation order can be controlled by enclosing subexpressions in parentheses. -### Example +#### Example ``` (continent = 'Europe' OR continent = 'Afica') AND pop_est < 1000000 ``` ## Spatial filters -CQL supports spatial filters by providing **geometry values** +CQL supports spatial filters by providing **geometry literals** and **spatial predicates**. ### Geometry Literals -Geometry literals use Well-Known Text (WKT) to describe -values for points, lines, polygons (with holes), and collections: +Geometry literals use [Well-Known Text](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) +(WKT) to describe +values for points, lines, polygons (with holes), and collections. +#### Examples ``` POINT (1 2) LINESTRING (0 0, 1 1) @@ -129,7 +135,8 @@ MULTIPOLYGON (((1 4, 4 1, 1 1, 1 4)), ((1 9, 4 9, 1 6, 1 9))) GEOMETRYCOLLECTION(POLYGON ((1 4, 4 1, 1 1, 1 4)), LINESTRING (3 3, 5 5), POINT (1 5)) ``` -CQL also provides a syntax for concisely defining a rectangular polygon: +CQL also provides a syntax for concisely representing a rectangular polygon +by the X and Y ordinates at the lower-left and upper-right corners: ``` ENVELOPE (1, 2, 3, 4) ``` @@ -153,20 +160,24 @@ Predicates for spatial relationships include: * `OVERLAPS` - tests whether the geometries overlap * `TOUCHES` - tests whether the geometries touch -For precise definitions of the spatial predicates see the +For detailed definitions of the spatial predicates see the [CQL standard](https://portal.ogc.org/files/96288#enhanced-spatial-operators) and the [PostGIS function reference](https://postgis.net/docs/reference.html#Spatial_Relationships). Typically a spatial predicate will be applied to the spatial column of the collection being queried, and a geometry literal value. -For example: + +#### Examples ``` -filter=INTERSECTS(geom, ENVELOPE(-100 49, -90, 50) ) +INTERSECTS(geom, ENVELOPE(-100 49, -90, 50) ) -filter=CONTAINS(geom, POINT(-100 49) ) +CONTAINS(geom, POINT(-100 49) ) ``` -The `DWITHIN` predicate allows testing whether a geometry lies within a given distance of another. The distance specified is in the units of the underlying dataset's coordinate system. For example: +The `DWITHIN` predicate allows testing whether a geometry lies within a given distance of another. The distance is in the units of the dataset's coordinate system +(degrees in the case of data stored in SRID=4326, or a length unit such as meters for non-geodetic data). + +#### Example ``` -filter=DWITHIN(geom, POINT(-100 49), 0.1) +DWITHIN(geom, POINT(-100 49), 0.1) ``` From 61d8d69fd4f325e42fcfc11b91e1b4c19f450aad Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 11:34:17 -0800 Subject: [PATCH 09/14] Improve CQL doc --- hugo/content/usage/cql.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index daac038b..a37eaf48 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -114,7 +114,7 @@ subexpressions in parentheses. ## Spatial filters -CQL supports spatial filters by providing **geometry literals** +CQL supports spatial filtering by providing **geometry literals** and **spatial predicates**. ### Geometry Literals From cb80439b10fb8143aad9ecd50e1146a72303c02e Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 11:41:33 -0800 Subject: [PATCH 10/14] Improve doc for query params --- hugo/content/usage/cql.md | 2 +- hugo/content/usage/query_data.md | 16 +++++++++------- hugo/content/usage/query_function.md | 10 ++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index a37eaf48..cdda9095 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -142,7 +142,7 @@ ENVELOPE (1, 2, 3, 4) ``` By default the coordinate system of geometry literal values is assumed to be geodetic (SRID = 4326). -The `filter-crs=SRID` query parameter can be used to specify that filter geometry literals are in a different coordinate system. +The `filter-crs=SRID` query parameter can be used to specify that the geometry literals in a filter expression are in a different coordinate system. ### Spatial predicates diff --git a/hugo/content/usage/query_data.md b/hugo/content/usage/query_data.md index 7f9dddfc..7fd15073 100644 --- a/hugo/content/usage/query_data.md +++ b/hugo/content/usage/query_data.md @@ -75,9 +75,11 @@ See the [CQL section](/query_data/cql/) for more details. http://localhost:9000/collections/ne.countries/items?filter=continent='Europe' AND pop_est<2000000 ``` -### Specify filter coordinate system +### Filter geometry coordinate system -The coordinate system used by geometry literals in the filter expression +By default the coordinate system of geometry literals in the filter expressionis +is assumed to be 4326 (geodetic). +A different coordinate system can be specified by using the query parameter `filter-crs=SRID`. #### Example @@ -85,7 +87,7 @@ can be specified by using the query parameter `filter-crs=SRID`. http://localhost:9000/collections/ebc.voting_area/items.json?filter=DWITHIN(geom,POINT(1209000+477000),1000)&filter-crs=3005 ``` -### Specify response properties +### Response properties The query parameter `properties=PROP1,PROP2,PROP3...` specifies the feature properties returned in the response. @@ -99,7 +101,7 @@ no feature properties are returned. http://localhost:9000/collections/ne.countries/items?properties=name,abbrev,pop_est ``` -### Specify response coordinate system +### Response coordinate system The query parameter `crs=SRID` specifies the coordinate system to be used for the @@ -174,7 +176,7 @@ The response is a GeoJSON feature containing the result. http://localhost:9000/collections/ne.countries/items/23 ``` -### Specify properties +### Specify response properties The query parameter `properties=PROP1,PROP2,PROP3...` specifies the feature properties which are returned @@ -185,11 +187,11 @@ in the response. http://localhost:9000/collections/ne.countries/items/23?properties=name,abbrev,pop_est ``` -### Specify coordinate system +### Specify responses coordinate system The query parameter `crs=SRID` can be included to specify the coordinate system to be used for the -feature geometry. +feature geometry in the response. #### Example ``` diff --git a/hugo/content/usage/query_function.md b/hugo/content/usage/query_function.md index 3ca736bd..dea0bc4f 100644 --- a/hugo/content/usage/query_function.md +++ b/hugo/content/usage/query_function.md @@ -68,9 +68,11 @@ See the [CQL section](/query_data/cql/) for more details. http://localhost:9000/functions/countries_name/items?name_prefix=C&filter=continent='Europe' AND pop_est<2000000 ``` -### Specify filter coordinate system +### Filter geometry coordinate system -The coordinate system used by geometry literals in the filter expression +By default the coordinate system of geometry literals in the filter expressionis +is assumed to be 4326 (geodetic). +A different coordinate system can be specified by using the query parameter `filter-crs=SRID`. #### Example @@ -78,7 +80,7 @@ can be specified by using the query parameter `filter-crs=SRID`. http://localhost:9000/functions/countries_name/items.json?filter=DWITHIN(geom,POINT(1209000+477000),1000)&filter-crs=3005 ``` -### Specify response properties +### Response properties The query parameter `properties=PROP1,PROP2,PROP3...` specifies the properties returned in the response. @@ -92,7 +94,7 @@ no feature properties are returned. http://localhost:9000/functions/countries_name/items?properties=name ``` -### Specify response coordinate system +### Response coordinate system The query parameter `crs=SRID` specifies the coordinate system to be used for the From 4ff40be4241960026a7d9e24cea1bb712a165305 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 12:14:42 -0800 Subject: [PATCH 11/14] Various doc improvements --- .../ex_query_functions_countries_name.md | 3 +- hugo/content/usage/collections.md | 2 +- hugo/content/usage/cql.md | 29 +++++++++++-------- hugo/content/usage/query_data.md | 10 ++++--- hugo/content/usage/query_function.md | 4 ++- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/hugo/content/examples/ex_query_functions_countries_name.md b/hugo/content/examples/ex_query_functions_countries_name.md index 9b0b0dee..a31278a3 100644 --- a/hugo/content/examples/ex_query_functions_countries_name.md +++ b/hugo/content/examples/ex_query_functions_countries_name.md @@ -7,7 +7,8 @@ weight: 210 This is the same spatial function example shown in the [Usage](/usage/functions/) section. Here we'll show a sample GeoJSON response and the web UI preview. -Note: this functionality can now be obtained more easily by using the `filter` query parameter with a `LIKE` CQl expression. +Note: +Another way to obtain this functionality is to use the `filter` query parameter with a `LIKE` CQl expression. See the [CQL section](/usage/cql/) ## Create a spatial function that returns a filtered set of countries diff --git a/hugo/content/usage/collections.md b/hugo/content/usage/collections.md index a263cc10..ad95fc64 100644 --- a/hugo/content/usage/collections.md +++ b/hugo/content/usage/collections.md @@ -25,7 +25,7 @@ Visible spatial tables and views are those which: * declare a **geometry type**; * declare an **SRID** (spatial reference ID); * and the service database connection has `SELECT` privileges for - (see the and [Security](/usage/security/) section for more detail). + (see the [Security](/usage/security/) section for more detail). If the table or view has a **primary key column** it will be used as the id for features in the collection. diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index cdda9095..29ba752b 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -1,5 +1,5 @@ --- -title: "Filtering with CQL" +title: "CQL Filters" date: draft: false weight: 175 @@ -11,25 +11,30 @@ the [Common Query Language](https://portal.ogc.org/files/96288) (CQL). CQL expressions return a value of `true` or `false`. Only features which evaluate to `true` are returned. -In `pg_featureserv` the filter expression is evaluated by the database, -so it can take advantage of indexes (standard and spatial) -to make filter evaluation very efficient. - This section describes the CQL query language subset supported by `pg_featureserv`. +{{% note %}} +The filter expression is evaluated by the database, +which will take advantage of indexes (attribute and spatial) +to make filter evaluation very efficient. +{{% /note %}} + ## Property and Literal Values The basic elements of filter expressions are values obtained -from feature collection properties and literals. +from feature collection properties, and literals. + Properties are referred to by name. Property names can be quoted, to support including special characters. -Literals can be numbers, boolean or text values. -#### Example ``` propname "quoted_name$" +``` +Literals can be numbers, boolean or text values. + +``` 1.234 true 'a text value' @@ -50,7 +55,7 @@ name = 'Finland' ## BETWEEN predicate -The `BETWEEN` predicate tests if a value lies in a range defined by start and end values (inclusive): +The `BETWEEN` predicate tests if a value lies in a range defined by a start and end value (inclusive): ``` property [NOT] BETWEEN a AND b ``` @@ -109,7 +114,7 @@ subexpressions in parentheses. #### Example ``` -(continent = 'Europe' OR continent = 'Afica') AND pop_est < 1000000 +(continent = 'Europe' OR continent = 'Africa') AND pop_est < 1000000 ``` ## Spatial filters @@ -164,8 +169,8 @@ For detailed definitions of the spatial predicates see the [CQL standard](https://portal.ogc.org/files/96288#enhanced-spatial-operators) and the [PostGIS function reference](https://postgis.net/docs/reference.html#Spatial_Relationships). -Typically a spatial predicate will be applied to the spatial column of the collection -being queried, and a geometry literal value. +Typically a spatial predicate is used to test the relationship between the spatial column of the queried collection +and a geometry literal value. #### Examples ``` diff --git a/hugo/content/usage/query_data.md b/hugo/content/usage/query_data.md index 7fd15073..f256a427 100644 --- a/hugo/content/usage/query_data.md +++ b/hugo/content/usage/query_data.md @@ -51,7 +51,7 @@ http://localhost:9000/collections/ne.countries/items?bbox=10.4,43.3,26.4,47.7 http://localhost:9000/collections/ne.countries/items?bbox-crs=3005&bbox=1000000,400000,1001000,401000 ``` -### Filter by properties +### Filter by property values The response feature set can be filtered to include only features which have a given value for one or more properties. @@ -72,7 +72,7 @@ See the [CQL section](/query_data/cql/) for more details. #### Example ``` -http://localhost:9000/collections/ne.countries/items?filter=continent='Europe' AND pop_est<2000000 +http://localhost:9000/collections/ne.countries/items?filter=continent='Europe' AND pop_est < 2000000 ``` ### Filter geometry coordinate system @@ -84,7 +84,7 @@ can be specified by using the query parameter `filter-crs=SRID`. #### Example ``` -http://localhost:9000/collections/ebc.voting_area/items.json?filter=DWITHIN(geom,POINT(1209000+477000),1000)&filter-crs=3005 +http://localhost:9000/collections/ebc.voting_area/items.json?filter-crs=3005&filter=DWITHIN(geom,POINT(1209000+477000),1000) ``` ### Response properties @@ -109,9 +109,11 @@ feature geometry in the response. The SRID must be a coordinate system which is defined in the PostGIS instance. By default data is returned in WGS84 (SRID=4326) geodetic coordinate system. -Note: GeoJSON technically does not support coordinate systems other than 4326, +{{% note %}} +GeoJSON technically does not support coordinate systems other than 4326, but the OGC API standard allows non-geodetic data to be encoded in GeoJSON. However, this data may not be compatible with other systems. +{{% /note %}} #### Example ``` diff --git a/hugo/content/usage/query_function.md b/hugo/content/usage/query_function.md index dea0bc4f..2242211c 100644 --- a/hugo/content/usage/query_function.md +++ b/hugo/content/usage/query_function.md @@ -102,9 +102,11 @@ feature geometry in the response. The SRID must be a coordinate system which is defined in the PostGIS instance. By default data is returned in WGS84 (SRID=4326) geodetic coordinate system. -Note: GeoJSON technically does not support coordinate systems other than 4326, +{{% note %}} +GeoJSON technically does not support coordinate systems other than 4326, but the OGC API standard allows non-geodetic data to be encoded in GeoJSON. However, this data may not be compatible with other systems. +{{% /note %}} This parameter is only useful for **spatial** functions. From f6353971085dd5129df5e927d8bdade7372dd055 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 12:23:08 -0800 Subject: [PATCH 12/14] Improve doc CQL formatting --- hugo/content/usage/cql.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index 29ba752b..43c2538c 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -117,12 +117,12 @@ subexpressions in parentheses. (continent = 'Europe' OR continent = 'Africa') AND pop_est < 1000000 ``` -## Spatial filters +# Spatial filters CQL supports spatial filtering by providing **geometry literals** and **spatial predicates**. -### Geometry Literals +## Geometry Literals Geometry literals use [Well-Known Text](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) (WKT) to describe @@ -149,7 +149,7 @@ ENVELOPE (1, 2, 3, 4) By default the coordinate system of geometry literal values is assumed to be geodetic (SRID = 4326). The `filter-crs=SRID` query parameter can be used to specify that the geometry literals in a filter expression are in a different coordinate system. -### Spatial predicates +## Spatial predicates Spatial predicates allow filtering features via spatial conditions on the feature geometry. From 919850e52e452fe09a31ea12d682b76f8f177293 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 13:20:52 -0800 Subject: [PATCH 13/14] Update API.md --- API.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/API.md b/API.md index 669c446b..911c54bc 100644 --- a/API.md +++ b/API.md @@ -2,8 +2,9 @@ ## References -1. [OGC API for Features version 1.0](http://docs.opengeospatial.org/is/17-069r3/17-069r3.html) -1. [OpenAPI Specifcation version 3.0.2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md) +* [OGC API for Features version 1.0](http://docs.opengeospatial.org/is/17-069r3/17-069r3.html) +* [OGC API - Features - Part 3: Filtering and the Common Query Language (CQL)](https://portal.ogc.org/files/96288) +* [OpenAPI Specifcation version 3.0.2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md) ## Notes @@ -69,25 +70,27 @@ Produces a dataset of items from the collection (as GeoJSON) Path: `/collections/{cid}/items` ### Parameters -* `crs=SRID` - specifies the CRS for the output feature geometry -* `limit=N` - limits the number of features in the response. -* `offset=N` - starts the response at an offset. -* `sortby=[+|-]PROP` - sort the response items by a property (ascending (default) or descending). * `bbox=mix,miny,maxx,maxy` - filter features in response to ones intersecting a bounding box (in lon/lat or specified CRS). * `bbox-crs=SRID` - specify CRS for the `bbox` coordinates * `=val` - filter features for a property having a value. Multiple property filters are ANDed together. +* `filter=cql-expr` - filters features via a CQL expression +* `filter-crs=SRID` - specifies the CRS for geometry values in the CQL filter +* `transform=fun1[,args][|fun2,args...]` - transform the feature geometry by a geometry function pipeline. +* `groupby=PROP-NAME` - group results on a property. +Usually used with an aggregate `transform` function. * `properties=PROP-LIST`- return only specific properties (comma-separated). If PROP-LIST is empty, no properties are returned. If not present, all properties are returned. +* `crs=SRID` - specifies the CRS for the output feature geometry * `precision=N` - set precision of GeoJSON ordinates to use N decimal places -* `transform=fun1[,args][|fun2,args...]` - transform the feature geometry by a geometry function pipeline. -* `groupby=PROP-NAME` - group results on a property. -Usually used with an aggregate `transform` function. +* `sortby=[+|-]PROP` - sort the response items by a property (ascending (default) or descending). +* `limit=N` - limits the number of features in the response. +* `offset=N` - starts the response at an offset. ### Response -GeoJSON document containg the features produced by the request. +GeoJSON document containing the features resulting from the request query. #### Links * self - `/collections/{cid}/items.json` - This document as JSON From d524aa4a326e4be2ec1632109793c89524868b9f Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Tue, 1 Mar 2022 14:03:50 -0800 Subject: [PATCH 14/14] Fix CQL envelope literal example --- hugo/content/usage/cql.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugo/content/usage/cql.md b/hugo/content/usage/cql.md index 43c2538c..668d32d5 100644 --- a/hugo/content/usage/cql.md +++ b/hugo/content/usage/cql.md @@ -174,7 +174,7 @@ and a geometry literal value. #### Examples ``` -INTERSECTS(geom, ENVELOPE(-100 49, -90, 50) ) +INTERSECTS(geom, ENVELOPE(-100, 49, -90, 50) ) CONTAINS(geom, POINT(-100 49) ) ```