Implement groupby() (#161)

* test: slq2sql more test cases; now executes the generated query

* groupby: first test case working against all DBs

* sakila: added sqlserver 2019 source

* groupby: tests for groupby synonyms

* groupby: final touches
This commit is contained in:
Neil O'Toole 2023-03-26 02:01:41 -06:00 committed by GitHub
parent 8c83f0df3a
commit d9b56eea8a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 761 additions and 575 deletions

View File

@ -5,11 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v0.28.0] - 2023-03-26
### Added
- [#160]: Use `groupby()` to group results. See [query guide](https://sq.io/docs/query/#group-by).
## [v0.27.0] - 2023-03-25 ## [v0.27.0] - 2023-03-25
### Added ### Added
- [#158]: Use `orderby()` to order results. See [query guide](https://sq.io/docs/query/#ordering). - [#158]: Use `orderby()` to order results. See [query guide](https://sq.io/docs/query/#order-by).
## [v0.26.0] - 2023-03-22 ## [v0.26.0] - 2023-03-22
@ -191,11 +197,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#123]: https://github.com/neilotoole/sq/issues/123 [#123]: https://github.com/neilotoole/sq/issues/123
[#142]: https://github.com/neilotoole/sq/issues/142 [#142]: https://github.com/neilotoole/sq/issues/142
[#144]: https://github.com/neilotoole/sq/issues/144 [#144]: https://github.com/neilotoole/sq/issues/144
[#15]: https://github.com/neilotoole/sq/issues/15
[#151]: https://github.com/neilotoole/sq/issues/151 [#151]: https://github.com/neilotoole/sq/issues/151
[#153]: https://github.com/neilotoole/sq/issues/153 [#153]: https://github.com/neilotoole/sq/issues/153
[#155]: https://github.com/neilotoole/sq/issues/155 [#155]: https://github.com/neilotoole/sq/issues/155
[#158]: https://github.com/neilotoole/sq/issues/158 [#158]: https://github.com/neilotoole/sq/issues/158
[#15]: https://github.com/neilotoole/sq/issues/15
[#160]: https://github.com/neilotoole/sq/issues/160
[#89]: https://github.com/neilotoole/sq/pull/89 [#89]: https://github.com/neilotoole/sq/pull/89
[#91]: https://github.com/neilotoole/sq/pull/91 [#91]: https://github.com/neilotoole/sq/pull/91
[#95]: https://github.com/neilotoole/sq/issues/93 [#95]: https://github.com/neilotoole/sq/issues/93
@ -222,3 +229,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[v0.25.1]: https://github.com/neilotoole/sq/compare/v0.25.0...v0.25.1 [v0.25.1]: https://github.com/neilotoole/sq/compare/v0.25.0...v0.25.1
[v0.26.0]: https://github.com/neilotoole/sq/compare/v0.25.1...v0.26.0 [v0.26.0]: https://github.com/neilotoole/sq/compare/v0.25.1...v0.26.0
[v0.27.0]: https://github.com/neilotoole/sq/compare/v0.26.0...v0.27.0 [v0.27.0]: https://github.com/neilotoole/sq/compare/v0.26.0...v0.27.0
[v0.28.0]: https://github.com/neilotoole/sq/compare/v0.27.0...v0.28.0

View File

@ -4,6 +4,8 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/neilotoole/sq/cli/output"
"github.com/neilotoole/sq/drivers/mysql" "github.com/neilotoole/sq/drivers/mysql"
"github.com/neilotoole/sq/libsq/source" "github.com/neilotoole/sq/libsq/source"
@ -19,164 +21,236 @@ import (
//nolint:exhaustive,lll //nolint:exhaustive,lll
func TestSLQ2SQLNew(t *testing.T) { func TestSLQ2SQLNew(t *testing.T) {
testCases := []struct { testCases := []struct {
// name is the test name
name string name string
// in is the SLQ input. The "@sakila" handle is replaced
// with the source's actual handle before an individual
// test cases is executed.
in string in string
// wantErr indicates that an error is expected
wantErr bool wantErr bool
want string
// wantSQL is the wanted SQL
wantSQL string
// override allows an alternative "wantSQL" for a specific driver type.
// For example, MySQL uses backtick as the quote char.
override map[source.Type]string override map[source.Type]string
// skip indicates the test should be skipped. Useful for test cases
// that we wantSQL to implement in the future.
skip bool
// skipExec indicates that the resulting query should not be executed.
// Some SLQ inputs we wantSQL to test don't actually have corresponding
// data in the Sakila datasets.
skipExec bool
// wantRecs is the number of expected records from executing the query.
wantRecs int
}{ }{
{ {
name: "select/cols", name: "select/cols",
in: `@sakila | .actor | .first_name, .last_name`, in: `@sakila | .actor | .first_name, .last_name`,
want: `SELECT "first_name", "last_name" FROM "actor"`, wantSQL: `SELECT "first_name", "last_name" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT `first_name`, `last_name` FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT `first_name`, `last_name` FROM `actor`"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "select/cols-whitespace", name: "select/cols-whitespace-single-col",
in: `@sakila | .actor | ."first name"`, in: `@sakila | .actor | ."first name"`,
want: `SELECT "first name" FROM "actor"`, wantSQL: `SELECT "first name" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT `first name` FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT `first name` FROM `actor`"},
wantRecs: sakila.TblActorCount,
skipExec: true,
}, },
{ {
name: "select/cols-whitespace-2", name: "select/cols-whitespace-multiple-cols",
in: `@sakila | .actor | .actor_id, ."first name", ."last name"`, in: `@sakila | .actor | .actor_id, ."first name", ."last name"`,
want: `SELECT "actor_id", "first name", "last name" FROM "actor"`, wantSQL: `SELECT "actor_id", "first name", "last name" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT `actor_id`, `first name`, `last name` FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT `actor_id`, `first name`, `last name` FROM `actor`"},
wantRecs: sakila.TblActorCount,
skipExec: true,
}, },
{ {
name: "select/count-whitespace-col", name: "select/count-whitespace-col",
in: `@sakila | .actor | count(."first name")`, in: `@sakila | .actor | count(."first name")`,
want: `SELECT COUNT("first name") FROM "actor"`, wantSQL: `SELECT COUNT("first name") FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(`first name`) FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT COUNT(`first name`) FROM `actor`"},
skipExec: true,
}, },
{ {
name: "select/table-whitespace", name: "select/table-whitespace",
in: `@sakila | ."film actor"`, in: `@sakila | ."film actor"`,
want: `SELECT * FROM "film actor"`, wantSQL: `SELECT * FROM "film actor"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `film actor`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `film actor`"},
skipExec: true,
}, },
{ {
name: "select/cols-aliases", name: "select/cols-aliases",
in: `@sakila | .actor | .first_name:given_name, .last_name:family_name`, in: `@sakila | .actor | .first_name:given_name, .last_name:family_name`,
want: `SELECT "first_name" AS "given_name", "last_name" AS "family_name" FROM "actor"`, wantSQL: `SELECT "first_name" AS "given_name", "last_name" AS "family_name" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT `first_name` AS `given_name`, `last_name` AS `family_name` FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT `first_name` AS `given_name`, `last_name` AS `family_name` FROM `actor`"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "select/count-star", name: "select/count-star",
in: `@sakila | .actor | count(*)`, in: `@sakila | .actor | count(*)`,
want: `SELECT COUNT(*) FROM "actor"`, wantSQL: `SELECT COUNT(*) FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) FROM `actor`"},
wantRecs: 1,
}, },
{ {
name: "select/count", name: "select/count",
in: `@sakila | .actor | count()`, in: `@sakila | .actor | count()`,
want: `SELECT COUNT(*) FROM "actor"`, wantSQL: `SELECT COUNT(*) FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) FROM `actor`"},
wantRecs: 1,
}, },
{ {
name: "select/handle-table/cols", name: "select/handle-table/cols",
in: `@sakila.actor | .first_name, .last_name`, in: `@sakila.actor | .first_name, .last_name`,
want: `SELECT "first_name", "last_name" FROM "actor"`, wantSQL: `SELECT "first_name", "last_name" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT `first_name`, `last_name` FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT `first_name`, `last_name` FROM `actor`"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "select/handle-table/count-star", name: "select/handle-table/count-star",
in: `@sakila.actor | count(*)`, in: `@sakila.actor | count(*)`,
want: `SELECT COUNT(*) FROM "actor"`, wantSQL: `SELECT COUNT(*) FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) FROM `actor`"},
wantRecs: 1,
}, },
{ {
name: "select/handle-table/count-col", name: "select/handle-table/count-col",
in: `@sakila.actor | count(."first name")`, in: `@sakila.actor | count(."first name")`,
want: `SELECT COUNT("first name") FROM "actor"`, wantSQL: `SELECT COUNT("first name") FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(`first name`) FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT COUNT(`first name`) FROM `actor`"},
skipExec: true,
}, },
{ {
name: "select/count-alias", name: "select/count-alias",
in: `@sakila | .actor | count(*):quantity`, in: `@sakila | .actor | count(*):quantity`,
want: `SELECT COUNT(*) AS "quantity" FROM "actor"`, wantSQL: `SELECT COUNT(*) AS "quantity" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) AS `quantity` FROM `actor`"}, override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) AS `quantity` FROM `actor`"},
wantRecs: 1,
}, },
{ {
name: "filter/equal", name: "filter/equal",
in: `@sakila | .actor | .actor_id == 1`, in: `@sakila | .actor | .actor_id == 1`,
want: `SELECT * FROM "actor" WHERE "actor_id" = 1`, wantSQL: `SELECT * FROM "actor" WHERE "actor_id" = 1`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` WHERE `actor_id` = 1"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` WHERE `actor_id` = 1"},
wantRecs: 1,
}, },
{ {
name: "join/single-selector", name: "join/single-selector",
in: `@sakila | .actor, .film_actor | join(.actor_id)`, in: `@sakila | .actor, .film_actor | join(.actor_id)`,
want: `SELECT * FROM "actor" INNER JOIN "film_actor" ON "actor"."actor_id" = "film_actor"."actor_id"`, wantSQL: `SELECT * FROM "actor" INNER JOIN "film_actor" ON "actor"."actor_id" = "film_actor"."actor_id"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` INNER JOIN `film_actor` ON `actor`.`actor_id` = `film_actor`.`actor_id`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` INNER JOIN `film_actor` ON `actor`.`actor_id` = `film_actor`.`actor_id`"},
wantRecs: sakila.TblFilmActorCount,
}, },
{ {
name: "join/fq-table-cols-equal", name: "join/fq-table-cols-equal",
in: `@sakila | .actor, .film_actor | join(.film_actor.actor_id == .actor.actor_id)`, in: `@sakila | .actor, .film_actor | join(.film_actor.actor_id == .actor.actor_id)`,
want: `SELECT * FROM "actor" INNER JOIN "film_actor" ON "film_actor"."actor_id" = "actor"."actor_id"`, wantSQL: `SELECT * FROM "actor" INNER JOIN "film_actor" ON "film_actor"."actor_id" = "actor"."actor_id"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` INNER JOIN `film_actor` ON `film_actor`.`actor_id` = `actor`.`actor_id`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` INNER JOIN `film_actor` ON `film_actor`.`actor_id` = `actor`.`actor_id`"},
wantRecs: sakila.TblFilmActorCount,
}, },
{ {
name: "join/fq-table-cols-equal-whitespace", name: "join/fq-table-cols-equal-whitespace",
in: `@sakila | .actor, ."film actor" | join(."film actor".actor_id == .actor.actor_id)`, in: `@sakila | .actor, ."film actor" | join(."film actor".actor_id == .actor.actor_id)`,
want: `SELECT * FROM "actor" INNER JOIN "film actor" ON "film actor"."actor_id" = "actor"."actor_id"`, wantSQL: `SELECT * FROM "actor" INNER JOIN "film actor" ON "film actor"."actor_id" = "actor"."actor_id"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` INNER JOIN `film actor` ON `film actor`.`actor_id` = `actor`.`actor_id`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` INNER JOIN `film actor` ON `film actor`.`actor_id` = `actor`.`actor_id`"},
skipExec: true,
}, },
{ {
name: "orderby/single-element", name: "orderby/single-element",
in: `@sakila | .actor | orderby(.first_name)`, in: `@sakila | .actor | orderby(.first_name)`,
want: `SELECT * FROM "actor" ORDER BY "first_name"`, wantSQL: `SELECT * FROM "actor" ORDER BY "first_name"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name`"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "orderby/single-element-table-selector", name: "orderby/single-element-table-selector",
in: `@sakila | .actor | orderby(.actor.first_name)`, in: `@sakila | .actor | orderby(.actor.first_name)`,
want: `SELECT * FROM "actor" ORDER BY "actor"."first_name"`, wantSQL: `SELECT * FROM "actor" ORDER BY "actor"."first_name"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `actor`.`first_name`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `actor`.`first_name`"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "orderby/single-element-asc", name: "orderby/single-element-asc",
in: `@sakila | .actor | orderby(.first_name+)`, in: `@sakila | .actor | orderby(.first_name+)`,
want: `SELECT * FROM "actor" ORDER BY "first_name" ASC`, wantSQL: `SELECT * FROM "actor" ORDER BY "first_name" ASC`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` ASC"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` ASC"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "orderby/single-element-desc", name: "orderby/single-element-desc",
in: `@sakila | .actor | orderby(.first_name-)`, in: `@sakila | .actor | orderby(.first_name-)`,
want: `SELECT * FROM "actor" ORDER BY "first_name" DESC`, wantSQL: `SELECT * FROM "actor" ORDER BY "first_name" DESC`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` DESC"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` DESC"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "orderby/multiple-elements", name: "orderby/multiple-elements",
in: `@sakila | .actor | orderby(.first_name+, .last_name-)`, in: `@sakila | .actor | orderby(.first_name+, .last_name-)`,
want: `SELECT * FROM "actor" ORDER BY "first_name" ASC, "last_name" DESC`, wantSQL: `SELECT * FROM "actor" ORDER BY "first_name" ASC, "last_name" DESC`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` ASC, `last_name` DESC"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` ASC, `last_name` DESC"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "orderby/synonym-sort-by", name: "orderby/synonym-sort-by",
in: `@sakila | .actor | sort_by(.first_name)`, in: `@sakila | .actor | sort_by(.first_name)`,
want: `SELECT * FROM "actor" ORDER BY "first_name"`, wantSQL: `SELECT * FROM "actor" ORDER BY "first_name"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name`"}, override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name`"},
wantRecs: sakila.TblActorCount,
}, },
{ {
name: "orderby/error-no-selector", name: "orderby/error-no-selector",
in: `@sakila | .actor | orderby()`, in: `@sakila | .actor | orderby()`,
wantErr: true, wantErr: true,
}, },
{
name: "groupby/single-term",
in: `@sakila | .payment | .customer_id, sum(.amount) | groupby(.customer_id)`,
wantSQL: `SELECT "customer_id", SUM("amount") FROM "payment" GROUP BY "customer_id"`,
override: map[source.Type]string{mysql.Type: "SELECT `customer_id`, SUM(`amount`) FROM `payment` GROUP BY `customer_id`"},
wantRecs: 599,
},
{
name: "groupby/synonym-group_by",
in: `@sakila | .payment | .customer_id, sum(.amount) | group_by(.customer_id)`,
wantSQL: `SELECT "customer_id", SUM("amount") FROM "payment" GROUP BY "customer_id"`,
override: map[source.Type]string{mysql.Type: "SELECT `customer_id`, SUM(`amount`) FROM `payment` GROUP BY `customer_id`"},
wantRecs: 599,
},
{
name: "groupby/multiple_terms",
in: `@sakila | .payment | .customer_id, .staff_id, sum(.amount) | groupby(.customer_id, .staff_id)`,
wantSQL: `SELECT "customer_id", "staff_id", SUM("amount") FROM "payment" GROUP BY "customer_id", "staff_id"`,
override: map[source.Type]string{mysql.Type: "SELECT `customer_id`, `staff_id`, SUM(`amount`) FROM `payment` GROUP BY `customer_id`, `staff_id`"},
wantRecs: 1198,
},
} }
srcs := testh.New(t).NewSourceSet(sakila.SQLLatest()...)
// srcs := testh.New(t).NewSourceSet(sakila.SL3)
for _, tc := range testCases { for _, tc := range testCases {
tc := tc tc := tc
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
if tc.skip {
t.Skip()
}
srcs := testh.New(t).NewSourceSet(sakila.SQLLatest()...)
for _, src := range srcs.Items() { for _, src := range srcs.Items() {
src := src src := src
t.Run(string(src.Type), func(t *testing.T) { t.Run(string(src.Type), func(t *testing.T) {
in := strings.Replace(tc.in, "@sakila", src.Handle, 1) in := strings.Replace(tc.in, "@sakila", src.Handle, 1)
t.Logf(in) t.Logf(in)
want := tc.want want := tc.wantSQL
if overrideWant, ok := tc.override[src.Type]; ok { if overrideWant, ok := tc.override[src.Type]; ok {
want = overrideWant want = overrideWant
} }
@ -195,6 +269,22 @@ func TestSLQ2SQLNew(t *testing.T) {
require.NoError(t, gotErr) require.NoError(t, gotErr)
require.Equal(t, want, gotSQL) require.Equal(t, want, gotSQL)
t.Log(gotSQL)
if tc.skipExec {
return
}
sink := &testh.RecordSink{}
recw := output.NewRecordWriterAdapter(sink)
gotErr = libsq.ExecuteSLQ(th.Context, th.Log, dbases, dbases, srcs, in, recw)
require.NoError(t, gotErr)
written, err := recw.Wait()
require.NoError(t, err)
require.Equal(t, tc.wantRecs, int(written))
require.Equal(t, tc.wantRecs, len(sink.Recs))
}) })
} }
}) })

View File

@ -32,12 +32,28 @@ joinConstraint:
selector cmpr selector // .user.uid == .address.userid selector cmpr selector // .user.uid == .address.userid
| selector ; // .uid | selector ; // .uid
group: ('group' | 'GROUP' | 'g') '(' selector (',' selector)* ')'; /*
groupby
-------
The 'groupby' construct implments the SQL "GROUP BY" clause.
.payment | .customer_id, sum(.amount) | groupby(.customer_id)
Syonyms:
- 'group_by' for jq interoperability.
https://stedolan.github.io/jq/manual/v1.6/#group_by(path_expression)
- 'group': for legacy sq compabibility. Should this be deprecated and removed?
*/
GROUP_BY: 'groupby' | 'group_by';
group: GROUP_BY '(' selector (',' selector)* ')';
/* /*
orderby orderby
------
The "orderby" construct implements the SQL "ORDER BY" clause. The 'orderby' construct implements the SQL "ORDER BY" clause.
.actor | orderby(.first_name, .last_name) .actor | orderby(.first_name, .last_name)
.actor | orderby(.first_name+) .actor | orderby(.first_name+)
@ -45,10 +61,12 @@ The "orderby" construct implements the SQL "ORDER BY" clause.
The optional plus/minus tokens specify ASC or DESC order. The optional plus/minus tokens specify ASC or DESC order.
For jq compatability, the "sort_by" synonym is provided. Synonyms:
See: https://stedolan.github.io/jq/manual/v1.6/#sort,sort_by(path_expression)
We do not implement a "sort" synonym for the jq "sort" function, because SQL - 'sort_by' for jq interoperability.
https://stedolan.github.io/jq/manual/v1.6/#sort,sort_by(path_expression)
We do not implement a 'sort' synonym for the jq 'sort' function, because SQL
results are inherently sorted. Although perhaps it should be implemented results are inherently sorted. Although perhaps it should be implemented
as a no-op. as a no-op.
*/ */

View File

@ -121,6 +121,29 @@ func (in *Inspector) FindOrderByNode() (*OrderByNode, error) {
return nil, nil //nolint:nilnil return nil, nil //nolint:nilnil
} }
// FindGroupByNode returns the GroupByNode, or nil if not found.
func (in *Inspector) FindGroupByNode() (*GroupByNode, error) {
segs := in.ast.Segments()
for i := range segs {
nodes := nodesWithType(segs[i].Children(), typeGroupByNode)
switch len(nodes) {
case 0:
// No GroupByNode in this segment, continue searching.
continue
case 1:
// Found it
node, _ := nodes[0].(*GroupByNode)
return node, nil
default:
// Shouldn't be possible
return nil, errorf("Segment {%s} has %d GroupByNode children, but should have a max of 1", segs[i])
}
}
return nil, nil //nolint:nilnil
}
// FindSelectableSegments returns the segments that have at least one child // FindSelectableSegments returns the segments that have at least one child
// that implements Selectable. // that implements Selectable.
func (in *Inspector) FindSelectableSegments() []*SegmentNode { func (in *Inspector) FindSelectableSegments() []*SegmentNode {

File diff suppressed because one or more lines are too long

View File

@ -21,72 +21,67 @@ T__19=20
T__20=21 T__20=21
T__21=22 T__21=22
T__22=23 T__22=23
T__23=24 GROUP_BY=24
T__24=25 ORDER_ASC=25
T__25=26 ORDER_DESC=26
ORDER_ASC=27 ORDER_BY=27
ORDER_DESC=28 ID=28
ORDER_BY=29 WS=29
ID=30 LPAR=30
WS=31 RPAR=31
LPAR=32 LBRA=32
RPAR=33 RBRA=33
LBRA=34 COMMA=34
RBRA=35 PIPE=35
COMMA=36 COLON=36
PIPE=37 NULL=37
COLON=38 NN=38
NULL=39 NUMBER=39
NN=40 LT_EQ=40
NUMBER=41 LT=41
LT_EQ=42 GT_EQ=42
LT=43 GT=43
GT_EQ=44 NEQ=44
GT=45 EQ=45
NEQ=46 NAME=46
EQ=47 HANDLE=47
NAME=48 STRING=48
HANDLE=49 LINECOMMENT=49
STRING=50
LINECOMMENT=51
';'=1 ';'=1
'*'=2 '*'=2
'join'=3 'join'=3
'JOIN'=4 'JOIN'=4
'j'=5 'j'=5
'group'=6 '.['=6
'GROUP'=7 'sum'=7
'g'=8 'SUM'=8
'.['=9 'avg'=9
'sum'=10 'AVG'=10
'SUM'=11 'count'=11
'avg'=12 'COUNT'=12
'AVG'=13 'where'=13
'count'=14 'WHERE'=14
'COUNT'=15 '||'=15
'where'=16 '/'=16
'WHERE'=17 '%'=17
'||'=18 '<<'=18
'/'=19 '>>'=19
'%'=20 '&'=20
'<<'=21 '&&'=21
'>>'=22 '~'=22
'&'=23 '!'=23
'&&'=24 '+'=25
'~'=25 '-'=26
'!'=26 '('=30
'+'=27 ')'=31
'-'=28 '['=32
'('=32 ']'=33
')'=33 ','=34
'['=34 '|'=35
']'=35 ':'=36
','=36 '<='=40
'|'=37 '<'=41
':'=38 '>='=42
'<='=42 '>'=43
'<'=43 '!='=44
'>='=44 '=='=45
'>'=45
'!='=46
'=='=47

File diff suppressed because one or more lines are too long

View File

@ -21,72 +21,67 @@ T__19=20
T__20=21 T__20=21
T__21=22 T__21=22
T__22=23 T__22=23
T__23=24 GROUP_BY=24
T__24=25 ORDER_ASC=25
T__25=26 ORDER_DESC=26
ORDER_ASC=27 ORDER_BY=27
ORDER_DESC=28 ID=28
ORDER_BY=29 WS=29
ID=30 LPAR=30
WS=31 RPAR=31
LPAR=32 LBRA=32
RPAR=33 RBRA=33
LBRA=34 COMMA=34
RBRA=35 PIPE=35
COMMA=36 COLON=36
PIPE=37 NULL=37
COLON=38 NN=38
NULL=39 NUMBER=39
NN=40 LT_EQ=40
NUMBER=41 LT=41
LT_EQ=42 GT_EQ=42
LT=43 GT=43
GT_EQ=44 NEQ=44
GT=45 EQ=45
NEQ=46 NAME=46
EQ=47 HANDLE=47
NAME=48 STRING=48
HANDLE=49 LINECOMMENT=49
STRING=50
LINECOMMENT=51
';'=1 ';'=1
'*'=2 '*'=2
'join'=3 'join'=3
'JOIN'=4 'JOIN'=4
'j'=5 'j'=5
'group'=6 '.['=6
'GROUP'=7 'sum'=7
'g'=8 'SUM'=8
'.['=9 'avg'=9
'sum'=10 'AVG'=10
'SUM'=11 'count'=11
'avg'=12 'COUNT'=12
'AVG'=13 'where'=13
'count'=14 'WHERE'=14
'COUNT'=15 '||'=15
'where'=16 '/'=16
'WHERE'=17 '%'=17
'||'=18 '<<'=18
'/'=19 '>>'=19
'%'=20 '&'=20
'<<'=21 '&&'=21
'>>'=22 '~'=22
'&'=23 '!'=23
'&&'=24 '+'=25
'~'=25 '-'=26
'!'=26 '('=30
'+'=27 ')'=31
'-'=28 '['=32
'('=32 ']'=33
')'=33 ','=34
'['=34 '|'=35
']'=35 ':'=36
','=36 '<='=40
'|'=37 '<'=41
':'=38 '>='=42
'<='=42 '>'=43
'<'=43 '!='=44
'>='=44 '=='=45
'>'=45
'!='=46
'=='=47

View File

@ -44,15 +44,15 @@ func slqlexerLexerInit() {
"DEFAULT_MODE", "DEFAULT_MODE",
} }
staticData.literalNames = []string{ staticData.literalNames = []string{
"", "';'", "'*'", "'join'", "'JOIN'", "'j'", "'group'", "'GROUP'", "'g'", "", "';'", "'*'", "'join'", "'JOIN'", "'j'", "'.['", "'sum'", "'SUM'",
"'.['", "'sum'", "'SUM'", "'avg'", "'AVG'", "'count'", "'COUNT'", "'where'", "'avg'", "'AVG'", "'count'", "'COUNT'", "'where'", "'WHERE'", "'||'",
"'WHERE'", "'||'", "'/'", "'%'", "'<<'", "'>>'", "'&'", "'&&'", "'~'", "'/'", "'%'", "'<<'", "'>>'", "'&'", "'&&'", "'~'", "'!'", "", "'+'",
"'!'", "'+'", "'-'", "", "", "", "'('", "')'", "'['", "']'", "','", "'-'", "", "", "", "'('", "')'", "'['", "']'", "','", "'|'", "':'",
"'|'", "':'", "", "", "", "'<='", "'<'", "'>='", "'>'", "'!='", "'=='", "", "", "", "'<='", "'<'", "'>='", "'>'", "'!='", "'=='",
} }
staticData.symbolicNames = []string{ staticData.symbolicNames = []string{
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "ORDER_ASC", "ORDER_DESC", "ORDER_BY", "", "", "", "", "", "", "", "GROUP_BY", "ORDER_ASC", "ORDER_DESC", "ORDER_BY",
"ID", "WS", "LPAR", "RPAR", "LBRA", "RBRA", "COMMA", "PIPE", "COLON", "ID", "WS", "LPAR", "RPAR", "LBRA", "RBRA", "COMMA", "PIPE", "COLON",
"NULL", "NN", "NUMBER", "LT_EQ", "LT", "GT_EQ", "GT", "NEQ", "EQ", "NAME", "NULL", "NN", "NUMBER", "LT_EQ", "LT", "GT_EQ", "GT", "NEQ", "EQ", "NAME",
"HANDLE", "STRING", "LINECOMMENT", "HANDLE", "STRING", "LINECOMMENT",
@ -60,17 +60,17 @@ func slqlexerLexerInit() {
staticData.ruleNames = []string{ staticData.ruleNames = []string{
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16", "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24", "T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "GROUP_BY", "ORDER_ASC",
"T__25", "ORDER_ASC", "ORDER_DESC", "ORDER_BY", "ID", "WS", "LPAR", "ORDER_DESC", "ORDER_BY", "ID", "WS", "LPAR", "RPAR", "LBRA", "RBRA",
"RPAR", "LBRA", "RBRA", "COMMA", "PIPE", "COLON", "NULL", "NN", "NUMBER", "COMMA", "PIPE", "COLON", "NULL", "NN", "NUMBER", "INTF", "EXP", "LT_EQ",
"INTF", "EXP", "LT_EQ", "LT", "GT_EQ", "GT", "NEQ", "EQ", "NAME", "HANDLE", "LT", "GT_EQ", "GT", "NEQ", "EQ", "NAME", "HANDLE", "STRING", "ESC",
"STRING", "ESC", "UNICODE", "HEX", "DIGIT", "A", "B", "C", "D", "E", "UNICODE", "HEX", "DIGIT", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
"T", "U", "V", "W", "X", "Y", "Z", "LINECOMMENT", "X", "Y", "Z", "LINECOMMENT",
} }
staticData.predictionContextCache = antlr.NewPredictionContextCache() staticData.predictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{ staticData.serializedATN = []int32{
4, 0, 51, 478, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 0, 49, 477, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2,
4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2,
10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15,
7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7,
@ -85,203 +85,203 @@ func slqlexerLexerInit() {
62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67,
2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2,
73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78,
7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 1, 0, 1, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2,
0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5,
3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8,
6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10,
10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1,
1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14,
14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1,
1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23,
19, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1,
1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 23, 1, 23, 1, 23, 3, 23, 260, 8, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26,
28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1,
1, 28, 1, 28, 3, 28, 281, 8, 28, 1, 29, 1, 29, 5, 29, 285, 8, 29, 10, 29, 26, 1, 26, 1, 26, 3, 26, 280, 8, 26, 1, 27, 1, 27, 5, 27, 284, 8, 27, 10,
12, 29, 288, 9, 29, 1, 30, 4, 30, 291, 8, 30, 11, 30, 12, 30, 292, 1, 30, 27, 12, 27, 287, 9, 27, 1, 28, 4, 28, 290, 8, 28, 11, 28, 12, 28, 291,
1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 32, 1, 32, 1,
35, 1, 36, 1, 36, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 33, 1, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36,
1, 38, 1, 38, 3, 38, 319, 8, 38, 1, 39, 1, 39, 1, 40, 1, 40, 3, 40, 325, 1, 36, 1, 36, 1, 36, 3, 36, 318, 8, 36, 1, 37, 1, 37, 1, 38, 1, 38, 3,
8, 40, 1, 40, 1, 40, 1, 40, 4, 40, 330, 8, 40, 11, 40, 12, 40, 331, 1, 38, 324, 8, 38, 1, 38, 1, 38, 1, 38, 4, 38, 329, 8, 38, 11, 38, 12, 38,
40, 3, 40, 335, 8, 40, 1, 40, 3, 40, 338, 8, 40, 1, 40, 1, 40, 1, 40, 1, 330, 1, 38, 3, 38, 334, 8, 38, 1, 38, 3, 38, 337, 8, 38, 1, 38, 1, 38,
40, 3, 40, 344, 8, 40, 1, 40, 3, 40, 347, 8, 40, 1, 41, 1, 41, 1, 41, 5, 1, 38, 1, 38, 3, 38, 343, 8, 38, 1, 38, 3, 38, 346, 8, 38, 1, 39, 1, 39,
41, 352, 8, 41, 10, 41, 12, 41, 355, 9, 41, 3, 41, 357, 8, 41, 1, 42, 1, 1, 39, 5, 39, 351, 8, 39, 10, 39, 12, 39, 354, 9, 39, 3, 39, 356, 8, 39,
42, 3, 42, 361, 8, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 40, 1, 40, 3, 40, 360, 8, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1,
1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 46,
48, 1, 49, 1, 49, 1, 49, 3, 49, 384, 8, 49, 1, 50, 1, 50, 1, 50, 1, 51, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 3, 47, 383, 8, 47, 1, 48, 1, 48, 1,
1, 51, 1, 51, 5, 51, 392, 8, 51, 10, 51, 12, 51, 395, 9, 51, 1, 51, 1, 48, 1, 49, 1, 49, 1, 49, 5, 49, 391, 8, 49, 10, 49, 12, 49, 394, 9, 49,
51, 1, 52, 1, 52, 1, 52, 3, 52, 402, 8, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 3, 50, 401, 8, 50, 1, 51, 1, 51, 1,
1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55,
58, 1, 58, 1, 59, 1, 59, 1, 60, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 63, 1, 55, 1, 56, 1, 56, 1, 57, 1, 57, 1, 58, 1, 58, 1, 59, 1, 59, 1, 60, 1,
1, 63, 1, 64, 1, 64, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 68, 1, 60, 1, 61, 1, 61, 1, 62, 1, 62, 1, 63, 1, 63, 1, 64, 1, 64, 1, 65, 1, 65,
68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 66, 1, 66, 1, 67, 1, 67, 1, 68, 1, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1,
1, 74, 1, 74, 1, 75, 1, 75, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 71, 1, 71, 1, 72, 1, 72, 1, 73, 1, 73, 1, 74, 1, 74, 1, 75, 1, 75, 1, 76,
79, 1, 79, 1, 80, 1, 80, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 5, 82, 1, 76, 1, 77, 1, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1,
470, 8, 82, 10, 82, 12, 82, 473, 9, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 80, 5, 80, 469, 8, 80, 10, 80, 12, 80, 472, 9, 80, 1, 80, 1, 80, 1, 80,
471, 0, 83, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 1, 80, 1, 470, 0, 81, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8,
10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17,
19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26,
28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35,
37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 0, 85, 0, 87, 42, 89, 43, 91, 44, 71, 36, 73, 37, 75, 38, 77, 39, 79, 0, 81, 0, 83, 40, 85, 41, 87, 42, 89,
93, 45, 95, 46, 97, 47, 99, 48, 101, 49, 103, 50, 105, 0, 107, 0, 109, 43, 91, 44, 93, 45, 95, 46, 97, 47, 99, 48, 101, 0, 103, 0, 105, 0, 107,
0, 111, 0, 113, 0, 115, 0, 117, 0, 119, 0, 121, 0, 123, 0, 125, 0, 127, 0, 109, 0, 111, 0, 113, 0, 115, 0, 117, 0, 119, 0, 121, 0, 123, 0, 125,
0, 129, 0, 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 127, 0, 129, 0, 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143,
0, 147, 0, 149, 0, 151, 0, 153, 0, 155, 0, 157, 0, 159, 0, 161, 0, 163, 0, 145, 0, 147, 0, 149, 0, 151, 0, 153, 0, 155, 0, 157, 0, 159, 0, 161,
0, 165, 51, 1, 0, 35, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 49, 1, 0, 35, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95,
90, 95, 95, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 1, 0, 49, 95, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 1, 0, 48, 57, 1, 0, 49, 57, 2,
57, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 34, 34, 92, 92, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 34, 34, 92, 92, 8, 0,
8, 0, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116,
116, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 65, 97, 97, 2, 0, 66, 66, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 65, 65, 97, 97, 2, 0, 66, 66, 98,
98, 98, 2, 0, 67, 67, 99, 99, 2, 0, 68, 68, 100, 100, 2, 0, 70, 70, 102, 98, 2, 0, 67, 67, 99, 99, 2, 0, 68, 68, 100, 100, 2, 0, 70, 70, 102, 102,
102, 2, 0, 71, 71, 103, 103, 2, 0, 72, 72, 104, 104, 2, 0, 73, 73, 105, 2, 0, 71, 71, 103, 103, 2, 0, 72, 72, 104, 104, 2, 0, 73, 73, 105, 105,
105, 2, 0, 74, 74, 106, 106, 2, 0, 75, 75, 107, 107, 2, 0, 76, 76, 108, 2, 0, 74, 74, 106, 106, 2, 0, 75, 75, 107, 107, 2, 0, 76, 76, 108, 108,
108, 2, 0, 77, 77, 109, 109, 2, 0, 78, 78, 110, 110, 2, 0, 79, 79, 111, 2, 0, 77, 77, 109, 109, 2, 0, 78, 78, 110, 110, 2, 0, 79, 79, 111, 111,
111, 2, 0, 80, 80, 112, 112, 2, 0, 81, 81, 113, 113, 2, 0, 82, 82, 114, 2, 0, 80, 80, 112, 112, 2, 0, 81, 81, 113, 113, 2, 0, 82, 82, 114, 114,
114, 2, 0, 83, 83, 115, 115, 2, 0, 84, 84, 116, 116, 2, 0, 85, 85, 117, 2, 0, 83, 83, 115, 115, 2, 0, 84, 84, 116, 116, 2, 0, 85, 85, 117, 117,
117, 2, 0, 86, 86, 118, 118, 2, 0, 87, 87, 119, 119, 2, 0, 88, 88, 120, 2, 0, 86, 86, 118, 118, 2, 0, 87, 87, 119, 119, 2, 0, 88, 88, 120, 120,
120, 2, 0, 89, 89, 121, 121, 2, 0, 90, 90, 122, 122, 465, 0, 1, 1, 0, 0, 2, 0, 89, 89, 121, 121, 2, 0, 90, 90, 122, 122, 465, 0, 1, 1, 0, 0, 0,
0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0,
0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0,
0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0,
0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1,
1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41,
41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0,
0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0,
0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0,
0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0,
0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 83, 1,
1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91,
91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0,
0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 165, 1, 0, 99, 1, 0, 0, 0, 0, 161, 1, 0, 0, 0, 1, 163, 1, 0, 0, 0, 3, 165, 1, 0, 0,
0, 0, 1, 167, 1, 0, 0, 0, 3, 169, 1, 0, 0, 0, 5, 171, 1, 0, 0, 0, 7, 176, 0, 5, 167, 1, 0, 0, 0, 7, 172, 1, 0, 0, 0, 9, 177, 1, 0, 0, 0, 11, 179,
1, 0, 0, 0, 9, 181, 1, 0, 0, 0, 11, 183, 1, 0, 0, 0, 13, 189, 1, 0, 0, 1, 0, 0, 0, 13, 182, 1, 0, 0, 0, 15, 186, 1, 0, 0, 0, 17, 190, 1, 0, 0,
0, 15, 195, 1, 0, 0, 0, 17, 197, 1, 0, 0, 0, 19, 200, 1, 0, 0, 0, 21, 204, 0, 19, 194, 1, 0, 0, 0, 21, 198, 1, 0, 0, 0, 23, 204, 1, 0, 0, 0, 25, 210,
1, 0, 0, 0, 23, 208, 1, 0, 0, 0, 25, 212, 1, 0, 0, 0, 27, 216, 1, 0, 0, 1, 0, 0, 0, 27, 216, 1, 0, 0, 0, 29, 222, 1, 0, 0, 0, 31, 225, 1, 0, 0,
0, 29, 222, 1, 0, 0, 0, 31, 228, 1, 0, 0, 0, 33, 234, 1, 0, 0, 0, 35, 240, 0, 33, 227, 1, 0, 0, 0, 35, 229, 1, 0, 0, 0, 37, 232, 1, 0, 0, 0, 39, 235,
1, 0, 0, 0, 37, 243, 1, 0, 0, 0, 39, 245, 1, 0, 0, 0, 41, 247, 1, 0, 0, 1, 0, 0, 0, 41, 237, 1, 0, 0, 0, 43, 240, 1, 0, 0, 0, 45, 242, 1, 0, 0,
0, 43, 250, 1, 0, 0, 0, 45, 253, 1, 0, 0, 0, 47, 255, 1, 0, 0, 0, 49, 258, 0, 47, 259, 1, 0, 0, 0, 49, 261, 1, 0, 0, 0, 51, 263, 1, 0, 0, 0, 53, 279,
1, 0, 0, 0, 51, 260, 1, 0, 0, 0, 53, 262, 1, 0, 0, 0, 55, 264, 1, 0, 0, 1, 0, 0, 0, 55, 281, 1, 0, 0, 0, 57, 289, 1, 0, 0, 0, 59, 295, 1, 0, 0,
0, 57, 280, 1, 0, 0, 0, 59, 282, 1, 0, 0, 0, 61, 290, 1, 0, 0, 0, 63, 296, 0, 61, 297, 1, 0, 0, 0, 63, 299, 1, 0, 0, 0, 65, 301, 1, 0, 0, 0, 67, 303,
1, 0, 0, 0, 65, 298, 1, 0, 0, 0, 67, 300, 1, 0, 0, 0, 69, 302, 1, 0, 0, 1, 0, 0, 0, 69, 305, 1, 0, 0, 0, 71, 307, 1, 0, 0, 0, 73, 317, 1, 0, 0,
0, 71, 304, 1, 0, 0, 0, 73, 306, 1, 0, 0, 0, 75, 308, 1, 0, 0, 0, 77, 318, 0, 75, 319, 1, 0, 0, 0, 77, 345, 1, 0, 0, 0, 79, 355, 1, 0, 0, 0, 81, 357,
1, 0, 0, 0, 79, 320, 1, 0, 0, 0, 81, 346, 1, 0, 0, 0, 83, 356, 1, 0, 0, 1, 0, 0, 0, 83, 363, 1, 0, 0, 0, 85, 366, 1, 0, 0, 0, 87, 368, 1, 0, 0,
0, 85, 358, 1, 0, 0, 0, 87, 364, 1, 0, 0, 0, 89, 367, 1, 0, 0, 0, 91, 369, 0, 89, 371, 1, 0, 0, 0, 91, 373, 1, 0, 0, 0, 93, 376, 1, 0, 0, 0, 95, 379,
1, 0, 0, 0, 93, 372, 1, 0, 0, 0, 95, 374, 1, 0, 0, 0, 97, 377, 1, 0, 0, 1, 0, 0, 0, 97, 384, 1, 0, 0, 0, 99, 387, 1, 0, 0, 0, 101, 397, 1, 0, 0,
0, 99, 380, 1, 0, 0, 0, 101, 385, 1, 0, 0, 0, 103, 388, 1, 0, 0, 0, 105, 0, 103, 402, 1, 0, 0, 0, 105, 408, 1, 0, 0, 0, 107, 410, 1, 0, 0, 0, 109,
398, 1, 0, 0, 0, 107, 403, 1, 0, 0, 0, 109, 409, 1, 0, 0, 0, 111, 411, 412, 1, 0, 0, 0, 111, 414, 1, 0, 0, 0, 113, 416, 1, 0, 0, 0, 115, 418,
1, 0, 0, 0, 113, 413, 1, 0, 0, 0, 115, 415, 1, 0, 0, 0, 117, 417, 1, 0, 1, 0, 0, 0, 117, 420, 1, 0, 0, 0, 119, 422, 1, 0, 0, 0, 121, 424, 1, 0,
0, 0, 119, 419, 1, 0, 0, 0, 121, 421, 1, 0, 0, 0, 123, 423, 1, 0, 0, 0, 0, 0, 123, 426, 1, 0, 0, 0, 125, 428, 1, 0, 0, 0, 127, 430, 1, 0, 0, 0,
125, 425, 1, 0, 0, 0, 127, 427, 1, 0, 0, 0, 129, 429, 1, 0, 0, 0, 131, 129, 432, 1, 0, 0, 0, 131, 434, 1, 0, 0, 0, 133, 436, 1, 0, 0, 0, 135,
431, 1, 0, 0, 0, 133, 433, 1, 0, 0, 0, 135, 435, 1, 0, 0, 0, 137, 437, 438, 1, 0, 0, 0, 137, 440, 1, 0, 0, 0, 139, 442, 1, 0, 0, 0, 141, 444,
1, 0, 0, 0, 139, 439, 1, 0, 0, 0, 141, 441, 1, 0, 0, 0, 143, 443, 1, 0, 1, 0, 0, 0, 143, 446, 1, 0, 0, 0, 145, 448, 1, 0, 0, 0, 147, 450, 1, 0,
0, 0, 145, 445, 1, 0, 0, 0, 147, 447, 1, 0, 0, 0, 149, 449, 1, 0, 0, 0, 0, 0, 149, 452, 1, 0, 0, 0, 151, 454, 1, 0, 0, 0, 153, 456, 1, 0, 0, 0,
151, 451, 1, 0, 0, 0, 153, 453, 1, 0, 0, 0, 155, 455, 1, 0, 0, 0, 157, 155, 458, 1, 0, 0, 0, 157, 460, 1, 0, 0, 0, 159, 462, 1, 0, 0, 0, 161,
457, 1, 0, 0, 0, 159, 459, 1, 0, 0, 0, 161, 461, 1, 0, 0, 0, 163, 463, 464, 1, 0, 0, 0, 163, 164, 5, 59, 0, 0, 164, 2, 1, 0, 0, 0, 165, 166, 5,
1, 0, 0, 0, 165, 465, 1, 0, 0, 0, 167, 168, 5, 59, 0, 0, 168, 2, 1, 0, 42, 0, 0, 166, 4, 1, 0, 0, 0, 167, 168, 5, 106, 0, 0, 168, 169, 5, 111,
0, 0, 169, 170, 5, 42, 0, 0, 170, 4, 1, 0, 0, 0, 171, 172, 5, 106, 0, 0, 0, 0, 169, 170, 5, 105, 0, 0, 170, 171, 5, 110, 0, 0, 171, 6, 1, 0, 0,
172, 173, 5, 111, 0, 0, 173, 174, 5, 105, 0, 0, 174, 175, 5, 110, 0, 0, 0, 172, 173, 5, 74, 0, 0, 173, 174, 5, 79, 0, 0, 174, 175, 5, 73, 0, 0,
175, 6, 1, 0, 0, 0, 176, 177, 5, 74, 0, 0, 177, 178, 5, 79, 0, 0, 178, 175, 176, 5, 78, 0, 0, 176, 8, 1, 0, 0, 0, 177, 178, 5, 106, 0, 0, 178,
179, 5, 73, 0, 0, 179, 180, 5, 78, 0, 0, 180, 8, 1, 0, 0, 0, 181, 182, 10, 1, 0, 0, 0, 179, 180, 5, 46, 0, 0, 180, 181, 5, 91, 0, 0, 181, 12,
5, 106, 0, 0, 182, 10, 1, 0, 0, 0, 183, 184, 5, 103, 0, 0, 184, 185, 5, 1, 0, 0, 0, 182, 183, 5, 115, 0, 0, 183, 184, 5, 117, 0, 0, 184, 185, 5,
114, 0, 0, 185, 186, 5, 111, 0, 0, 186, 187, 5, 117, 0, 0, 187, 188, 5, 109, 0, 0, 185, 14, 1, 0, 0, 0, 186, 187, 5, 83, 0, 0, 187, 188, 5, 85,
112, 0, 0, 188, 12, 1, 0, 0, 0, 189, 190, 5, 71, 0, 0, 190, 191, 5, 82, 0, 0, 188, 189, 5, 77, 0, 0, 189, 16, 1, 0, 0, 0, 190, 191, 5, 97, 0, 0,
0, 0, 191, 192, 5, 79, 0, 0, 192, 193, 5, 85, 0, 0, 193, 194, 5, 80, 0, 191, 192, 5, 118, 0, 0, 192, 193, 5, 103, 0, 0, 193, 18, 1, 0, 0, 0, 194,
0, 194, 14, 1, 0, 0, 0, 195, 196, 5, 103, 0, 0, 196, 16, 1, 0, 0, 0, 197, 195, 5, 65, 0, 0, 195, 196, 5, 86, 0, 0, 196, 197, 5, 71, 0, 0, 197, 20,
198, 5, 46, 0, 0, 198, 199, 5, 91, 0, 0, 199, 18, 1, 0, 0, 0, 200, 201, 1, 0, 0, 0, 198, 199, 5, 99, 0, 0, 199, 200, 5, 111, 0, 0, 200, 201, 5,
5, 115, 0, 0, 201, 202, 5, 117, 0, 0, 202, 203, 5, 109, 0, 0, 203, 20, 117, 0, 0, 201, 202, 5, 110, 0, 0, 202, 203, 5, 116, 0, 0, 203, 22, 1,
1, 0, 0, 0, 204, 205, 5, 83, 0, 0, 205, 206, 5, 85, 0, 0, 206, 207, 5, 0, 0, 0, 204, 205, 5, 67, 0, 0, 205, 206, 5, 79, 0, 0, 206, 207, 5, 85,
77, 0, 0, 207, 22, 1, 0, 0, 0, 208, 209, 5, 97, 0, 0, 209, 210, 5, 118, 0, 0, 207, 208, 5, 78, 0, 0, 208, 209, 5, 84, 0, 0, 209, 24, 1, 0, 0, 0,
0, 0, 210, 211, 5, 103, 0, 0, 211, 24, 1, 0, 0, 0, 212, 213, 5, 65, 0, 210, 211, 5, 119, 0, 0, 211, 212, 5, 104, 0, 0, 212, 213, 5, 101, 0, 0,
0, 213, 214, 5, 86, 0, 0, 214, 215, 5, 71, 0, 0, 215, 26, 1, 0, 0, 0, 216, 213, 214, 5, 114, 0, 0, 214, 215, 5, 101, 0, 0, 215, 26, 1, 0, 0, 0, 216,
217, 5, 99, 0, 0, 217, 218, 5, 111, 0, 0, 218, 219, 5, 117, 0, 0, 219, 217, 5, 87, 0, 0, 217, 218, 5, 72, 0, 0, 218, 219, 5, 69, 0, 0, 219, 220,
220, 5, 110, 0, 0, 220, 221, 5, 116, 0, 0, 221, 28, 1, 0, 0, 0, 222, 223, 5, 82, 0, 0, 220, 221, 5, 69, 0, 0, 221, 28, 1, 0, 0, 0, 222, 223, 5, 124,
5, 67, 0, 0, 223, 224, 5, 79, 0, 0, 224, 225, 5, 85, 0, 0, 225, 226, 5, 0, 0, 223, 224, 5, 124, 0, 0, 224, 30, 1, 0, 0, 0, 225, 226, 5, 47, 0,
78, 0, 0, 226, 227, 5, 84, 0, 0, 227, 30, 1, 0, 0, 0, 228, 229, 5, 119, 0, 226, 32, 1, 0, 0, 0, 227, 228, 5, 37, 0, 0, 228, 34, 1, 0, 0, 0, 229,
0, 0, 229, 230, 5, 104, 0, 0, 230, 231, 5, 101, 0, 0, 231, 232, 5, 114, 230, 5, 60, 0, 0, 230, 231, 5, 60, 0, 0, 231, 36, 1, 0, 0, 0, 232, 233,
0, 0, 232, 233, 5, 101, 0, 0, 233, 32, 1, 0, 0, 0, 234, 235, 5, 87, 0, 5, 62, 0, 0, 233, 234, 5, 62, 0, 0, 234, 38, 1, 0, 0, 0, 235, 236, 5, 38,
0, 235, 236, 5, 72, 0, 0, 236, 237, 5, 69, 0, 0, 237, 238, 5, 82, 0, 0, 0, 0, 236, 40, 1, 0, 0, 0, 237, 238, 5, 38, 0, 0, 238, 239, 5, 38, 0, 0,
238, 239, 5, 69, 0, 0, 239, 34, 1, 0, 0, 0, 240, 241, 5, 124, 0, 0, 241, 239, 42, 1, 0, 0, 0, 240, 241, 5, 126, 0, 0, 241, 44, 1, 0, 0, 0, 242,
242, 5, 124, 0, 0, 242, 36, 1, 0, 0, 0, 243, 244, 5, 47, 0, 0, 244, 38, 243, 5, 33, 0, 0, 243, 46, 1, 0, 0, 0, 244, 245, 5, 103, 0, 0, 245, 246,
1, 0, 0, 0, 245, 246, 5, 37, 0, 0, 246, 40, 1, 0, 0, 0, 247, 248, 5, 60, 5, 114, 0, 0, 246, 247, 5, 111, 0, 0, 247, 248, 5, 117, 0, 0, 248, 249,
0, 0, 248, 249, 5, 60, 0, 0, 249, 42, 1, 0, 0, 0, 250, 251, 5, 62, 0, 0, 5, 112, 0, 0, 249, 250, 5, 98, 0, 0, 250, 260, 5, 121, 0, 0, 251, 252,
251, 252, 5, 62, 0, 0, 252, 44, 1, 0, 0, 0, 253, 254, 5, 38, 0, 0, 254, 5, 103, 0, 0, 252, 253, 5, 114, 0, 0, 253, 254, 5, 111, 0, 0, 254, 255,
46, 1, 0, 0, 0, 255, 256, 5, 38, 0, 0, 256, 257, 5, 38, 0, 0, 257, 48, 5, 117, 0, 0, 255, 256, 5, 112, 0, 0, 256, 257, 5, 95, 0, 0, 257, 258,
1, 0, 0, 0, 258, 259, 5, 126, 0, 0, 259, 50, 1, 0, 0, 0, 260, 261, 5, 33, 5, 98, 0, 0, 258, 260, 5, 121, 0, 0, 259, 244, 1, 0, 0, 0, 259, 251, 1,
0, 0, 261, 52, 1, 0, 0, 0, 262, 263, 5, 43, 0, 0, 263, 54, 1, 0, 0, 0, 0, 0, 0, 260, 48, 1, 0, 0, 0, 261, 262, 5, 43, 0, 0, 262, 50, 1, 0, 0,
264, 265, 5, 45, 0, 0, 265, 56, 1, 0, 0, 0, 266, 267, 5, 111, 0, 0, 267, 0, 263, 264, 5, 45, 0, 0, 264, 52, 1, 0, 0, 0, 265, 266, 5, 111, 0, 0,
268, 5, 114, 0, 0, 268, 269, 5, 100, 0, 0, 269, 270, 5, 101, 0, 0, 270, 266, 267, 5, 114, 0, 0, 267, 268, 5, 100, 0, 0, 268, 269, 5, 101, 0, 0,
271, 5, 114, 0, 0, 271, 272, 5, 98, 0, 0, 272, 281, 5, 121, 0, 0, 273, 269, 270, 5, 114, 0, 0, 270, 271, 5, 98, 0, 0, 271, 280, 5, 121, 0, 0,
274, 5, 115, 0, 0, 274, 275, 5, 111, 0, 0, 275, 276, 5, 114, 0, 0, 276, 272, 273, 5, 115, 0, 0, 273, 274, 5, 111, 0, 0, 274, 275, 5, 114, 0, 0,
277, 5, 116, 0, 0, 277, 278, 5, 95, 0, 0, 278, 279, 5, 98, 0, 0, 279, 281, 275, 276, 5, 116, 0, 0, 276, 277, 5, 95, 0, 0, 277, 278, 5, 98, 0, 0, 278,
5, 121, 0, 0, 280, 266, 1, 0, 0, 0, 280, 273, 1, 0, 0, 0, 281, 58, 1, 0, 280, 5, 121, 0, 0, 279, 265, 1, 0, 0, 0, 279, 272, 1, 0, 0, 0, 280, 54,
0, 0, 282, 286, 7, 0, 0, 0, 283, 285, 7, 1, 0, 0, 284, 283, 1, 0, 0, 0, 1, 0, 0, 0, 281, 285, 7, 0, 0, 0, 282, 284, 7, 1, 0, 0, 283, 282, 1, 0,
285, 288, 1, 0, 0, 0, 286, 284, 1, 0, 0, 0, 286, 287, 1, 0, 0, 0, 287, 0, 0, 284, 287, 1, 0, 0, 0, 285, 283, 1, 0, 0, 0, 285, 286, 1, 0, 0, 0,
60, 1, 0, 0, 0, 288, 286, 1, 0, 0, 0, 289, 291, 7, 2, 0, 0, 290, 289, 1, 286, 56, 1, 0, 0, 0, 287, 285, 1, 0, 0, 0, 288, 290, 7, 2, 0, 0, 289, 288,
0, 0, 0, 291, 292, 1, 0, 0, 0, 292, 290, 1, 0, 0, 0, 292, 293, 1, 0, 0, 1, 0, 0, 0, 290, 291, 1, 0, 0, 0, 291, 289, 1, 0, 0, 0, 291, 292, 1, 0,
0, 293, 294, 1, 0, 0, 0, 294, 295, 6, 30, 0, 0, 295, 62, 1, 0, 0, 0, 296, 0, 0, 292, 293, 1, 0, 0, 0, 293, 294, 6, 28, 0, 0, 294, 58, 1, 0, 0, 0,
297, 5, 40, 0, 0, 297, 64, 1, 0, 0, 0, 298, 299, 5, 41, 0, 0, 299, 66, 295, 296, 5, 40, 0, 0, 296, 60, 1, 0, 0, 0, 297, 298, 5, 41, 0, 0, 298,
1, 0, 0, 0, 300, 301, 5, 91, 0, 0, 301, 68, 1, 0, 0, 0, 302, 303, 5, 93, 62, 1, 0, 0, 0, 299, 300, 5, 91, 0, 0, 300, 64, 1, 0, 0, 0, 301, 302, 5,
0, 0, 303, 70, 1, 0, 0, 0, 304, 305, 5, 44, 0, 0, 305, 72, 1, 0, 0, 0, 93, 0, 0, 302, 66, 1, 0, 0, 0, 303, 304, 5, 44, 0, 0, 304, 68, 1, 0, 0,
306, 307, 5, 124, 0, 0, 307, 74, 1, 0, 0, 0, 308, 309, 5, 58, 0, 0, 309, 0, 305, 306, 5, 124, 0, 0, 306, 70, 1, 0, 0, 0, 307, 308, 5, 58, 0, 0,
76, 1, 0, 0, 0, 310, 311, 5, 110, 0, 0, 311, 312, 5, 117, 0, 0, 312, 313, 308, 72, 1, 0, 0, 0, 309, 310, 5, 110, 0, 0, 310, 311, 5, 117, 0, 0, 311,
5, 108, 0, 0, 313, 319, 5, 108, 0, 0, 314, 315, 5, 78, 0, 0, 315, 316, 312, 5, 108, 0, 0, 312, 318, 5, 108, 0, 0, 313, 314, 5, 78, 0, 0, 314,
5, 85, 0, 0, 316, 317, 5, 76, 0, 0, 317, 319, 5, 76, 0, 0, 318, 310, 1, 315, 5, 85, 0, 0, 315, 316, 5, 76, 0, 0, 316, 318, 5, 76, 0, 0, 317, 309,
0, 0, 0, 318, 314, 1, 0, 0, 0, 319, 78, 1, 0, 0, 0, 320, 321, 3, 83, 41, 1, 0, 0, 0, 317, 313, 1, 0, 0, 0, 318, 74, 1, 0, 0, 0, 319, 320, 3, 79,
0, 321, 80, 1, 0, 0, 0, 322, 347, 3, 79, 39, 0, 323, 325, 5, 45, 0, 0, 39, 0, 320, 76, 1, 0, 0, 0, 321, 346, 3, 75, 37, 0, 322, 324, 5, 45, 0,
324, 323, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325, 326, 1, 0, 0, 0, 326, 0, 323, 322, 1, 0, 0, 0, 323, 324, 1, 0, 0, 0, 324, 325, 1, 0, 0, 0, 325,
327, 3, 83, 41, 0, 327, 329, 5, 46, 0, 0, 328, 330, 7, 3, 0, 0, 329, 328, 326, 3, 79, 39, 0, 326, 328, 5, 46, 0, 0, 327, 329, 7, 3, 0, 0, 328, 327,
1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 329, 1, 0, 0, 0, 331, 332, 1, 0, 1, 0, 0, 0, 329, 330, 1, 0, 0, 0, 330, 328, 1, 0, 0, 0, 330, 331, 1, 0,
0, 0, 332, 334, 1, 0, 0, 0, 333, 335, 3, 85, 42, 0, 334, 333, 1, 0, 0, 0, 0, 331, 333, 1, 0, 0, 0, 332, 334, 3, 81, 40, 0, 333, 332, 1, 0, 0,
0, 334, 335, 1, 0, 0, 0, 335, 347, 1, 0, 0, 0, 336, 338, 5, 45, 0, 0, 337, 0, 333, 334, 1, 0, 0, 0, 334, 346, 1, 0, 0, 0, 335, 337, 5, 45, 0, 0, 336,
336, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, 339, 1, 0, 0, 0, 339, 340, 335, 1, 0, 0, 0, 336, 337, 1, 0, 0, 0, 337, 338, 1, 0, 0, 0, 338, 339,
3, 83, 41, 0, 340, 341, 3, 85, 42, 0, 341, 347, 1, 0, 0, 0, 342, 344, 5, 3, 79, 39, 0, 339, 340, 3, 81, 40, 0, 340, 346, 1, 0, 0, 0, 341, 343, 5,
45, 0, 0, 343, 342, 1, 0, 0, 0, 343, 344, 1, 0, 0, 0, 344, 345, 1, 0, 0, 45, 0, 0, 342, 341, 1, 0, 0, 0, 342, 343, 1, 0, 0, 0, 343, 344, 1, 0, 0,
0, 345, 347, 3, 83, 41, 0, 346, 322, 1, 0, 0, 0, 346, 324, 1, 0, 0, 0, 0, 344, 346, 3, 79, 39, 0, 345, 321, 1, 0, 0, 0, 345, 323, 1, 0, 0, 0,
346, 337, 1, 0, 0, 0, 346, 343, 1, 0, 0, 0, 347, 82, 1, 0, 0, 0, 348, 357, 345, 336, 1, 0, 0, 0, 345, 342, 1, 0, 0, 0, 346, 78, 1, 0, 0, 0, 347, 356,
5, 48, 0, 0, 349, 353, 7, 4, 0, 0, 350, 352, 7, 3, 0, 0, 351, 350, 1, 0, 5, 48, 0, 0, 348, 352, 7, 4, 0, 0, 349, 351, 7, 3, 0, 0, 350, 349, 1, 0,
0, 0, 352, 355, 1, 0, 0, 0, 353, 351, 1, 0, 0, 0, 353, 354, 1, 0, 0, 0, 0, 0, 351, 354, 1, 0, 0, 0, 352, 350, 1, 0, 0, 0, 352, 353, 1, 0, 0, 0,
354, 357, 1, 0, 0, 0, 355, 353, 1, 0, 0, 0, 356, 348, 1, 0, 0, 0, 356, 353, 356, 1, 0, 0, 0, 354, 352, 1, 0, 0, 0, 355, 347, 1, 0, 0, 0, 355,
349, 1, 0, 0, 0, 357, 84, 1, 0, 0, 0, 358, 360, 7, 5, 0, 0, 359, 361, 7, 348, 1, 0, 0, 0, 356, 80, 1, 0, 0, 0, 357, 359, 7, 5, 0, 0, 358, 360, 7,
6, 0, 0, 360, 359, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 362, 1, 0, 0, 6, 0, 0, 359, 358, 1, 0, 0, 0, 359, 360, 1, 0, 0, 0, 360, 361, 1, 0, 0,
0, 362, 363, 3, 83, 41, 0, 363, 86, 1, 0, 0, 0, 364, 365, 5, 60, 0, 0, 0, 361, 362, 3, 79, 39, 0, 362, 82, 1, 0, 0, 0, 363, 364, 5, 60, 0, 0,
365, 366, 5, 61, 0, 0, 366, 88, 1, 0, 0, 0, 367, 368, 5, 60, 0, 0, 368, 364, 365, 5, 61, 0, 0, 365, 84, 1, 0, 0, 0, 366, 367, 5, 60, 0, 0, 367,
90, 1, 0, 0, 0, 369, 370, 5, 62, 0, 0, 370, 371, 5, 61, 0, 0, 371, 92, 86, 1, 0, 0, 0, 368, 369, 5, 62, 0, 0, 369, 370, 5, 61, 0, 0, 370, 88,
1, 0, 0, 0, 372, 373, 5, 62, 0, 0, 373, 94, 1, 0, 0, 0, 374, 375, 5, 33, 1, 0, 0, 0, 371, 372, 5, 62, 0, 0, 372, 90, 1, 0, 0, 0, 373, 374, 5, 33,
0, 0, 375, 376, 5, 61, 0, 0, 376, 96, 1, 0, 0, 0, 377, 378, 5, 61, 0, 0, 0, 0, 374, 375, 5, 61, 0, 0, 375, 92, 1, 0, 0, 0, 376, 377, 5, 61, 0, 0,
378, 379, 5, 61, 0, 0, 379, 98, 1, 0, 0, 0, 380, 383, 5, 46, 0, 0, 381, 377, 378, 5, 61, 0, 0, 378, 94, 1, 0, 0, 0, 379, 382, 5, 46, 0, 0, 380,
384, 3, 59, 29, 0, 382, 384, 3, 103, 51, 0, 383, 381, 1, 0, 0, 0, 383, 383, 3, 55, 27, 0, 381, 383, 3, 99, 49, 0, 382, 380, 1, 0, 0, 0, 382, 381,
382, 1, 0, 0, 0, 384, 100, 1, 0, 0, 0, 385, 386, 5, 64, 0, 0, 386, 387, 1, 0, 0, 0, 383, 96, 1, 0, 0, 0, 384, 385, 5, 64, 0, 0, 385, 386, 3, 55,
3, 59, 29, 0, 387, 102, 1, 0, 0, 0, 388, 393, 5, 34, 0, 0, 389, 392, 3, 27, 0, 386, 98, 1, 0, 0, 0, 387, 392, 5, 34, 0, 0, 388, 391, 3, 101, 50,
105, 52, 0, 390, 392, 8, 7, 0, 0, 391, 389, 1, 0, 0, 0, 391, 390, 1, 0, 0, 389, 391, 8, 7, 0, 0, 390, 388, 1, 0, 0, 0, 390, 389, 1, 0, 0, 0, 391,
0, 0, 392, 395, 1, 0, 0, 0, 393, 391, 1, 0, 0, 0, 393, 394, 1, 0, 0, 0, 394, 1, 0, 0, 0, 392, 390, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 395,
394, 396, 1, 0, 0, 0, 395, 393, 1, 0, 0, 0, 396, 397, 5, 34, 0, 0, 397, 1, 0, 0, 0, 394, 392, 1, 0, 0, 0, 395, 396, 5, 34, 0, 0, 396, 100, 1, 0,
104, 1, 0, 0, 0, 398, 401, 5, 92, 0, 0, 399, 402, 7, 8, 0, 0, 400, 402, 0, 0, 397, 400, 5, 92, 0, 0, 398, 401, 7, 8, 0, 0, 399, 401, 3, 103, 51,
3, 107, 53, 0, 401, 399, 1, 0, 0, 0, 401, 400, 1, 0, 0, 0, 402, 106, 1, 0, 400, 398, 1, 0, 0, 0, 400, 399, 1, 0, 0, 0, 401, 102, 1, 0, 0, 0, 402,
0, 0, 0, 403, 404, 5, 117, 0, 0, 404, 405, 3, 109, 54, 0, 405, 406, 3, 403, 5, 117, 0, 0, 403, 404, 3, 105, 52, 0, 404, 405, 3, 105, 52, 0, 405,
109, 54, 0, 406, 407, 3, 109, 54, 0, 407, 408, 3, 109, 54, 0, 408, 108, 406, 3, 105, 52, 0, 406, 407, 3, 105, 52, 0, 407, 104, 1, 0, 0, 0, 408,
1, 0, 0, 0, 409, 410, 7, 9, 0, 0, 410, 110, 1, 0, 0, 0, 411, 412, 7, 3, 409, 7, 9, 0, 0, 409, 106, 1, 0, 0, 0, 410, 411, 7, 3, 0, 0, 411, 108,
0, 0, 412, 112, 1, 0, 0, 0, 413, 414, 7, 10, 0, 0, 414, 114, 1, 0, 0, 0, 1, 0, 0, 0, 412, 413, 7, 10, 0, 0, 413, 110, 1, 0, 0, 0, 414, 415, 7, 11,
415, 416, 7, 11, 0, 0, 416, 116, 1, 0, 0, 0, 417, 418, 7, 12, 0, 0, 418, 0, 0, 415, 112, 1, 0, 0, 0, 416, 417, 7, 12, 0, 0, 417, 114, 1, 0, 0, 0,
118, 1, 0, 0, 0, 419, 420, 7, 13, 0, 0, 420, 120, 1, 0, 0, 0, 421, 422, 418, 419, 7, 13, 0, 0, 419, 116, 1, 0, 0, 0, 420, 421, 7, 5, 0, 0, 421,
7, 5, 0, 0, 422, 122, 1, 0, 0, 0, 423, 424, 7, 14, 0, 0, 424, 124, 1, 0, 118, 1, 0, 0, 0, 422, 423, 7, 14, 0, 0, 423, 120, 1, 0, 0, 0, 424, 425,
0, 0, 425, 426, 7, 15, 0, 0, 426, 126, 1, 0, 0, 0, 427, 428, 7, 16, 0, 7, 15, 0, 0, 425, 122, 1, 0, 0, 0, 426, 427, 7, 16, 0, 0, 427, 124, 1,
0, 428, 128, 1, 0, 0, 0, 429, 430, 7, 17, 0, 0, 430, 130, 1, 0, 0, 0, 431, 0, 0, 0, 428, 429, 7, 17, 0, 0, 429, 126, 1, 0, 0, 0, 430, 431, 7, 18,
432, 7, 18, 0, 0, 432, 132, 1, 0, 0, 0, 433, 434, 7, 19, 0, 0, 434, 134, 0, 0, 431, 128, 1, 0, 0, 0, 432, 433, 7, 19, 0, 0, 433, 130, 1, 0, 0, 0,
1, 0, 0, 0, 435, 436, 7, 20, 0, 0, 436, 136, 1, 0, 0, 0, 437, 438, 7, 21, 434, 435, 7, 20, 0, 0, 435, 132, 1, 0, 0, 0, 436, 437, 7, 21, 0, 0, 437,
0, 0, 438, 138, 1, 0, 0, 0, 439, 440, 7, 22, 0, 0, 440, 140, 1, 0, 0, 0, 134, 1, 0, 0, 0, 438, 439, 7, 22, 0, 0, 439, 136, 1, 0, 0, 0, 440, 441,
441, 442, 7, 23, 0, 0, 442, 142, 1, 0, 0, 0, 443, 444, 7, 24, 0, 0, 444, 7, 23, 0, 0, 441, 138, 1, 0, 0, 0, 442, 443, 7, 24, 0, 0, 443, 140, 1,
144, 1, 0, 0, 0, 445, 446, 7, 25, 0, 0, 446, 146, 1, 0, 0, 0, 447, 448, 0, 0, 0, 444, 445, 7, 25, 0, 0, 445, 142, 1, 0, 0, 0, 446, 447, 7, 26,
7, 26, 0, 0, 448, 148, 1, 0, 0, 0, 449, 450, 7, 27, 0, 0, 450, 150, 1, 0, 0, 447, 144, 1, 0, 0, 0, 448, 449, 7, 27, 0, 0, 449, 146, 1, 0, 0, 0,
0, 0, 0, 451, 452, 7, 28, 0, 0, 452, 152, 1, 0, 0, 0, 453, 454, 7, 29, 450, 451, 7, 28, 0, 0, 451, 148, 1, 0, 0, 0, 452, 453, 7, 29, 0, 0, 453,
0, 0, 454, 154, 1, 0, 0, 0, 455, 456, 7, 30, 0, 0, 456, 156, 1, 0, 0, 0, 150, 1, 0, 0, 0, 454, 455, 7, 30, 0, 0, 455, 152, 1, 0, 0, 0, 456, 457,
457, 458, 7, 31, 0, 0, 458, 158, 1, 0, 0, 0, 459, 460, 7, 32, 0, 0, 460, 7, 31, 0, 0, 457, 154, 1, 0, 0, 0, 458, 459, 7, 32, 0, 0, 459, 156, 1,
160, 1, 0, 0, 0, 461, 462, 7, 33, 0, 0, 462, 162, 1, 0, 0, 0, 463, 464, 0, 0, 0, 460, 461, 7, 33, 0, 0, 461, 158, 1, 0, 0, 0, 462, 463, 7, 34,
7, 34, 0, 0, 464, 164, 1, 0, 0, 0, 465, 466, 5, 47, 0, 0, 466, 467, 5, 0, 0, 463, 160, 1, 0, 0, 0, 464, 465, 5, 47, 0, 0, 465, 466, 5, 47, 0,
47, 0, 0, 467, 471, 1, 0, 0, 0, 468, 470, 9, 0, 0, 0, 469, 468, 1, 0, 0, 0, 466, 470, 1, 0, 0, 0, 467, 469, 9, 0, 0, 0, 468, 467, 1, 0, 0, 0, 469,
0, 470, 473, 1, 0, 0, 0, 471, 472, 1, 0, 0, 0, 471, 469, 1, 0, 0, 0, 472, 472, 1, 0, 0, 0, 470, 471, 1, 0, 0, 0, 470, 468, 1, 0, 0, 0, 471, 473,
474, 1, 0, 0, 0, 473, 471, 1, 0, 0, 0, 474, 475, 5, 10, 0, 0, 475, 476, 1, 0, 0, 0, 472, 470, 1, 0, 0, 0, 473, 474, 5, 10, 0, 0, 474, 475, 1, 0,
1, 0, 0, 0, 476, 477, 6, 82, 0, 0, 477, 166, 1, 0, 0, 0, 19, 0, 280, 286, 0, 0, 475, 476, 6, 80, 0, 0, 476, 162, 1, 0, 0, 0, 20, 0, 259, 279, 285,
292, 318, 324, 331, 334, 337, 343, 346, 353, 356, 360, 383, 391, 393, 401, 291, 317, 323, 330, 333, 336, 342, 345, 352, 355, 359, 382, 390, 392, 400,
471, 1, 6, 0, 0, 470, 1, 6, 0, 0,
} }
deserializer := antlr.NewATNDeserializer(nil) deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN) staticData.atn = deserializer.Deserialize(staticData.serializedATN)
@ -345,32 +345,30 @@ const (
SLQLexerT__20 = 21 SLQLexerT__20 = 21
SLQLexerT__21 = 22 SLQLexerT__21 = 22
SLQLexerT__22 = 23 SLQLexerT__22 = 23
SLQLexerT__23 = 24 SLQLexerGROUP_BY = 24
SLQLexerT__24 = 25 SLQLexerORDER_ASC = 25
SLQLexerT__25 = 26 SLQLexerORDER_DESC = 26
SLQLexerORDER_ASC = 27 SLQLexerORDER_BY = 27
SLQLexerORDER_DESC = 28 SLQLexerID = 28
SLQLexerORDER_BY = 29 SLQLexerWS = 29
SLQLexerID = 30 SLQLexerLPAR = 30
SLQLexerWS = 31 SLQLexerRPAR = 31
SLQLexerLPAR = 32 SLQLexerLBRA = 32
SLQLexerRPAR = 33 SLQLexerRBRA = 33
SLQLexerLBRA = 34 SLQLexerCOMMA = 34
SLQLexerRBRA = 35 SLQLexerPIPE = 35
SLQLexerCOMMA = 36 SLQLexerCOLON = 36
SLQLexerPIPE = 37 SLQLexerNULL = 37
SLQLexerCOLON = 38 SLQLexerNN = 38
SLQLexerNULL = 39 SLQLexerNUMBER = 39
SLQLexerNN = 40 SLQLexerLT_EQ = 40
SLQLexerNUMBER = 41 SLQLexerLT = 41
SLQLexerLT_EQ = 42 SLQLexerGT_EQ = 42
SLQLexerLT = 43 SLQLexerGT = 43
SLQLexerGT_EQ = 44 SLQLexerNEQ = 44
SLQLexerGT = 45 SLQLexerEQ = 45
SLQLexerNEQ = 46 SLQLexerNAME = 46
SLQLexerEQ = 47 SLQLexerHANDLE = 47
SLQLexerNAME = 48 SLQLexerSTRING = 48
SLQLexerHANDLE = 49 SLQLexerLINECOMMENT = 49
SLQLexerSTRING = 50
SLQLexerLINECOMMENT = 51
) )

View File

@ -32,15 +32,15 @@ var slqParserStaticData struct {
func slqParserInit() { func slqParserInit() {
staticData := &slqParserStaticData staticData := &slqParserStaticData
staticData.literalNames = []string{ staticData.literalNames = []string{
"", "';'", "'*'", "'join'", "'JOIN'", "'j'", "'group'", "'GROUP'", "'g'", "", "';'", "'*'", "'join'", "'JOIN'", "'j'", "'.['", "'sum'", "'SUM'",
"'.['", "'sum'", "'SUM'", "'avg'", "'AVG'", "'count'", "'COUNT'", "'where'", "'avg'", "'AVG'", "'count'", "'COUNT'", "'where'", "'WHERE'", "'||'",
"'WHERE'", "'||'", "'/'", "'%'", "'<<'", "'>>'", "'&'", "'&&'", "'~'", "'/'", "'%'", "'<<'", "'>>'", "'&'", "'&&'", "'~'", "'!'", "", "'+'",
"'!'", "'+'", "'-'", "", "", "", "'('", "')'", "'['", "']'", "','", "'-'", "", "", "", "'('", "')'", "'['", "']'", "','", "'|'", "':'",
"'|'", "':'", "", "", "", "'<='", "'<'", "'>='", "'>'", "'!='", "'=='", "", "", "", "'<='", "'<'", "'>='", "'>'", "'!='", "'=='",
} }
staticData.symbolicNames = []string{ staticData.symbolicNames = []string{
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "ORDER_ASC", "ORDER_DESC", "ORDER_BY", "", "", "", "", "", "", "", "GROUP_BY", "ORDER_ASC", "ORDER_DESC", "ORDER_BY",
"ID", "WS", "LPAR", "RPAR", "LBRA", "RBRA", "COMMA", "PIPE", "COLON", "ID", "WS", "LPAR", "RPAR", "LBRA", "RBRA", "COMMA", "PIPE", "COLON",
"NULL", "NN", "NUMBER", "LT_EQ", "LT", "GT_EQ", "GT", "NEQ", "EQ", "NAME", "NULL", "NN", "NUMBER", "LT_EQ", "LT", "GT_EQ", "GT", "NEQ", "EQ", "NAME",
"HANDLE", "STRING", "LINECOMMENT", "HANDLE", "STRING", "LINECOMMENT",
@ -53,7 +53,7 @@ func slqParserInit() {
} }
staticData.predictionContextCache = antlr.NewPredictionContextCache() staticData.predictionContextCache = antlr.NewPredictionContextCache()
staticData.serializedATN = []int32{ staticData.serializedATN = []int32{
4, 1, 51, 231, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 1, 49, 231, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7,
4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7,
10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15,
2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2,
@ -77,85 +77,85 @@ func slqParserInit() {
19, 1, 19, 1, 19, 3, 19, 216, 8, 19, 1, 19, 1, 19, 1, 19, 1, 19, 5, 19, 19, 1, 19, 1, 19, 3, 19, 216, 8, 19, 1, 19, 1, 19, 1, 19, 1, 19, 5, 19,
222, 8, 19, 10, 19, 12, 19, 225, 9, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 222, 8, 19, 10, 19, 12, 19, 225, 9, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1,
21, 0, 1, 38, 22, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 21, 0, 1, 38, 22, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28,
30, 32, 34, 36, 38, 40, 42, 0, 10, 1, 0, 42, 47, 1, 0, 3, 5, 1, 0, 6, 8, 30, 32, 34, 36, 38, 40, 42, 0, 9, 1, 0, 40, 45, 1, 0, 3, 5, 1, 0, 25, 26,
1, 0, 27, 28, 1, 0, 10, 17, 2, 0, 2, 2, 19, 20, 1, 0, 21, 23, 1, 0, 42, 1, 0, 7, 14, 2, 0, 2, 2, 16, 17, 1, 0, 18, 20, 1, 0, 40, 43, 2, 0, 37,
45, 2, 0, 39, 41, 50, 50, 1, 0, 25, 28, 248, 0, 47, 1, 0, 0, 0, 2, 68, 39, 48, 48, 2, 0, 22, 23, 25, 26, 248, 0, 47, 1, 0, 0, 0, 2, 68, 1, 0,
1, 0, 0, 0, 4, 76, 1, 0, 0, 0, 6, 93, 1, 0, 0, 0, 8, 95, 1, 0, 0, 0, 10, 0, 0, 4, 76, 1, 0, 0, 0, 6, 93, 1, 0, 0, 0, 8, 95, 1, 0, 0, 0, 10, 97,
97, 1, 0, 0, 0, 12, 112, 1, 0, 0, 0, 14, 116, 1, 0, 0, 0, 16, 126, 1, 0, 1, 0, 0, 0, 12, 112, 1, 0, 0, 0, 14, 116, 1, 0, 0, 0, 16, 126, 1, 0, 0,
0, 0, 18, 128, 1, 0, 0, 0, 20, 140, 1, 0, 0, 0, 22, 144, 1, 0, 0, 0, 24, 0, 18, 128, 1, 0, 0, 0, 20, 140, 1, 0, 0, 0, 22, 144, 1, 0, 0, 0, 24, 156,
156, 1, 0, 0, 0, 26, 160, 1, 0, 0, 0, 28, 164, 1, 0, 0, 0, 30, 167, 1, 1, 0, 0, 0, 26, 160, 1, 0, 0, 0, 28, 164, 1, 0, 0, 0, 30, 167, 1, 0, 0,
0, 0, 0, 32, 170, 1, 0, 0, 0, 34, 172, 1, 0, 0, 0, 36, 185, 1, 0, 0, 0, 0, 32, 170, 1, 0, 0, 0, 34, 172, 1, 0, 0, 0, 36, 185, 1, 0, 0, 0, 38, 194,
38, 194, 1, 0, 0, 0, 40, 226, 1, 0, 0, 0, 42, 228, 1, 0, 0, 0, 44, 46, 1, 0, 0, 0, 40, 226, 1, 0, 0, 0, 42, 228, 1, 0, 0, 0, 44, 46, 5, 1, 0,
5, 1, 0, 0, 45, 44, 1, 0, 0, 0, 46, 49, 1, 0, 0, 0, 47, 45, 1, 0, 0, 0, 0, 45, 44, 1, 0, 0, 0, 46, 49, 1, 0, 0, 0, 47, 45, 1, 0, 0, 0, 47, 48,
47, 48, 1, 0, 0, 0, 48, 50, 1, 0, 0, 0, 49, 47, 1, 0, 0, 0, 50, 59, 3, 1, 0, 0, 0, 48, 50, 1, 0, 0, 0, 49, 47, 1, 0, 0, 0, 50, 59, 3, 2, 1, 0,
2, 1, 0, 51, 53, 5, 1, 0, 0, 52, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 51, 53, 5, 1, 0, 0, 52, 51, 1, 0, 0, 0, 53, 54, 1, 0, 0, 0, 54, 52, 1,
52, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 56, 1, 0, 0, 0, 56, 58, 3, 2, 1, 0, 0, 0, 54, 55, 1, 0, 0, 0, 55, 56, 1, 0, 0, 0, 56, 58, 3, 2, 1, 0, 57,
0, 57, 52, 1, 0, 0, 0, 58, 61, 1, 0, 0, 0, 59, 57, 1, 0, 0, 0, 59, 60, 52, 1, 0, 0, 0, 58, 61, 1, 0, 0, 0, 59, 57, 1, 0, 0, 0, 59, 60, 1, 0, 0,
1, 0, 0, 0, 60, 65, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 62, 64, 5, 1, 0, 0, 0, 60, 65, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 62, 64, 5, 1, 0, 0, 63, 62,
63, 62, 1, 0, 0, 0, 64, 67, 1, 0, 0, 0, 65, 63, 1, 0, 0, 0, 65, 66, 1, 1, 0, 0, 0, 64, 67, 1, 0, 0, 0, 65, 63, 1, 0, 0, 0, 65, 66, 1, 0, 0, 0,
0, 0, 0, 66, 1, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 68, 73, 3, 4, 2, 0, 69, 66, 1, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 68, 73, 3, 4, 2, 0, 69, 70, 5, 35,
70, 5, 37, 0, 0, 70, 72, 3, 4, 2, 0, 71, 69, 1, 0, 0, 0, 72, 75, 1, 0, 0, 0, 70, 72, 3, 4, 2, 0, 71, 69, 1, 0, 0, 0, 72, 75, 1, 0, 0, 0, 73, 71,
0, 0, 73, 71, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 3, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0, 73, 74, 1, 0, 0, 0, 74, 3, 1, 0, 0, 0, 75, 73, 1, 0, 0, 0,
1, 0, 0, 0, 76, 81, 3, 6, 3, 0, 77, 78, 5, 36, 0, 0, 78, 80, 3, 6, 3, 0, 76, 81, 3, 6, 3, 0, 77, 78, 5, 34, 0, 0, 78, 80, 3, 6, 3, 0, 79, 77, 1,
79, 77, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 80, 83, 1, 0, 0, 0, 81, 79, 1, 0, 0, 0, 81, 82, 1, 0, 0, 0, 82,
0, 0, 0, 82, 5, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 84, 94, 3, 30, 15, 0, 85, 5, 1, 0, 0, 0, 83, 81, 1, 0, 0, 0, 84, 94, 3, 30, 15, 0, 85, 94, 3, 32,
94, 3, 32, 16, 0, 86, 94, 3, 26, 13, 0, 87, 94, 3, 14, 7, 0, 88, 94, 3, 16, 0, 86, 94, 3, 26, 13, 0, 87, 94, 3, 14, 7, 0, 88, 94, 3, 18, 9, 0,
18, 9, 0, 89, 94, 3, 22, 11, 0, 90, 94, 3, 34, 17, 0, 91, 94, 3, 12, 6, 89, 94, 3, 22, 11, 0, 90, 94, 3, 34, 17, 0, 91, 94, 3, 12, 6, 0, 92, 94,
0, 92, 94, 3, 38, 19, 0, 93, 84, 1, 0, 0, 0, 93, 85, 1, 0, 0, 0, 93, 86, 3, 38, 19, 0, 93, 84, 1, 0, 0, 0, 93, 85, 1, 0, 0, 0, 93, 86, 1, 0, 0,
1, 0, 0, 0, 93, 87, 1, 0, 0, 0, 93, 88, 1, 0, 0, 0, 93, 89, 1, 0, 0, 0, 0, 93, 87, 1, 0, 0, 0, 93, 88, 1, 0, 0, 0, 93, 89, 1, 0, 0, 0, 93, 90,
93, 90, 1, 0, 0, 0, 93, 91, 1, 0, 0, 0, 93, 92, 1, 0, 0, 0, 94, 7, 1, 0, 1, 0, 0, 0, 93, 91, 1, 0, 0, 0, 93, 92, 1, 0, 0, 0, 94, 7, 1, 0, 0, 0,
0, 0, 95, 96, 7, 0, 0, 0, 96, 9, 1, 0, 0, 0, 97, 98, 3, 36, 18, 0, 98, 95, 96, 7, 0, 0, 0, 96, 9, 1, 0, 0, 0, 97, 98, 3, 36, 18, 0, 98, 108, 5,
108, 5, 32, 0, 0, 99, 104, 3, 38, 19, 0, 100, 101, 5, 36, 0, 0, 101, 103, 30, 0, 0, 99, 104, 3, 38, 19, 0, 100, 101, 5, 34, 0, 0, 101, 103, 3, 38,
3, 38, 19, 0, 102, 100, 1, 0, 0, 0, 103, 106, 1, 0, 0, 0, 104, 102, 1, 19, 0, 102, 100, 1, 0, 0, 0, 103, 106, 1, 0, 0, 0, 104, 102, 1, 0, 0, 0,
0, 0, 0, 104, 105, 1, 0, 0, 0, 105, 109, 1, 0, 0, 0, 106, 104, 1, 0, 0, 104, 105, 1, 0, 0, 0, 105, 109, 1, 0, 0, 0, 106, 104, 1, 0, 0, 0, 107,
0, 107, 109, 5, 2, 0, 0, 108, 99, 1, 0, 0, 0, 108, 107, 1, 0, 0, 0, 108, 109, 5, 2, 0, 0, 108, 99, 1, 0, 0, 0, 108, 107, 1, 0, 0, 0, 108, 109, 1,
109, 1, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 111, 5, 33, 0, 0, 111, 11, 0, 0, 0, 109, 110, 1, 0, 0, 0, 110, 111, 5, 31, 0, 0, 111, 11, 1, 0, 0,
1, 0, 0, 0, 112, 114, 3, 10, 5, 0, 113, 115, 3, 28, 14, 0, 114, 113, 1, 0, 112, 114, 3, 10, 5, 0, 113, 115, 3, 28, 14, 0, 114, 113, 1, 0, 0, 0,
0, 0, 0, 114, 115, 1, 0, 0, 0, 115, 13, 1, 0, 0, 0, 116, 117, 7, 1, 0, 114, 115, 1, 0, 0, 0, 115, 13, 1, 0, 0, 0, 116, 117, 7, 1, 0, 0, 117, 118,
0, 117, 118, 5, 32, 0, 0, 118, 119, 3, 16, 8, 0, 119, 120, 5, 33, 0, 0, 5, 30, 0, 0, 118, 119, 3, 16, 8, 0, 119, 120, 5, 31, 0, 0, 120, 15, 1,
120, 15, 1, 0, 0, 0, 121, 122, 3, 24, 12, 0, 122, 123, 3, 8, 4, 0, 123, 0, 0, 0, 121, 122, 3, 24, 12, 0, 122, 123, 3, 8, 4, 0, 123, 124, 3, 24,
124, 3, 24, 12, 0, 124, 127, 1, 0, 0, 0, 125, 127, 3, 24, 12, 0, 126, 121, 12, 0, 124, 127, 1, 0, 0, 0, 125, 127, 3, 24, 12, 0, 126, 121, 1, 0, 0,
1, 0, 0, 0, 126, 125, 1, 0, 0, 0, 127, 17, 1, 0, 0, 0, 128, 129, 7, 2, 0, 126, 125, 1, 0, 0, 0, 127, 17, 1, 0, 0, 0, 128, 129, 5, 24, 0, 0, 129,
0, 0, 129, 130, 5, 32, 0, 0, 130, 135, 3, 24, 12, 0, 131, 132, 5, 36, 0, 130, 5, 30, 0, 0, 130, 135, 3, 24, 12, 0, 131, 132, 5, 34, 0, 0, 132, 134,
0, 132, 134, 3, 24, 12, 0, 133, 131, 1, 0, 0, 0, 134, 137, 1, 0, 0, 0, 3, 24, 12, 0, 133, 131, 1, 0, 0, 0, 134, 137, 1, 0, 0, 0, 135, 133, 1,
135, 133, 1, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 138, 1, 0, 0, 0, 137, 0, 0, 0, 135, 136, 1, 0, 0, 0, 136, 138, 1, 0, 0, 0, 137, 135, 1, 0, 0,
135, 1, 0, 0, 0, 138, 139, 5, 33, 0, 0, 139, 19, 1, 0, 0, 0, 140, 142, 0, 138, 139, 5, 31, 0, 0, 139, 19, 1, 0, 0, 0, 140, 142, 3, 24, 12, 0,
3, 24, 12, 0, 141, 143, 7, 3, 0, 0, 142, 141, 1, 0, 0, 0, 142, 143, 1, 141, 143, 7, 2, 0, 0, 142, 141, 1, 0, 0, 0, 142, 143, 1, 0, 0, 0, 143,
0, 0, 0, 143, 21, 1, 0, 0, 0, 144, 145, 5, 29, 0, 0, 145, 146, 5, 32, 0, 21, 1, 0, 0, 0, 144, 145, 5, 27, 0, 0, 145, 146, 5, 30, 0, 0, 146, 151,
0, 146, 151, 3, 20, 10, 0, 147, 148, 5, 36, 0, 0, 148, 150, 3, 20, 10, 3, 20, 10, 0, 147, 148, 5, 34, 0, 0, 148, 150, 3, 20, 10, 0, 149, 147,
0, 149, 147, 1, 0, 0, 0, 150, 153, 1, 0, 0, 0, 151, 149, 1, 0, 0, 0, 151, 1, 0, 0, 0, 150, 153, 1, 0, 0, 0, 151, 149, 1, 0, 0, 0, 151, 152, 1, 0,
152, 1, 0, 0, 0, 152, 154, 1, 0, 0, 0, 153, 151, 1, 0, 0, 0, 154, 155, 0, 0, 152, 154, 1, 0, 0, 0, 153, 151, 1, 0, 0, 0, 154, 155, 5, 31, 0, 0,
5, 33, 0, 0, 155, 23, 1, 0, 0, 0, 156, 158, 5, 48, 0, 0, 157, 159, 5, 48, 155, 23, 1, 0, 0, 0, 156, 158, 5, 46, 0, 0, 157, 159, 5, 46, 0, 0, 158,
0, 0, 158, 157, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 25, 1, 0, 0, 0, 157, 1, 0, 0, 0, 158, 159, 1, 0, 0, 0, 159, 25, 1, 0, 0, 0, 160, 162, 3,
160, 162, 3, 24, 12, 0, 161, 163, 3, 28, 14, 0, 162, 161, 1, 0, 0, 0, 162, 24, 12, 0, 161, 163, 3, 28, 14, 0, 162, 161, 1, 0, 0, 0, 162, 163, 1, 0,
163, 1, 0, 0, 0, 163, 27, 1, 0, 0, 0, 164, 165, 5, 38, 0, 0, 165, 166, 0, 0, 163, 27, 1, 0, 0, 0, 164, 165, 5, 36, 0, 0, 165, 166, 5, 28, 0, 0,
5, 30, 0, 0, 166, 29, 1, 0, 0, 0, 167, 168, 5, 49, 0, 0, 168, 169, 5, 48, 166, 29, 1, 0, 0, 0, 167, 168, 5, 47, 0, 0, 168, 169, 5, 46, 0, 0, 169,
0, 0, 169, 31, 1, 0, 0, 0, 170, 171, 5, 49, 0, 0, 171, 33, 1, 0, 0, 0, 31, 1, 0, 0, 0, 170, 171, 5, 47, 0, 0, 171, 33, 1, 0, 0, 0, 172, 181, 5,
172, 181, 5, 9, 0, 0, 173, 174, 5, 40, 0, 0, 174, 175, 5, 38, 0, 0, 175, 6, 0, 0, 173, 174, 5, 38, 0, 0, 174, 175, 5, 36, 0, 0, 175, 182, 5, 38,
182, 5, 40, 0, 0, 176, 177, 5, 40, 0, 0, 177, 182, 5, 38, 0, 0, 178, 179, 0, 0, 176, 177, 5, 38, 0, 0, 177, 182, 5, 36, 0, 0, 178, 179, 5, 36, 0,
5, 38, 0, 0, 179, 182, 5, 40, 0, 0, 180, 182, 5, 40, 0, 0, 181, 173, 1, 0, 179, 182, 5, 38, 0, 0, 180, 182, 5, 38, 0, 0, 181, 173, 1, 0, 0, 0,
0, 0, 0, 181, 176, 1, 0, 0, 0, 181, 178, 1, 0, 0, 0, 181, 180, 1, 0, 0, 181, 176, 1, 0, 0, 0, 181, 178, 1, 0, 0, 0, 181, 180, 1, 0, 0, 0, 181,
0, 181, 182, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 184, 5, 35, 0, 0, 184, 182, 1, 0, 0, 0, 182, 183, 1, 0, 0, 0, 183, 184, 5, 33, 0, 0, 184, 35,
35, 1, 0, 0, 0, 185, 186, 7, 4, 0, 0, 186, 37, 1, 0, 0, 0, 187, 188, 6, 1, 0, 0, 0, 185, 186, 7, 3, 0, 0, 186, 37, 1, 0, 0, 0, 187, 188, 6, 19,
19, -1, 0, 188, 195, 3, 24, 12, 0, 189, 195, 3, 40, 20, 0, 190, 191, 3, -1, 0, 188, 195, 3, 24, 12, 0, 189, 195, 3, 40, 20, 0, 190, 191, 3, 42,
42, 21, 0, 191, 192, 3, 38, 19, 9, 192, 195, 1, 0, 0, 0, 193, 195, 3, 10, 21, 0, 191, 192, 3, 38, 19, 9, 192, 195, 1, 0, 0, 0, 193, 195, 3, 10, 5,
5, 0, 194, 187, 1, 0, 0, 0, 194, 189, 1, 0, 0, 0, 194, 190, 1, 0, 0, 0, 0, 194, 187, 1, 0, 0, 0, 194, 189, 1, 0, 0, 0, 194, 190, 1, 0, 0, 0, 194,
194, 193, 1, 0, 0, 0, 195, 223, 1, 0, 0, 0, 196, 197, 10, 8, 0, 0, 197, 193, 1, 0, 0, 0, 195, 223, 1, 0, 0, 0, 196, 197, 10, 8, 0, 0, 197, 198,
198, 5, 18, 0, 0, 198, 222, 3, 38, 19, 9, 199, 200, 10, 7, 0, 0, 200, 201, 5, 15, 0, 0, 198, 222, 3, 38, 19, 9, 199, 200, 10, 7, 0, 0, 200, 201, 7,
7, 5, 0, 0, 201, 222, 3, 38, 19, 8, 202, 203, 10, 6, 0, 0, 203, 204, 7, 4, 0, 0, 201, 222, 3, 38, 19, 8, 202, 203, 10, 6, 0, 0, 203, 204, 7, 2,
3, 0, 0, 204, 222, 3, 38, 19, 7, 205, 206, 10, 5, 0, 0, 206, 207, 7, 6, 0, 0, 204, 222, 3, 38, 19, 7, 205, 206, 10, 5, 0, 0, 206, 207, 7, 5, 0,
0, 0, 207, 222, 3, 38, 19, 6, 208, 209, 10, 4, 0, 0, 209, 210, 7, 7, 0, 0, 207, 222, 3, 38, 19, 6, 208, 209, 10, 4, 0, 0, 209, 210, 7, 6, 0, 0,
0, 210, 222, 3, 38, 19, 5, 211, 215, 10, 3, 0, 0, 212, 216, 5, 47, 0, 0, 210, 222, 3, 38, 19, 5, 211, 215, 10, 3, 0, 0, 212, 216, 5, 45, 0, 0, 213,
213, 216, 5, 46, 0, 0, 214, 216, 1, 0, 0, 0, 215, 212, 1, 0, 0, 0, 215, 216, 5, 44, 0, 0, 214, 216, 1, 0, 0, 0, 215, 212, 1, 0, 0, 0, 215, 213,
213, 1, 0, 0, 0, 215, 214, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 222, 1, 0, 0, 0, 215, 214, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 222, 3, 38,
3, 38, 19, 4, 218, 219, 10, 2, 0, 0, 219, 220, 5, 24, 0, 0, 220, 222, 3, 19, 4, 218, 219, 10, 2, 0, 0, 219, 220, 5, 21, 0, 0, 220, 222, 3, 38, 19,
38, 19, 3, 221, 196, 1, 0, 0, 0, 221, 199, 1, 0, 0, 0, 221, 202, 1, 0, 3, 221, 196, 1, 0, 0, 0, 221, 199, 1, 0, 0, 0, 221, 202, 1, 0, 0, 0, 221,
0, 0, 221, 205, 1, 0, 0, 0, 221, 208, 1, 0, 0, 0, 221, 211, 1, 0, 0, 0, 205, 1, 0, 0, 0, 221, 208, 1, 0, 0, 0, 221, 211, 1, 0, 0, 0, 221, 218,
221, 218, 1, 0, 0, 0, 222, 225, 1, 0, 0, 0, 223, 221, 1, 0, 0, 0, 223, 1, 0, 0, 0, 222, 225, 1, 0, 0, 0, 223, 221, 1, 0, 0, 0, 223, 224, 1, 0,
224, 1, 0, 0, 0, 224, 39, 1, 0, 0, 0, 225, 223, 1, 0, 0, 0, 226, 227, 7, 0, 0, 224, 39, 1, 0, 0, 0, 225, 223, 1, 0, 0, 0, 226, 227, 7, 7, 0, 0,
8, 0, 0, 227, 41, 1, 0, 0, 0, 228, 229, 7, 9, 0, 0, 229, 43, 1, 0, 0, 0, 227, 41, 1, 0, 0, 0, 228, 229, 7, 8, 0, 0, 229, 43, 1, 0, 0, 0, 21, 47,
21, 47, 54, 59, 65, 73, 81, 93, 104, 108, 114, 126, 135, 142, 151, 158, 54, 59, 65, 73, 81, 93, 104, 108, 114, 126, 135, 142, 151, 158, 162, 181,
162, 181, 194, 215, 221, 223, 194, 215, 221, 223,
} }
deserializer := antlr.NewATNDeserializer(nil) deserializer := antlr.NewATNDeserializer(nil)
staticData.atn = deserializer.Deserialize(staticData.serializedATN) staticData.atn = deserializer.Deserialize(staticData.serializedATN)
@ -217,34 +217,32 @@ const (
SLQParserT__20 = 21 SLQParserT__20 = 21
SLQParserT__21 = 22 SLQParserT__21 = 22
SLQParserT__22 = 23 SLQParserT__22 = 23
SLQParserT__23 = 24 SLQParserGROUP_BY = 24
SLQParserT__24 = 25 SLQParserORDER_ASC = 25
SLQParserT__25 = 26 SLQParserORDER_DESC = 26
SLQParserORDER_ASC = 27 SLQParserORDER_BY = 27
SLQParserORDER_DESC = 28 SLQParserID = 28
SLQParserORDER_BY = 29 SLQParserWS = 29
SLQParserID = 30 SLQParserLPAR = 30
SLQParserWS = 31 SLQParserRPAR = 31
SLQParserLPAR = 32 SLQParserLBRA = 32
SLQParserRPAR = 33 SLQParserRBRA = 33
SLQParserLBRA = 34 SLQParserCOMMA = 34
SLQParserRBRA = 35 SLQParserPIPE = 35
SLQParserCOMMA = 36 SLQParserCOLON = 36
SLQParserPIPE = 37 SLQParserNULL = 37
SLQParserCOLON = 38 SLQParserNN = 38
SLQParserNULL = 39 SLQParserNUMBER = 39
SLQParserNN = 40 SLQParserLT_EQ = 40
SLQParserNUMBER = 41 SLQParserLT = 41
SLQParserLT_EQ = 42 SLQParserGT_EQ = 42
SLQParserLT = 43 SLQParserGT = 43
SLQParserGT_EQ = 44 SLQParserNEQ = 44
SLQParserGT = 45 SLQParserEQ = 45
SLQParserNEQ = 46 SLQParserNAME = 46
SLQParserEQ = 47 SLQParserHANDLE = 47
SLQParserNAME = 48 SLQParserSTRING = 48
SLQParserHANDLE = 49 SLQParserLINECOMMENT = 49
SLQParserSTRING = 50
SLQParserLINECOMMENT = 51
) )
// SLQParser rules. // SLQParser rules.
@ -1274,7 +1272,7 @@ func (p *SLQParser) Cmpr() (localctx ICmprContext) {
p.SetState(95) p.SetState(95)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&277076930199552) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&69269232549888) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)
@ -1472,7 +1470,7 @@ func (p *SLQParser) Fn() (localctx IFnContext) {
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
switch p.GetTokenStream().LA(1) { switch p.GetTokenStream().LA(1) {
case SLQParserT__9, SLQParserT__10, SLQParserT__11, SLQParserT__12, SLQParserT__13, SLQParserT__14, SLQParserT__15, SLQParserT__16, SLQParserT__24, SLQParserT__25, SLQParserORDER_ASC, SLQParserORDER_DESC, SLQParserNULL, SLQParserNN, SLQParserNUMBER, SLQParserNAME, SLQParserSTRING: case SLQParserT__6, SLQParserT__7, SLQParserT__8, SLQParserT__9, SLQParserT__10, SLQParserT__11, SLQParserT__12, SLQParserT__13, SLQParserT__21, SLQParserT__22, SLQParserORDER_ASC, SLQParserORDER_DESC, SLQParserNULL, SLQParserNN, SLQParserNUMBER, SLQParserNAME, SLQParserSTRING:
{ {
p.SetState(99) p.SetState(99)
p.expr(0) p.expr(0)
@ -2002,6 +2000,7 @@ type IGroupContext interface {
GetParser() antlr.Parser GetParser() antlr.Parser
// Getter signatures // Getter signatures
GROUP_BY() antlr.TerminalNode
LPAR() antlr.TerminalNode LPAR() antlr.TerminalNode
AllSelector() []ISelectorContext AllSelector() []ISelectorContext
Selector(i int) ISelectorContext Selector(i int) ISelectorContext
@ -2040,6 +2039,10 @@ func NewGroupContext(parser antlr.Parser, parent antlr.ParserRuleContext, invoki
func (s *GroupContext) GetParser() antlr.Parser { return s.parser } func (s *GroupContext) GetParser() antlr.Parser { return s.parser }
func (s *GroupContext) GROUP_BY() antlr.TerminalNode {
return s.GetToken(SLQParserGROUP_BY, 0)
}
func (s *GroupContext) LPAR() antlr.TerminalNode { func (s *GroupContext) LPAR() antlr.TerminalNode {
return s.GetToken(SLQParserLPAR, 0) return s.GetToken(SLQParserLPAR, 0)
} }
@ -2154,14 +2157,7 @@ func (p *SLQParser) Group() (localctx IGroupContext) {
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
{ {
p.SetState(128) p.SetState(128)
_la = p.GetTokenStream().LA(1) p.Match(SLQParserGROUP_BY)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&448) != 0) {
p.GetErrorHandler().RecoverInline(p)
} else {
p.GetErrorHandler().ReportMatch(p)
p.Consume()
}
} }
{ {
p.SetState(129) p.SetState(129)
@ -3271,7 +3267,7 @@ func (p *SLQParser) RowRange() (localctx IRowRangeContext) {
p.EnterOuterAlt(localctx, 1) p.EnterOuterAlt(localctx, 1)
{ {
p.SetState(172) p.SetState(172)
p.Match(SLQParserT__8) p.Match(SLQParserT__5)
} }
p.SetState(181) p.SetState(181)
p.GetErrorHandler().Sync(p) p.GetErrorHandler().Sync(p)
@ -3420,7 +3416,7 @@ func (p *SLQParser) FnName() (localctx IFnNameContext) {
p.SetState(185) p.SetState(185)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&261120) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&32640) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)
@ -3704,7 +3700,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
p.Literal() p.Literal()
} }
case SLQParserT__24, SLQParserT__25, SLQParserORDER_ASC, SLQParserORDER_DESC: case SLQParserT__21, SLQParserT__22, SLQParserORDER_ASC, SLQParserORDER_DESC:
{ {
p.SetState(190) p.SetState(190)
p.UnaryOperator() p.UnaryOperator()
@ -3714,7 +3710,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
p.expr(9) p.expr(9)
} }
case SLQParserT__9, SLQParserT__10, SLQParserT__11, SLQParserT__12, SLQParserT__13, SLQParserT__14, SLQParserT__15, SLQParserT__16: case SLQParserT__6, SLQParserT__7, SLQParserT__8, SLQParserT__9, SLQParserT__10, SLQParserT__11, SLQParserT__12, SLQParserT__13:
{ {
p.SetState(193) p.SetState(193)
p.Fn() p.Fn()
@ -3747,7 +3743,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
} }
{ {
p.SetState(197) p.SetState(197)
p.Match(SLQParserT__17) p.Match(SLQParserT__14)
} }
{ {
p.SetState(198) p.SetState(198)
@ -3766,7 +3762,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
p.SetState(200) p.SetState(200)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1572868) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&196612) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)
@ -3814,7 +3810,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
p.SetState(206) p.SetState(206)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&14680064) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1835008) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)
@ -3838,7 +3834,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
p.SetState(209) p.SetState(209)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&65970697666560) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&16492674416640) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)
@ -3874,7 +3870,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
p.Match(SLQParserNEQ) p.Match(SLQParserNEQ)
} }
case SLQParserT__9, SLQParserT__10, SLQParserT__11, SLQParserT__12, SLQParserT__13, SLQParserT__14, SLQParserT__15, SLQParserT__16, SLQParserT__24, SLQParserT__25, SLQParserORDER_ASC, SLQParserORDER_DESC, SLQParserNULL, SLQParserNN, SLQParserNUMBER, SLQParserNAME, SLQParserSTRING: case SLQParserT__6, SLQParserT__7, SLQParserT__8, SLQParserT__9, SLQParserT__10, SLQParserT__11, SLQParserT__12, SLQParserT__13, SLQParserT__21, SLQParserT__22, SLQParserORDER_ASC, SLQParserORDER_DESC, SLQParserNULL, SLQParserNN, SLQParserNUMBER, SLQParserNAME, SLQParserSTRING:
default: default:
panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil)) panic(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
@ -3894,7 +3890,7 @@ func (p *SLQParser) expr(_p int) (localctx IExprContext) {
} }
{ {
p.SetState(219) p.SetState(219)
p.Match(SLQParserT__23) p.Match(SLQParserT__20)
} }
{ {
p.SetState(220) p.SetState(220)
@ -4031,7 +4027,7 @@ func (p *SLQParser) Literal() (localctx ILiteralContext) {
p.SetState(226) p.SetState(226)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1129748197539840) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&282437049384960) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)
@ -4151,7 +4147,7 @@ func (p *SLQParser) UnaryOperator() (localctx IUnaryOperatorContext) {
p.SetState(228) p.SetState(228)
_la = p.GetTokenStream().LA(1) _la = p.GetTokenStream().LA(1)
if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&503316480) != 0) { if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&113246208) != 0) {
p.GetErrorHandler().RecoverInline(p) p.GetErrorHandler().RecoverInline(p)
} else { } else {
p.GetErrorHandler().ReportMatch(p) p.GetErrorHandler().ReportMatch(p)

View File

@ -43,12 +43,13 @@ type Node interface {
// //
// REVISIT: the name "Selectable" might be confusing. Perhaps "Tabler" or such. // REVISIT: the name "Selectable" might be confusing. Perhaps "Tabler" or such.
type Selectable interface { type Selectable interface {
// Selectable is a marker interface method. Node
selectable() selectable()
} }
// selector is a marker interface for selector types. // selector is a marker interface for selector types.
type selector interface { type selector interface {
Node
selector() selector()
} }
@ -218,7 +219,7 @@ type GroupByNode struct {
// AddChild implements Node. // AddChild implements Node.
func (n *GroupByNode) AddChild(child Node) error { func (n *GroupByNode) AddChild(child Node) error {
_, ok := child.(*ColSelectorNode) _, ok := child.(selector)
if !ok { if !ok {
return errorf("GROUP() only accepts children of type %s, but got %T", typeColSelectorNode, child) return errorf("GROUP() only accepts children of type %s, but got %T", typeColSelectorNode, child)
} }
@ -227,6 +228,18 @@ func (n *GroupByNode) AddChild(child Node) error {
return child.SetParent(n) return child.SetParent(n)
} }
// SetChildren implements ast.Node.
func (n *GroupByNode) SetChildren(children []Node) error {
for i := range children {
if _, ok := children[i].(selector); !ok {
return errorf("illegal child [%d] type %T {%s} for %T", i, children[i], children[i], n)
}
}
n.setChildren(children)
return nil
}
// String returns a log/debug-friendly representation. // String returns a log/debug-friendly representation.
func (n *GroupByNode) String() string { func (n *GroupByNode) String() string {
text := nodeString(n) text := nodeString(n)
@ -329,5 +342,6 @@ var (
typeTblSelectorNode = reflect.TypeOf((*TblSelectorNode)(nil)) typeTblSelectorNode = reflect.TypeOf((*TblSelectorNode)(nil))
typeRowRangeNode = reflect.TypeOf((*RowRangeNode)(nil)) typeRowRangeNode = reflect.TypeOf((*RowRangeNode)(nil))
typeOrderByNode = reflect.TypeOf((*OrderByNode)(nil)) typeOrderByNode = reflect.TypeOf((*OrderByNode)(nil))
typeGroupByNode = reflect.TypeOf((*GroupByNode)(nil))
typeExprNode = reflect.TypeOf((*ExprNode)(nil)) typeExprNode = reflect.TypeOf((*ExprNode)(nil))
) )

View File

@ -476,31 +476,29 @@ func (v *parseTreeVisitor) VisitFnName(ctx *slq.FnNameContext) any {
// VisitGroup implements slq.SLQVisitor. // VisitGroup implements slq.SLQVisitor.
func (v *parseTreeVisitor) VisitGroup(ctx *slq.GroupContext) any { func (v *parseTreeVisitor) VisitGroup(ctx *slq.GroupContext) any {
// parent node must be a segment // parent node must be a segment
_, ok := v.cur.(*SegmentNode) seg, ok := v.cur.(*SegmentNode)
if !ok { if !ok {
return errorf("parent of GROUP() must be SegmentNode, but got: %T", v.cur) return errorf("parent of GROUP() must be %T, but got: %T", seg, v.cur)
} }
// FIXME: this needs to be revisited.
sels := ctx.AllSelector() sels := ctx.AllSelector()
if len(sels) == 0 { if len(sels) == 0 {
return errorf("GROUP() requires at least one column selector argument") return errorf("GROUP() requires at least one column selector argument")
} }
grp := &GroupByNode{} grpNode := &GroupByNode{}
grp.ctx = ctx grpNode.ctx = ctx
err := v.cur.AddChild(grp) grpNode.text = ctx.GetText()
if err != nil { if err := v.cur.AddChild(grpNode); err != nil {
return err return err
} }
for _, selCtx := range sels { for _, selCtx := range sels {
colSel, err := newSelectorNode(grp, selCtx) colSel, err := newSelectorNode(grpNode, selCtx)
if err != nil { if err != nil {
return err return err
} }
err = grp.AddChild(colSel) err = grpNode.AddChild(colSel)
if err != nil { if err != nil {
return err return err
} }

View File

@ -38,6 +38,31 @@ type BaseFragmentBuilder struct {
Ops map[string]string Ops map[string]string
} }
// GroupBy implements FragmentBuilder.
func (fb *BaseFragmentBuilder) GroupBy(gb *ast.GroupByNode) (string, error) {
if gb == nil {
return "", nil
}
clause := "GROUP BY "
children := gb.Children()
for i := 0; i < len(children); i++ {
if i > 0 {
clause += ", "
}
// FIXME: really should check for other types
s, err := renderSelectorNode(fb.Quote, children[i])
if err != nil {
return "", err
}
clause += s
}
return clause, nil
}
// OrderBy implements FragmentBuilder. // OrderBy implements FragmentBuilder.
func (fb *BaseFragmentBuilder) OrderBy(ob *ast.OrderByNode) (string, error) { func (fb *BaseFragmentBuilder) OrderBy(ob *ast.OrderByNode) (string, error) {
if ob == nil { if ob == nil {
@ -433,8 +458,15 @@ type BaseQueryBuilder struct {
WhereClause string WhereClause string
RangeClause string RangeClause string
OrderByClause string OrderByClause string
GroupByClause string
} }
// SetGroupBy implements QueryBuilder.
func (qb *BaseQueryBuilder) SetGroupBy(gb string) {
qb.GroupByClause = gb
}
// SetOrderBy implements QueryBuilder.
func (qb *BaseQueryBuilder) SetOrderBy(ob string) { func (qb *BaseQueryBuilder) SetOrderBy(ob string) {
qb.OrderByClause = ob qb.OrderByClause = ob
} }
@ -477,6 +509,11 @@ func (qb *BaseQueryBuilder) SQL() (string, error) {
buf.WriteString(qb.OrderByClause) buf.WriteString(qb.OrderByClause)
} }
if qb.GroupByClause != "" {
buf.WriteRune(' ')
buf.WriteString(qb.GroupByClause)
}
if qb.RangeClause != "" { if qb.RangeClause != "" {
buf.WriteRune(' ') buf.WriteRune(' ')
buf.WriteString(qb.RangeClause) buf.WriteString(qb.RangeClause)

View File

@ -23,6 +23,9 @@ type FragmentBuilder interface {
// OrderBy renders the ORDER BY fragment. // OrderBy renders the ORDER BY fragment.
OrderBy(ob *ast.OrderByNode) (string, error) OrderBy(ob *ast.OrderByNode) (string, error)
// GroupBy renders the GROUP BY fragment.
GroupBy(gb *ast.GroupByNode) (string, error)
// Join renders a join fragment. // Join renders a join fragment.
Join(fnJoin *ast.JoinNode) (string, error) Join(fnJoin *ast.JoinNode) (string, error)
@ -56,6 +59,9 @@ type QueryBuilder interface {
// SetOrderBy sets the ORDER BY clause. // SetOrderBy sets the ORDER BY clause.
SetOrderBy(ob string) SetOrderBy(ob string)
// SetGroupBy sets the GROUP BY clause.
SetGroupBy(gb string)
// SQL renders the SQL query. // SQL renders the SQL query.
SQL() (string, error) SQL() (string, error)
} }

View File

@ -128,7 +128,7 @@ func narrowTblColSel(log lg.Log, w *Walker, node Node) error {
parent := sel.Parent() parent := sel.Parent()
switch parent := parent.(type) { switch parent := parent.(type) {
case *JoinConstraint, *FuncNode, *OrderByTermNode, *ExprNode: case *JoinConstraint, *FuncNode, *OrderByTermNode, *GroupByNode, *ExprNode:
if sel.name1 == "" { if sel.name1 == "" {
return nil return nil
} }
@ -181,7 +181,7 @@ func narrowColSel(log lg.Log, w *Walker, node Node) error {
parent := sel.Parent() parent := sel.Parent()
switch parent := parent.(type) { switch parent := parent.(type) {
case *JoinConstraint, *FuncNode, *OrderByTermNode, *ExprNode: case *JoinConstraint, *FuncNode, *OrderByTermNode, *GroupByNode, *ExprNode:
colSel, err := newColSelectorNode(sel) colSel, err := newColSelectorNode(sel)
if err != nil { if err != nil {
return err return err

View File

@ -99,6 +99,15 @@ func (ng *engine) prepare(ctx context.Context, qm *queryModel) error {
qb.SetOrderBy(orderByClause) qb.SetOrderBy(orderByClause)
} }
if qm.GroupBy != nil {
var groupByClause string
if groupByClause, err = fragBuilder.GroupBy(qm.GroupBy); err != nil {
return err
}
qb.SetGroupBy(groupByClause)
}
ng.targetSQL, err = qb.SQL() ng.targetSQL, err = qb.SQL()
if err != nil { if err != nil {
return err return err
@ -344,6 +353,7 @@ type queryModel struct {
Range *ast.RowRangeNode Range *ast.RowRangeNode
Where *ast.WhereNode Where *ast.WhereNode
OrderBy *ast.OrderByNode OrderBy *ast.OrderByNode
GroupBy *ast.GroupByNode
} }
func (qm *queryModel) String() string { func (qm *queryModel) String() string {
@ -432,5 +442,9 @@ func buildQueryModel(log lg.Log, a *ast.AST) (*queryModel, error) {
return nil, err return nil, err
} }
if qm.GroupBy, err = insp.FindGroupByNode(); err != nil {
return nil, err
}
return qm, nil return qm, nil
} }

View File

@ -27,24 +27,25 @@ const (
My8 = "@sakila_my8" My8 = "@sakila_my8"
My = My8 My = My8
MS17 = "@sakila_ms17" MS17 = "@sakila_ms17"
MS19 = "@sakila_ms19"
MS = MS17 MS = MS17
) )
// AllHandles returns all the typical sakila handles. It does not // AllHandles returns all the typical sakila handles. It does not
// include monotable handles such as @sakila_csv_actor. // include monotable handles such as @sakila_csv_actor.
func AllHandles() []string { func AllHandles() []string {
return []string{SL3, Pg9, Pg10, Pg11, Pg12, My56, My57, My8, MS17, XLSX} return []string{SL3, Pg9, Pg10, Pg11, Pg12, My56, My57, My8, MS17, MS19, XLSX}
} }
// SQLAll returns all the sakila SQL handles. // SQLAll returns all the sakila SQL handles.
func SQLAll() []string { func SQLAll() []string {
return []string{SL3, Pg9, Pg10, Pg11, Pg12, My56, My57, My8, MS17} return []string{SL3, Pg9, Pg10, Pg11, Pg12, My56, My57, My8, MS17, MS19}
} }
// SQLAllExternal is the same as SQLAll, but only includes // SQLAllExternal is the same as SQLAll, but only includes
// external (non-embedded) sources. That is, it excludes SL3. // external (non-embedded) sources. That is, it excludes SL3.
func SQLAllExternal() []string { func SQLAllExternal() []string {
return []string{Pg9, Pg10, Pg11, Pg12, My56, My57, My8, MS17} return []string{Pg9, Pg10, Pg11, Pg12, My56, My57, My8, MS17, MS19}
} }
// SQLLatest returns the handles for the latest // SQLLatest returns the handles for the latest

View File

@ -30,6 +30,9 @@ sources:
- handle: '@sakila_ms17' - handle: '@sakila_ms17'
type: sqlserver type: sqlserver
location: sqlserver://sakila:p_ssW0rd@${SQ_TEST_SRC__SAKILA_MS17}?database=sakila location: sqlserver://sakila:p_ssW0rd@${SQ_TEST_SRC__SAKILA_MS17}?database=sakila
- handle: '@sakila_ms19'
type: sqlserver
location: sqlserver://sakila:p_ssW0rd@${SQ_TEST_SRC__SAKILA_MS19}?database=sakila
- handle: '@sakila_xlsx' - handle: '@sakila_xlsx'
type: xlsx type: xlsx
location: '${SQ_ROOT}/drivers/xlsx/testdata/sakila.xlsx' location: '${SQ_ROOT}/drivers/xlsx/testdata/sakila.xlsx'