orderby() (#159)

* wip: orderby impl

* Tests passing (note: ast.checkASTIntegrity is disabled)

* ExprNode now rendered via renderSelectorNode

* linting

* CHAGELOG for v0.27.0
This commit is contained in:
Neil O'Toole 2023-03-25 19:20:53 -06:00 committed by GitHub
parent d48adeed2e
commit 9746f4c1a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 1640 additions and 793 deletions

View File

@ -5,6 +5,12 @@ 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/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v0.27.0] - 2023-03-25
### Added
- [#158]: Use `orderby()` to order results. See [query guide](https://sq.io/docs/query/#ordering).
## [v0.26.0] - 2023-03-22
@ -188,6 +194,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [#89]: Bug with SQL generated for joins.
[v0.27.0]: https://github.com/neilotoole/sq/compare/v0.26.0...v0.27.0
[v0.26.0]: https://github.com/neilotoole/sq/compare/v0.25.1...v0.26.0
[v0.25.1]: https://github.com/neilotoole/sq/compare/v0.25.0...v0.25.1
[v0.25.0]: https://github.com/neilotoole/sq/compare/v0.24.4...v0.25.0
@ -210,6 +217,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[v0.15.3]: https://github.com/neilotoole/sq/compare/v0.15.2...v0.15.3
[v0.15.2]: https://github.com/neilotoole/sq/releases/tag/v0.15.2
[#158]: https://github.com/neilotoole/sq/issues/158
[#155]: https://github.com/neilotoole/sq/issues/155
[#153]: https://github.com/neilotoole/sq/issues/153
[#151]: https://github.com/neilotoole/sq/issues/151

View File

@ -17,7 +17,7 @@ import (
"github.com/neilotoole/sq/testh/sakila"
)
// TestCmdSLQ_Insert tests "sq slq QUERY --insert=_newdest.tbl".
// TestCmdSLQ_Insert tests "sq QUERY --insert=@src.tbl".
func TestCmdSLQ_Insert_Create(t *testing.T) {
th := testh.New(t)
originSrc, destSrc := th.Source(sakila.SL3), th.Source(sakila.SL3)

View File

@ -311,7 +311,7 @@ func getAllTblMetas(ctx context.Context, log lg.Log, db sqlz.DB) ([]*source.Tabl
const query = `SELECT t.TABLE_SCHEMA, t.TABLE_NAME, t.TABLE_TYPE, t.TABLE_COMMENT,
(DATA_LENGTH + INDEX_LENGTH) AS table_size,
c.COLUMN_NAME, c.ORDINAL_POSITION, c.COLUMN_KEY, c.DATA_TYPE, c.COLUMN_TYPE,
c.IS_NULLABLE, c.COLßUMN_DEFAULT, c.COLUMN_COMMENT, c.EXTRA
c.IS_NULLABLE, c.COLUMN_DEFAULT, c.COLUMN_COMMENT, c.EXTRA
FROM information_schema.TABLES t
LEFT JOIN information_schema.COLUMNS c
ON c.TABLE_CATALOG = t.TABLE_CATALOG

View File

@ -97,6 +97,18 @@ func TestSLQ2SQLNew(t *testing.T) {
want: `SELECT COUNT(*) AS "quantity" FROM "actor"`,
override: map[source.Type]string{mysql.Type: "SELECT COUNT(*) AS `quantity` FROM `actor`"},
},
{
name: "filter/equal",
in: `@sakila | .actor | .actor_id == 1`,
want: `SELECT * FROM "actor" WHERE "actor_id" = 1`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` WHERE `actor_id` = 1"},
},
{
name: "join/single-selector",
in: `@sakila | .actor, .film_actor | join(.actor_id)`,
want: `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`"},
},
{
name: "join/fq-table-cols-equal",
in: `@sakila | .actor, .film_actor | join(.film_actor.actor_id == .actor.actor_id)`,
@ -109,9 +121,51 @@ func TestSLQ2SQLNew(t *testing.T) {
want: `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`"},
},
{
name: "orderby/single-element",
in: `@sakila | .actor | orderby(.first_name)`,
want: `SELECT * FROM "actor" ORDER BY "first_name"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name`"},
},
{
name: "orderby/single-element-table-selector",
in: `@sakila | .actor | orderby(.actor.first_name)`,
want: `SELECT * FROM "actor" ORDER BY "actor"."first_name"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `actor`.`first_name`"},
},
{
name: "orderby/single-element-asc",
in: `@sakila | .actor | orderby(.first_name+)`,
want: `SELECT * FROM "actor" ORDER BY "first_name" ASC`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` ASC"},
},
{
name: "orderby/single-element-desc",
in: `@sakila | .actor | orderby(.first_name-)`,
want: `SELECT * FROM "actor" ORDER BY "first_name" DESC`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name` DESC"},
},
{
name: "orderby/multiple-elements",
in: `@sakila | .actor | orderby(.first_name+, .last_name-)`,
want: `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"},
},
{
name: "orderby/synonym-sort-by",
in: `@sakila | .actor | sort_by(.first_name)`,
want: `SELECT * FROM "actor" ORDER BY "first_name"`,
override: map[source.Type]string{mysql.Type: "SELECT * FROM `actor` ORDER BY `first_name`"},
},
{
name: "orderby/error-no-selector",
in: `@sakila | .actor | orderby()`,
wantErr: true,
},
}
srcs := testh.New(t).NewSourceSet(sakila.SQLLatest()...)
// srcs := testh.New(t).NewSourceSet(sakila.SL3)
for _, tc := range testCases {
tc := tc
@ -133,9 +187,6 @@ func TestSLQ2SQLNew(t *testing.T) {
th := testh.New(t)
dbases := th.Databases()
// drvr := th.DriverFor(src).(driver.SQLDriver)
// drvr.AlterTableAddColumn()
gotSQL, gotErr := libsq.SLQ2SQL(th.Context, th.Log, dbases, dbases, srcs, in)
if tc.wantErr {
require.Error(t, gotErr)

View File

@ -16,6 +16,8 @@ import (
"github.com/neilotoole/sq/libsq/core/sqlmodel"
)
var _ sqlbuilder.FragmentBuilder = (*fragBuilder)(nil)
type fragBuilder struct {
sqlbuilder.BaseFragmentBuilder
}
@ -29,13 +31,13 @@ func newFragmentBuilder(log lg.Log) *fragBuilder {
return r
}
func (fb *fragBuilder) Range(rr *ast.RowRange) (string, error) {
func (fb *fragBuilder) Range(rr *ast.RowRangeNode) (string, error) {
if rr == nil {
return "", nil
}
/*
SELECT * FROM tbluser
SELECT * FROM actor
ORDER BY (SELECT 0)
OFFSET 1 ROWS
FETCH NEXT 2 ROWS ONLY;
@ -62,6 +64,8 @@ func (fb *fragBuilder) Range(rr *ast.RowRange) (string, error) {
return sql, nil
}
var _ sqlbuilder.QueryBuilder = (*queryBuilder)(nil)
type queryBuilder struct {
sqlbuilder.BaseQueryBuilder
}
@ -71,7 +75,7 @@ func (qb *queryBuilder) SQL() (string, error) {
// then the ORDER BY clause is required. If ORDER BY is not specified, we use a trick (SELECT 0)
// to satisfy SQL Server. For example:
//
// SELECT * FROM tbluser
// SELECT * FROM actor
// ORDER BY (SELECT 0)
// OFFSET 1 ROWS
// FETCH NEXT 2 ROWS ONLY;

View File

@ -14,6 +14,7 @@ element:
| selectorElement
| join
| group
| orderBy
| rowRange
| fnElement
| expr;
@ -33,6 +34,31 @@ joinConstraint:
group: ('group' | 'GROUP' | 'g') '(' selector (',' selector)* ')';
/*
orderby
The "orderby" construct implements the SQL "ORDER BY" clause.
.actor | orderby(.first_name, .last_name)
.actor | orderby(.first_name+)
.actor | orderby(.actor.first_name-)
The optional plus/minus tokens specify ASC or DESC order.
For jq compatability, the "sort_by" synonym is provided.
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
results are inherently sorted. Although perhaps it should be implemented
as a no-op.
*/
ORDER_ASC: '+';
ORDER_DESC: '-';
ORDER_BY: 'orderby' | 'sort_by';
orderByTerm: selector (ORDER_ASC | ORDER_DESC)?;
orderBy: ORDER_BY '(' orderByTerm (',' orderByTerm)* ')';
// selector specfies a table name, a column name, or table.column.
// - .first_name
// - ."first name"
@ -142,6 +168,7 @@ GT: '>';
NEQ: '!=';
EQ: '==';
NAME: '.' (ID | STRING);
// SEL can be .THING or .THING.OTHERTHING.

View File

@ -17,13 +17,23 @@ import (
// Parse parses the SLQ input string and builds the AST.
func Parse(log lg.Log, input string) (*AST, error) { //nolint:staticcheck
// REVISIT: We need a better solution for disabling parser logging.
log = lg.Discard() //nolint:staticcheck // Disable parser logging.
ptree, err := parseSLQ(log, input)
if err != nil {
return nil, err
}
return buildAST(log, ptree)
ast, err := buildAST(log, ptree)
if err != nil {
return nil, err
}
if err := verify(log, ast); err != nil {
return nil, err
}
return ast, nil
}
// buildAST constructs sq's AST from a parse tree.
@ -65,6 +75,19 @@ func buildAST(log lg.Log, query slq.IQueryContext) (*AST, error) {
return tree.ast, nil
}
// verify performs additional checks on the state of the built AST.
func verify(log lg.Log, ast *AST) error {
selCount := NewInspector(log, ast).CountNodes(typeSelectorNode)
if selCount != 0 {
return errorf("AST should have zero nodes of type %T but found %d",
(*SelectorNode)(nil), selCount)
}
// TODO: Lots more checks could go here
return nil
}
var _ Node = (*AST)(nil)
// AST is the Abstract Syntax Tree. It is the root node of a SQL query/stmt.

View File

@ -1,24 +1,24 @@
package ast
var (
_ Node = (*Func)(nil)
_ ResultColumn = (*Func)(nil)
_ Node = (*FuncNode)(nil)
_ ResultColumn = (*FuncNode)(nil)
)
// Func models a function. For example, "COUNT()".
type Func struct {
// FuncNode models a function. For example, "COUNT()".
type FuncNode struct {
baseNode
fnName string
alias string
}
// FuncName returns the function name.
func (fn *Func) FuncName() string {
func (fn *FuncNode) FuncName() string {
return fn.fnName
}
// String returns a log/debug-friendly representation.
func (fn *Func) String() string {
func (fn *FuncNode) String() string {
str := nodeString(fn)
if fn.alias != "" {
str += ":" + fn.alias
@ -27,28 +27,28 @@ func (fn *Func) String() string {
}
// Text implements ResultColumn.
func (fn *Func) Text() string {
func (fn *FuncNode) Text() string {
return fn.ctx.GetText()
}
// Alias implements ResultColumn.
func (fn *Func) Alias() string {
func (fn *FuncNode) Alias() string {
return fn.alias
}
// SetChildren implements Node.
func (fn *Func) SetChildren(children []Node) error {
func (fn *FuncNode) SetChildren(children []Node) error {
fn.setChildren(children)
return nil
}
// IsColumn implements ResultColumn.
func (fn *Func) IsColumn() bool {
func (fn *FuncNode) IsColumn() bool {
return false
}
func (fn *Func) AddChild(child Node) error {
// TODO: add check for valid Func child types
func (fn *FuncNode) AddChild(child Node) error {
// TODO: add check for valid FuncNode child types
fn.addChild(child)
return child.SetParent(fn)
}

View File

@ -3,6 +3,8 @@ package ast
import (
"reflect"
"github.com/ryboe/q"
"github.com/neilotoole/lg"
)
@ -23,6 +25,11 @@ func (in *Inspector) CountNodes(typ reflect.Type) int {
w := NewWalker(in.log, in.ast)
w.AddVisitor(typ, func(log lg.Log, w *Walker, node Node) error {
count++
if typ == typeSelectorNode {
// found it
// FIXME: delete this
q.Q("found it", node)
}
return nil
})
@ -30,7 +37,7 @@ func (in *Inspector) CountNodes(typ reflect.Type) int {
return count
}
// FindNodes returns all of the nodes having typ.
// FindNodes returns the nodes having typ.
func (in *Inspector) FindNodes(typ reflect.Type) []Node {
var nodes []Node
w := NewWalker(in.log, in.ast)
@ -44,19 +51,19 @@ func (in *Inspector) FindNodes(typ reflect.Type) []Node {
}
// FindWhereClauses returns all the WHERE clauses in the AST.
func (in *Inspector) FindWhereClauses() ([]*Where, error) {
ws := []*Where{}
func (in *Inspector) FindWhereClauses() ([]*WhereNode, error) {
var nodes []*WhereNode
for _, seg := range in.ast.Segments() {
// Where clauses must be the only child of a segment
// WhereNode clauses must be the only child of a segment
if len(seg.Children()) == 1 {
if w, ok := seg.Children()[0].(*Where); ok {
ws = append(ws, w)
if w, ok := seg.Children()[0].(*WhereNode); ok {
nodes = append(nodes, w)
}
}
}
return ws, nil
return nodes, nil
}
// FindColExprSegment returns the segment containing col expressions (such as
@ -91,6 +98,29 @@ func (in *Inspector) FindColExprSegment() (*SegmentNode, error) {
return nil, nil //nolint:nilnil
}
// FindOrderByNode returns the OrderByNode, or nil if not found.
func (in *Inspector) FindOrderByNode() (*OrderByNode, error) {
segs := in.ast.Segments()
for i := range segs {
nodes := nodesWithType(segs[i].Children(), typeOrderByNode)
switch len(nodes) {
case 0:
// No OrderByNode in this segment, continue searching.
continue
case 1:
// Found it
node, _ := nodes[0].(*OrderByNode)
return node, nil
default:
// Shouldn't be possible
return nil, errorf("Segment {%s} has %d OrderByNode 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
// that implements Selectable.
func (in *Inspector) FindSelectableSegments() []*SegmentNode {

File diff suppressed because one or more lines are too long

View File

@ -24,30 +24,31 @@ T__22=23
T__23=24
T__24=25
T__25=26
T__26=27
T__27=28
ID=29
WS=30
LPAR=31
RPAR=32
LBRA=33
RBRA=34
COMMA=35
PIPE=36
COLON=37
NULL=38
NN=39
NUMBER=40
LT_EQ=41
LT=42
GT_EQ=43
GT=44
NEQ=45
EQ=46
NAME=47
HANDLE=48
STRING=49
LINECOMMENT=50
ORDER_ASC=27
ORDER_DESC=28
ORDER_BY=29
ID=30
WS=31
LPAR=32
RPAR=33
LBRA=34
RBRA=35
COMMA=36
PIPE=37
COLON=38
NULL=39
NN=40
NUMBER=41
LT_EQ=42
LT=43
GT_EQ=44
GT=45
NEQ=46
EQ=47
NAME=48
HANDLE=49
STRING=50
LINECOMMENT=51
';'=1
'*'=2
'join'=3
@ -68,24 +69,24 @@ LINECOMMENT=50
'||'=18
'/'=19
'%'=20
'+'=21
'-'=22
'<<'=23
'>>'=24
'&'=25
'&&'=26
'~'=27
'!'=28
'('=31
')'=32
'['=33
']'=34
','=35
'|'=36
':'=37
'<='=41
'<'=42
'>='=43
'>'=44
'!='=45
'=='=46
'<<'=21
'>>'=22
'&'=23
'&&'=24
'~'=25
'!'=26
'+'=27
'-'=28
'('=32
')'=33
'['=34
']'=35
','=36
'|'=37
':'=38
'<='=42
'<'=43
'>='=44
'>'=45
'!='=46
'=='=47

File diff suppressed because one or more lines are too long

View File

@ -24,30 +24,31 @@ T__22=23
T__23=24
T__24=25
T__25=26
T__26=27
T__27=28
ID=29
WS=30
LPAR=31
RPAR=32
LBRA=33
RBRA=34
COMMA=35
PIPE=36
COLON=37
NULL=38
NN=39
NUMBER=40
LT_EQ=41
LT=42
GT_EQ=43
GT=44
NEQ=45
EQ=46
NAME=47
HANDLE=48
STRING=49
LINECOMMENT=50
ORDER_ASC=27
ORDER_DESC=28
ORDER_BY=29
ID=30
WS=31
LPAR=32
RPAR=33
LBRA=34
RBRA=35
COMMA=36
PIPE=37
COLON=38
NULL=39
NN=40
NUMBER=41
LT_EQ=42
LT=43
GT_EQ=44
GT=45
NEQ=46
EQ=47
NAME=48
HANDLE=49
STRING=50
LINECOMMENT=51
';'=1
'*'=2
'join'=3
@ -68,24 +69,24 @@ LINECOMMENT=50
'||'=18
'/'=19
'%'=20
'+'=21
'-'=22
'<<'=23
'>>'=24
'&'=25
'&&'=26
'~'=27
'!'=28
'('=31
')'=32
'['=33
']'=34
','=35
'|'=36
':'=37
'<='=41
'<'=42
'>='=43
'>'=44
'!='=45
'=='=46
'<<'=21
'>>'=22
'&'=23
'&&'=24
'~'=25
'!'=26
'+'=27
'-'=28
'('=32
')'=33
'['=34
']'=35
','=36
'|'=37
':'=38
'<='=42
'<'=43
'>='=44
'>'=45
'!='=46
'=='=47

View File

@ -80,6 +80,18 @@ func (s *BaseSLQListener) EnterGroup(ctx *GroupContext) {}
// ExitGroup is called when production group is exited.
func (s *BaseSLQListener) ExitGroup(ctx *GroupContext) {}
// EnterOrderByTerm is called when production orderByTerm is entered.
func (s *BaseSLQListener) EnterOrderByTerm(ctx *OrderByTermContext) {}
// ExitOrderByTerm is called when production orderByTerm is exited.
func (s *BaseSLQListener) ExitOrderByTerm(ctx *OrderByTermContext) {}
// EnterOrderBy is called when production orderBy is entered.
func (s *BaseSLQListener) EnterOrderBy(ctx *OrderByContext) {}
// ExitOrderBy is called when production orderBy is exited.
func (s *BaseSLQListener) ExitOrderBy(ctx *OrderByContext) {}
// EnterSelector is called when production selector is entered.
func (s *BaseSLQListener) EnterSelector(ctx *SelectorContext) {}

View File

@ -47,6 +47,14 @@ func (v *BaseSLQVisitor) VisitGroup(ctx *GroupContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseSLQVisitor) VisitOrderByTerm(ctx *OrderByTermContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseSLQVisitor) VisitOrderBy(ctx *OrderByContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseSLQVisitor) VisitSelector(ctx *SelectorContext) interface{} {
return v.VisitChildren(ctx)
}

View File

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

View File

@ -37,6 +37,12 @@ type SLQListener interface {
// EnterGroup is called when entering the group production.
EnterGroup(c *GroupContext)
// EnterOrderByTerm is called when entering the orderByTerm production.
EnterOrderByTerm(c *OrderByTermContext)
// EnterOrderBy is called when entering the orderBy production.
EnterOrderBy(c *OrderByContext)
// EnterSelector is called when entering the selector production.
EnterSelector(c *SelectorContext)
@ -97,6 +103,12 @@ type SLQListener interface {
// ExitGroup is called when exiting the group production.
ExitGroup(c *GroupContext)
// ExitOrderByTerm is called when exiting the orderByTerm production.
ExitOrderByTerm(c *OrderByTermContext)
// ExitOrderBy is called when exiting the orderBy production.
ExitOrderBy(c *OrderByContext)
// ExitSelector is called when exiting the selector production.
ExitSelector(c *SelectorContext)

File diff suppressed because it is too large Load Diff

View File

@ -37,6 +37,12 @@ type SLQVisitor interface {
// Visit a parse tree produced by SLQParser#group.
VisitGroup(ctx *GroupContext) interface{}
// Visit a parse tree produced by SLQParser#orderByTerm.
VisitOrderByTerm(ctx *OrderByTermContext) interface{}
// Visit a parse tree produced by SLQParser#orderBy.
VisitOrderBy(ctx *OrderByContext) interface{}
// Visit a parse tree produced by SLQParser#selector.
VisitSelector(ctx *SelectorContext) interface{}

View File

@ -30,7 +30,7 @@ func (jn *JoinNode) RightTbl() *TblSelectorNode {
}
// Selectable implements the Selectable marker interface.
func (jn *JoinNode) Selectable() {
func (jn *JoinNode) selectable() {
// no-op
}

View File

@ -40,9 +40,16 @@ type Node interface {
// Selectable is a marker interface to indicate that the node can be
// selected from. That is, the node represents a SQL table, view, or
// join table, and can be used like "SELECT * FROM [selectable]".
//
// REVISIT: the name "Selectable" might be confusing. Perhaps "Tabler" or such.
type Selectable interface {
// Selectable is a marker interface method.
Selectable()
selectable()
}
// selector is a marker interface for selector types.
type selector interface {
selector()
}
// ResultColumn indicates a column selection expression such as a
@ -91,6 +98,9 @@ func (bn *baseNode) Children() []Node {
return bn.children
}
// AddChild always returns an error. Node implementations should
// implement a type-specific method that only accepts a child of
// an appropriate type for that node.
func (bn *baseNode) AddChild(child Node) error {
return errorf(msgNodeNoAddChild, bn, child)
}
@ -201,99 +211,100 @@ func nodesWithType(nodes []Node, typ reflect.Type) []Node {
return s
}
// Terminal is a terminal/leaf node that typically is interpreted simply as its
// text value.
// REVISIT: Is Terminal needed?
type Terminal struct {
// GroupByNode models GROUP BY.
type GroupByNode struct {
baseNode
}
func (t *Terminal) String() string {
return nodeString(t)
}
// Group models GROUP BY.
type Group struct {
baseNode
}
func (g *Group) AddChild(child Node) error {
// AddChild implements Node.
func (n *GroupByNode) AddChild(child Node) error {
_, ok := child.(*ColSelectorNode)
if !ok {
return errorf("GROUP() only accepts children of type %s, but got %T", typeColSelectorNode, child)
}
g.addChild(child)
return child.SetParent(g)
n.addChild(child)
return child.SetParent(n)
}
func (g *Group) String() string {
text := nodeString(g)
// String returns a log/debug-friendly representation.
func (n *GroupByNode) String() string {
text := nodeString(n)
return text
}
// Expr models a SLQ expression such as ".uid > 4".
type Expr struct {
// ExprNode models a SLQ expression such as ".uid > 4".
type ExprNode struct {
baseNode
}
func (e *Expr) AddChild(child Node) error {
e.addChild(child)
return child.SetParent(e)
// AddChild implements Node.
func (n *ExprNode) AddChild(child Node) error {
n.addChild(child)
return child.SetParent(n)
}
func (e *Expr) String() string {
text := nodeString(e)
// SetChildren implements Node.
func (n *ExprNode) SetChildren(children []Node) error {
n.setChildren(children)
return nil
}
// String returns a log/debug-friendly representation.
func (n *ExprNode) String() string {
text := nodeString(n)
return text
}
// Operator is a leaf node in an expression representing an operator such as ">" or "==".
type Operator struct {
// OperatorNode is a leaf node in an expression representing an operator such as ">" or "==".
type OperatorNode struct {
baseNode
}
func (o *Operator) String() string {
return nodeString(o)
// String returns a log/debug-friendly representation.
func (n *OperatorNode) String() string {
return nodeString(n)
}
// Literal is a leaf node representing a literal such as a number or a string.
type Literal struct {
// LiteralNode is a leaf node representing a literal such as a number or a string.
type LiteralNode struct {
baseNode
}
func (li *Literal) String() string {
return nodeString(li)
// String returns a log/debug-friendly representation.
func (n *LiteralNode) String() string {
return nodeString(n)
}
// Where represents a SQL WHERE clause, i.e. a filter on the SELECT.
type Where struct {
// WhereNode represents a SQL WHERE clause, i.e. a filter on the SELECT.
type WhereNode struct {
baseNode
}
func (w *Where) String() string {
return nodeString(w)
func (n *WhereNode) String() string {
return nodeString(n)
}
// Expr returns the expression that constitutes the SetWhere clause, or nil if no expression.
func (w *Where) Expr() *Expr {
if len(w.children) == 0 {
func (n *WhereNode) Expr() *ExprNode {
if len(n.children) == 0 {
return nil
}
return w.children[0].(*Expr)
return n.children[0].(*ExprNode)
}
func (w *Where) AddChild(node Node) error {
expr, ok := node.(*Expr)
func (n *WhereNode) AddChild(node Node) error {
expr, ok := node.(*ExprNode)
if !ok {
return errorf("WHERE child must be *Expr, but got: %T", node)
return errorf("WHERE child must be %T, but got: %T", expr, node)
}
if len(w.children) > 0 {
if len(n.children) > 0 {
return errorf("WHERE has max 1 child: failed to add: %T", node)
}
w.addChild(expr)
n.addChild(expr)
return nil
}
@ -316,6 +327,7 @@ var (
typeSelectorNode = reflect.TypeOf((*SelectorNode)(nil))
typeColSelectorNode = reflect.TypeOf((*ColSelectorNode)(nil))
typeTblSelectorNode = reflect.TypeOf((*TblSelectorNode)(nil))
typeRowRangeNode = reflect.TypeOf((*RowRange)(nil))
typeExprNode = reflect.TypeOf((*Expr)(nil))
typeRowRangeNode = reflect.TypeOf((*RowRangeNode)(nil))
typeOrderByNode = reflect.TypeOf((*OrderByNode)(nil))
typeExprNode = reflect.TypeOf((*ExprNode)(nil))
)

View File

@ -26,7 +26,7 @@ func TestChildIndex(t *testing.T) {
}
func TestNodesWithType(t *testing.T) {
nodes := []Node{&ColSelectorNode{}, &ColSelectorNode{}, &TblSelectorNode{}, &RowRange{}}
nodes := []Node{&ColSelectorNode{}, &ColSelectorNode{}, &TblSelectorNode{}, &RowRangeNode{}}
require.Equal(t, 2, len(nodesWithType(nodes, typeColSelectorNode)))
require.Equal(t, 1, len(nodesWithType(nodes, typeTblSelectorNode)))

118
libsq/ast/orderby.go Normal file
View File

@ -0,0 +1,118 @@
package ast
// OrderByNode implements the SQL "ORDER BY" clause.
type OrderByNode struct {
baseNode
}
// String returns a log/debug-friendly representation.
func (n *OrderByNode) String() string {
return nodeString(n)
}
// Terms returns a new slice containing the ordering terms of the OrderByNode.
// The returned slice has at least one term.
func (n *OrderByNode) Terms() []*OrderByTermNode {
terms := make([]*OrderByTermNode, len(n.children))
for i := range n.children {
terms[i], _ = n.children[i].(*OrderByTermNode)
}
return terms
}
// AddChild implements Node.AddChild. It returns an error
// if child is nil or not type OrderByTermNode.
func (n *OrderByNode) AddChild(child Node) error {
term, ok := child.(*OrderByTermNode)
if !ok {
return errorf("can only add child of type %T to %T but got %T", term, n, child)
}
n.addChild(child)
return nil
}
// SetChildren implements ast.Node.
func (n *OrderByNode) SetChildren(children []Node) error {
if len(children) > 1 {
return errorf("%T can have only 1 child but attempt to set %d children",
n, len(children))
}
for i := range children {
if _, ok := children[i].(*OrderByTermNode); !ok {
return errorf("illegal child type %T {%s} for %T", children[i], children[i], n)
}
}
n.setChildren(children)
return nil
}
// OrderByDirection specifies the "ORDER BY" direction.
type OrderByDirection string
const (
// OrderByDirectionNone is the default order direction.
OrderByDirectionNone OrderByDirection = ""
// OrderByDirectionAsc is the ascending (DESC) order direction.
OrderByDirectionAsc OrderByDirection = "ASC"
// OrderByDirectionDesc is the descending (DESC) order direction.
OrderByDirectionDesc OrderByDirection = "DESC"
)
// OrderByTermNode is a child of OrderByNode.
type OrderByTermNode struct {
baseNode
direction OrderByDirection
}
// AddChild accepts a single child of type *SelectorNode.
func (n *OrderByTermNode) AddChild(child Node) error {
if len(n.children) > 0 {
return errorf("%s is only allowed a single child")
}
selNode, ok := child.(*SelectorNode)
if !ok {
return errorf("illegal %T child type %T: %s", n, child, child)
}
n.addChild(selNode)
return child.SetParent(n)
}
// SetChildren implements ast.Node.
func (n *OrderByTermNode) SetChildren(children []Node) error {
switch len(children) {
case 0:
// fallthrough
case 1:
if _, ok := children[0].(selector); !ok {
return errorf("illegal child type %T {%s} for %T", children[0], children[0], n)
}
default:
return errorf("%T can have only 1 child but attempt to set %d children",
n, len(children))
}
n.setChildren(children)
return nil
}
// Selector returns the ordering term's selector.
func (n *OrderByTermNode) Selector() Node {
return n.children[0]
}
// Direction returns the ordering term's direction.
func (n *OrderByTermNode) Direction() OrderByDirection {
return n.direction
}
// String returns a log/debug-friendly representation.
func (n *OrderByTermNode) String() string {
return nodeString(n)
}

View File

@ -128,9 +128,9 @@ type parseTreeVisitor struct {
// executes fn, and then restores v.cur to its previous value.
// The type of the returned value is declared as "any" instead of
// error, because that's the generated antlr code returns "any".
func (v *parseTreeVisitor) using(cur Node, fn func() any) any {
func (v *parseTreeVisitor) using(node Node, fn func() any) any {
prev := v.cur
v.cur = cur
v.cur = node
defer func() { v.cur = prev }()
return fn()
}
@ -170,6 +170,10 @@ func (v *parseTreeVisitor) Visit(ctx antlr.ParseTree) any {
return v.VisitExpr(ctx)
case *slq.GroupContext:
return v.VisitGroup(ctx)
case *slq.OrderByContext:
return v.VisitOrderBy(ctx)
case *slq.OrderByTermContext:
return v.VisitOrderByTerm(ctx)
case *slq.LiteralContext:
return v.VisitLiteral(ctx)
case *antlr.TerminalNodeImpl:
@ -248,32 +252,46 @@ func (v *parseTreeVisitor) VisitSegment(ctx *slq.SegmentContext) any {
return v.VisitChildren(ctx)
}
func newSelectorNode(parent Node, ctx slq.ISelectorContext) (*SelectorNode, error) {
selNode := &SelectorNode{}
selNode.parent = parent
selNode.ctx = ctx
selNode.text = ctx.GetText()
// VisitOrderBy implements slq.SLQVisitor.
func (v *parseTreeVisitor) VisitOrderBy(ctx *slq.OrderByContext) interface{} {
node := &OrderByNode{}
node.parent = v.cur
node.ctx = ctx
node.text = ctx.GetText()
var err error
names := ctx.AllNAME()
switch len(names) {
default:
return nil, errorf("expected 1 or 2 name parts in selector (e.g. '.table.column') but got %d parts: %s",
len(names), ctx.GetText())
case 1:
if selNode.name0, err = extractSelVal(names[0]); err != nil {
return nil, err
}
case 2:
if selNode.name0, err = extractSelVal(names[0]); err != nil {
return nil, err
}
if selNode.name1, err = extractSelVal(names[1]); err != nil {
return nil, err
}
if err := v.cur.AddChild(node); err != nil {
return err
}
return selNode, nil
return v.using(node, func() any {
// This will result in VisitOrderByTerm being called on the children.
return v.VisitChildren(ctx)
})
}
// VisitOrderByTerm implements slq.SLQVisitor.
func (v *parseTreeVisitor) VisitOrderByTerm(ctx *slq.OrderByTermContext) interface{} {
node := &OrderByTermNode{}
node.parent = v.cur
node.ctx = ctx
node.text = ctx.GetText()
selNode, err := newSelectorNode(node, ctx.Selector())
if err != nil {
return nil
}
if ctx.ORDER_ASC() != nil {
node.direction = OrderByDirectionAsc
} else if ctx.ORDER_DESC() != nil {
node.direction = OrderByDirectionDesc
}
if err := node.AddChild(selNode); err != nil {
return err
}
return v.cur.AddChild(node)
}
// VisitSelectorElement implements slq.SLQVisitor.
@ -315,7 +333,7 @@ func (v *parseTreeVisitor) VisitAlias(ctx *slq.AliasContext) any {
switch node := v.cur.(type) {
case *SelectorNode:
node.alias = alias
case *Func:
case *FuncNode:
node.alias = alias
default:
return errorf("alias not allowed for type %T: %v", node, ctx.GetText())
@ -353,9 +371,9 @@ func (v *parseTreeVisitor) VisitFnElement(ctx *slq.FnElementContext) any {
return errorf("expected second child to be %T but was %T: %v", aliasCtx, child2, ctx.GetText())
}
// VisitAlias will expect v.cur to be a Func.
// VisitAlias will expect v.cur to be a FuncNode.
lastNode := nodeLastChild(v.cur)
fnNode, ok := lastNode.(*Func)
fnNode, ok := lastNode.(*FuncNode)
if !ok {
return errorf("expected %T but got %T: %v", fnNode, lastNode, ctx.GetText())
}
@ -372,7 +390,7 @@ func (v *parseTreeVisitor) VisitFnElement(ctx *slq.FnElementContext) any {
func (v *parseTreeVisitor) VisitFn(ctx *slq.FnContext) any {
v.log.Debugf("visiting Fn: %v", ctx.GetText())
fn := &Func{fnName: ctx.FnName().GetText()}
fn := &FuncNode{fnName: ctx.FnName().GetText()}
fn.ctx = ctx
err := fn.SetParent(v.cur)
if err != nil {
@ -405,7 +423,7 @@ func (v *parseTreeVisitor) VisitExpr(ctx *slq.ExprContext) any {
return v.VisitLiteral(ctx.Literal().(*slq.LiteralContext))
}
ex := &Expr{}
ex := &ExprNode{}
ex.ctx = ctx
err := ex.SetParent(v.cur)
if err != nil {
@ -438,7 +456,7 @@ func (v *parseTreeVisitor) VisitStmtList(ctx *slq.StmtListContext) any {
func (v *parseTreeVisitor) VisitLiteral(ctx *slq.LiteralContext) any {
v.log.Debugf("visiting literal: %q", ctx.GetText())
lit := &Literal{}
lit := &LiteralNode{}
lit.ctx = ctx
_ = lit.SetParent(v.cur)
err := v.cur.AddChild(lit)
@ -469,7 +487,7 @@ func (v *parseTreeVisitor) VisitGroup(ctx *slq.GroupContext) any {
return errorf("GROUP() requires at least one column selector argument")
}
grp := &Group{}
grp := &GroupByNode{}
grp.ctx = ctx
err := v.cur.AddChild(grp)
if err != nil {
@ -602,7 +620,7 @@ func (v *parseTreeVisitor) VisitTerminal(ctx antlr.TerminalNode) any {
val := ctx.GetText()
if isOperator(val) {
op := &Operator{}
op := &OperatorNode{}
op.ctx = ctx
err := op.SetParent(v.cur)
@ -642,7 +660,7 @@ func (v *parseTreeVisitor) VisitRowRange(ctx *slq.RowRangeContext) any {
}
i, _ := strconv.Atoi(ctx.AllNN()[0].GetText())
rr := newRowRange(ctx, i, 1)
rr := newRowRangeNode(ctx, i, 1)
return v.cur.AddChild(rr)
}
@ -656,7 +674,7 @@ func (v *parseTreeVisitor) VisitRowRange(ctx *slq.RowRangeContext) any {
offset, _ := strconv.Atoi(ctx.AllNN()[0].GetText())
finish, _ := strconv.Atoi(ctx.AllNN()[1].GetText())
limit := finish - offset
rr := newRowRange(ctx, offset, limit)
rr := newRowRangeNode(ctx, offset, limit)
return v.cur.AddChild(rr)
}
@ -676,7 +694,7 @@ func (v *parseTreeVisitor) VisitRowRange(ctx *slq.RowRangeContext) any {
offset, _ = strconv.Atoi(ctx.AllNN()[0].GetText())
}
rr := newRowRange(ctx, offset, limit)
rr := newRowRangeNode(ctx, offset, limit)
return v.cur.AddChild(rr)
}

View File

@ -106,7 +106,7 @@ func TestInspector_FindWhereClauses(t *testing.T) {
log := testlg.New(t)
// Verify that ".uid > 4" becomes a WHERE clause.
const input = "@my1 | .tbluser | .uid > 4 | .uid, .username"
const input = "@my1 | .actor | .uid > 4 | .uid, .username"
ptree, err := parseSLQ(log, input)
require.Nil(t, err)

View File

@ -2,32 +2,32 @@ package ast
import "github.com/neilotoole/sq/libsq/ast/internal/slq"
// RowRange models a range, effectively {OFFSET,LIMIT}.
type RowRange struct {
// RowRangeNode models a range, effectively {OFFSET,LIMIT}.
type RowRangeNode struct {
baseNode
Offset int
Limit int
}
func newRowRange(ctx *slq.RowRangeContext, offset, limit int) *RowRange {
rr := &RowRange{}
func newRowRangeNode(ctx *slq.RowRangeContext, offset, limit int) *RowRangeNode {
rr := &RowRangeNode{}
rr.ctx = ctx
rr.Offset = offset
rr.Limit = limit
return rr
}
func (rr *RowRange) String() string {
func (rr *RowRangeNode) String() string {
return rr.Text()
}
func (rr *RowRange) Range() (offset, limit int) {
func (rr *RowRangeNode) Range() (offset, limit int) {
offset = rr.Offset
limit = rr.Limit
return offset, limit
}
func (rr *RowRange) SetParent(parent Node) error {
func (rr *RowRangeNode) SetParent(parent Node) error {
seg, ok := parent.(*SegmentNode)
if !ok {
return errorf("%T requires parent of type *%s", rr, typeSegmentNode)

View File

@ -29,7 +29,7 @@ func TestRowRange2(t *testing.T) {
assert.Equal(t, 1, insp.CountNodes(typeRowRangeNode))
nodes := insp.FindNodes(typeRowRangeNode)
assert.Equal(t, 1, len(nodes))
rr, _ := nodes[0].(*RowRange)
rr, _ := nodes[0].(*RowRangeNode)
assert.Equal(t, 2, rr.Offset)
assert.Equal(t, 1, rr.Limit)
}
@ -39,7 +39,7 @@ func TestRowRange3(t *testing.T) {
ast := mustParse(t, fixtRowRange3)
insp := NewInspector(log, ast)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRange)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRangeNode)
assert.Equal(t, 1, rr.Offset)
assert.Equal(t, 2, rr.Limit)
}
@ -49,7 +49,7 @@ func TestRowRange4(t *testing.T) {
ast := mustParse(t, fixtRowRange4)
insp := NewInspector(log, ast)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRange)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRangeNode)
assert.Equal(t, 0, rr.Offset)
assert.Equal(t, 3, rr.Limit)
}
@ -58,7 +58,7 @@ func TestRowRange5(t *testing.T) {
log := testlg.New(t).Strict(true)
ast := mustParse(t, fixtRowRange5)
insp := NewInspector(log, ast)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRange)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRangeNode)
assert.Equal(t, 0, rr.Offset)
assert.Equal(t, 3, rr.Limit)
}
@ -67,7 +67,7 @@ func TestRowRange6(t *testing.T) {
log := testlg.New(t).Strict(true)
ast := mustParse(t, fixtRowRange6)
insp := NewInspector(log, ast)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRange)
rr, _ := insp.FindNodes(typeRowRangeNode)[0].(*RowRangeNode)
assert.Equal(t, 2, rr.Offset)
assert.Equal(t, -1, rr.Limit)
}

View File

@ -72,7 +72,7 @@ func (s *SegmentNode) SetContext(ctx antlr.ParseTree) error {
// ChildType returns the expected Type of the segment's elements, based
// on the content of the segment's node's children. The type should be something
// like SelectorNode|Func.
// like SelectorNode|FuncNode.
func (s *SegmentNode) ChildType() (reflect.Type, error) {
if len(s.Children()) == 0 {
return nil, nil

View File

@ -14,7 +14,38 @@ const (
msgNodeNoAddChildren = "%T cannot add children: failed to add %d children"
)
var _ Node = (*SelectorNode)(nil)
func newSelectorNode(parent Node, ctx slq.ISelectorContext) (*SelectorNode, error) {
selNode := &SelectorNode{}
selNode.parent = parent
selNode.ctx = ctx
selNode.text = ctx.GetText()
var err error
names := ctx.AllNAME()
switch len(names) {
default:
return nil, errorf("expected 1 or 2 name parts in selector (e.g. '.table.column') but got %d parts: %s",
len(names), ctx.GetText())
case 1:
if selNode.name0, err = extractSelVal(names[0]); err != nil {
return nil, err
}
case 2:
if selNode.name0, err = extractSelVal(names[0]); err != nil {
return nil, err
}
if selNode.name1, err = extractSelVal(names[1]); err != nil {
return nil, err
}
}
return selNode, nil
}
var (
_ Node = (*SelectorNode)(nil)
_ selector = (*SelectorNode)(nil)
)
// SelectorNode is a selector such as ".my_table" or ".my_col". The
// generic selector will typically be replaced with a more specific
@ -38,6 +69,11 @@ type SelectorNode struct {
name1 string
}
// selector implements the ast.selector marker interface.
func (s *SelectorNode) selector() {
}
// Strings returns a log/debug-friendly representation.
func (s *SelectorNode) String() string {
return nodeString(s)
}
@ -83,7 +119,7 @@ func (s *TblSelectorNode) Handle() string {
}
// Selectable implements the Selectable marker interface.
func (s *TblSelectorNode) Selectable() {
func (s *TblSelectorNode) selectable() {
// no-op
}
@ -107,6 +143,7 @@ func (s *TblSelectorNode) String() string {
var (
_ Node = (*TblColSelectorNode)(nil)
_ ResultColumn = (*TblColSelectorNode)(nil)
_ selector = (*TblColSelectorNode)(nil)
)
// TblColSelectorNode models the TABLE.COLUMN selector, e.g. actor.first_name.
@ -169,6 +206,7 @@ func (n *TblColSelectorNode) Alias() string {
var (
_ Node = (*ColSelectorNode)(nil)
_ ResultColumn = (*ColSelectorNode)(nil)
_ selector = (*ColSelectorNode)(nil)
)
// ColSelectorNode models a column selector such as ".first_name".

View File

@ -27,6 +27,8 @@ func BaseOps() map[string]string {
return ops
}
var _ FragmentBuilder = (*BaseFragmentBuilder)(nil)
// BaseFragmentBuilder is a default implementation of sqlbuilder.FragmentBuilder.
type BaseFragmentBuilder struct {
Log lg.Log
@ -36,8 +38,43 @@ type BaseFragmentBuilder struct {
Ops map[string]string
}
// OrderBy implements FragmentBuilder.
func (fb *BaseFragmentBuilder) OrderBy(ob *ast.OrderByNode) (string, error) {
if ob == nil {
return "", nil
}
terms := ob.Terms()
if len(terms) == 0 {
return "", errz.Errorf("%T has no ordering terms: %s", ob, ob)
}
clause := "ORDER BY "
for i := 0; i < len(terms); i++ {
if i > 0 {
clause += ", "
}
sel, err := renderSelectorNode(fb.Quote, terms[i].Selector())
if err != nil {
return "", err
}
clause += sel
switch terms[i].Direction() { //nolint:exhaustive
case ast.OrderByDirectionAsc:
clause += " ASC"
case ast.OrderByDirectionDesc:
clause += " DESC"
default:
}
}
return clause, nil
}
// Operator implements FragmentBuilder.
func (fb *BaseFragmentBuilder) Operator(op *ast.Operator) (string, error) {
func (fb *BaseFragmentBuilder) Operator(op *ast.OperatorNode) (string, error) {
if val, ok := fb.Ops[op.Text()]; ok {
return val, nil
}
@ -46,7 +83,7 @@ func (fb *BaseFragmentBuilder) Operator(op *ast.Operator) (string, error) {
}
// Where implements FragmentBuilder.
func (fb *BaseFragmentBuilder) Where(where *ast.Where) (string, error) {
func (fb *BaseFragmentBuilder) Where(where *ast.WhereNode) (string, error) {
sql, err := fb.Expr(where.Expr())
if err != nil {
return "", err
@ -57,32 +94,29 @@ func (fb *BaseFragmentBuilder) Where(where *ast.Where) (string, error) {
}
// Expr implements FragmentBuilder.
func (fb *BaseFragmentBuilder) Expr(expr *ast.Expr) (string, error) {
func (fb *BaseFragmentBuilder) Expr(expr *ast.ExprNode) (string, error) {
var sql string
for _, child := range expr.Children() {
switch child := child.(type) {
case *ast.SelectorNode:
val, err := child.SelValue()
case *ast.TblColSelectorNode, *ast.ColSelectorNode:
val, err := renderSelectorNode(fb.ColQuote, child)
if err != nil {
return "", err
}
parts := strings.Split(val, ".")
identifier := fb.ColQuote + strings.Join(parts, fb.ColQuote+"."+fb.ColQuote) + fb.ColQuote
sql = sql + " " + identifier
case *ast.Operator:
sql = val
case *ast.OperatorNode:
val, err := fb.Operator(child)
if err != nil {
return "", err
}
sql = sql + " " + val
case *ast.Expr:
case *ast.ExprNode:
val, err := fb.Expr(child)
if err != nil {
return "", err
}
sql = sql + " " + val
default:
sql = sql + " " + child.Text()
}
@ -98,7 +132,7 @@ func (fb *BaseFragmentBuilder) SelectAll(tblSel *ast.TblSelectorNode) (string, e
}
// Function implements FragmentBuilder.
func (fb *BaseFragmentBuilder) Function(fn *ast.Func) (string, error) {
func (fb *BaseFragmentBuilder) Function(fn *ast.FuncNode) (string, error) {
buf := &bytes.Buffer{}
children := fn.Children()
@ -129,7 +163,7 @@ func (fb *BaseFragmentBuilder) Function(fn *ast.Func) (string, error) {
buf.WriteString(fb.Quote)
buf.WriteString(colName)
buf.WriteString(fb.Quote)
case *ast.Operator:
case *ast.OperatorNode:
buf.WriteString(child.Text())
default:
fb.Log.Debugf("unknown AST child node type %T", child)
@ -320,7 +354,7 @@ func quoteTableOrColSelector(quote, selector string) (string, error) {
}
// Range implements FragmentBuilder.
func (fb *BaseFragmentBuilder) Range(rr *ast.RowRange) (string, error) {
func (fb *BaseFragmentBuilder) Range(rr *ast.RowRangeNode) (string, error) {
if rr == nil {
return "", nil
}
@ -370,7 +404,7 @@ func (fb *BaseFragmentBuilder) SelectCols(cols []ast.ResultColumn) (string, erro
vals[i] = fmt.Sprintf("%s%s%s", fb.Quote, col.ColName(), fb.Quote)
case *ast.TblColSelectorNode:
vals[i] = fmt.Sprintf("%s%s%s.%s%s%s", fb.Quote, col.TblName(), fb.Quote, fb.Quote, col.ColName(), fb.Quote)
case *ast.Func:
case *ast.FuncNode:
// it's a function
var err error
if vals[i], err = fb.Function(col); err != nil {
@ -389,6 +423,8 @@ func (fb *BaseFragmentBuilder) SelectCols(cols []ast.ResultColumn) (string, erro
return text, nil
}
var _ QueryBuilder = (*BaseQueryBuilder)(nil)
// BaseQueryBuilder is a default implementation
// of sqlbuilder.QueryBuilder.
type BaseQueryBuilder struct {
@ -399,6 +435,10 @@ type BaseQueryBuilder struct {
OrderByClause string
}
func (qb *BaseQueryBuilder) SetOrderBy(ob string) {
qb.OrderByClause = ob
}
// SetSelect implements QueryBuilder.
func (qb *BaseQueryBuilder) SetSelect(cols string) {
qb.SelectClause = cols

View File

@ -18,22 +18,25 @@ type FragmentBuilder interface {
SelectAll(tblSel *ast.TblSelectorNode) (string, error)
// Range renders a row range fragment.
Range(rr *ast.RowRange) (string, error)
Range(rr *ast.RowRangeNode) (string, error)
// OrderBy renders the ORDER BY fragment.
OrderBy(ob *ast.OrderByNode) (string, error)
// Join renders a join fragment.
Join(fnJoin *ast.JoinNode) (string, error)
// Function renders a function fragment.
Function(fn *ast.Func) (string, error)
Function(fn *ast.FuncNode) (string, error)
// Where renders a WHERE fragment.
Where(where *ast.Where) (string, error)
Where(where *ast.WhereNode) (string, error)
// Expr renders an expression fragment.
Expr(expr *ast.Expr) (string, error)
Expr(expr *ast.ExprNode) (string, error)
// Operator renders an operator fragment.
Operator(op *ast.Operator) (string, error)
Operator(op *ast.OperatorNode) (string, error)
}
// QueryBuilder provides an abstraction for building a SQL query.
@ -50,6 +53,9 @@ type QueryBuilder interface {
// SetRange sets the range clause.
SetRange(rng string)
// SetOrderBy sets the ORDER BY clause.
SetOrderBy(ob string)
// SQL renders the SQL query.
SQL() (string, error)
}

View File

@ -123,12 +123,12 @@ func narrowTblColSel(log lg.Log, w *Walker, node Node) error {
// node is guaranteed to be type SelectorNode
sel, ok := node.(*SelectorNode)
if !ok {
return errorf("expected *SelectorNode but got %T", node)
return errorf("expected %T but got %T", sel, node)
}
parent := sel.Parent()
switch parent := parent.(type) {
case *JoinConstraint, *Func:
case *JoinConstraint, *FuncNode, *OrderByTermNode, *ExprNode:
if sel.name1 == "" {
return nil
}
@ -175,15 +175,13 @@ func narrowColSel(log lg.Log, w *Walker, node Node) error {
// node is guaranteed to be type SelectorNode
sel, ok := node.(*SelectorNode)
if !ok {
return errorf("expected *SelectorNode but got %T", node)
return errorf("expected %T but got %T", sel, node)
}
parent := sel.Parent()
switch parent := parent.(type) {
case *JoinConstraint, *Func:
// selector parent is JoinConstraint or Func, therefore this is a ColSelectorNode
log.Debugf("selector parent is %T, therefore this is a ColSelectorNode", parent)
case *JoinConstraint, *FuncNode, *OrderByTermNode, *ExprNode:
colSel, err := newColSelectorNode(sel)
if err != nil {
return err
@ -219,34 +217,31 @@ func narrowColSel(log lg.Log, w *Walker, node Node) error {
// findWhereClause locates any expressions that represent the WHERE clause of the SQL SELECT stmt, and
// inserts a SetWhere node into the AST for that expression.
//
// In practice, a WHERE clause is an *Expr that is the only child of a segment. For example:
// In practice, a WHERE clause is an *ExprNode that is the only child of a segment. For example:
//
// @my1 | .tbluser | .uid > 4 | .uid, .email
//
// In this case, ".uid > 4" is the WHERE clause.
func findWhereClause(log lg.Log, w *Walker, node Node) error {
// node is guaranteed to be *Expr
expr, ok := node.(*Expr)
// node is guaranteed to be *ExprNode
expr, ok := node.(*ExprNode)
if !ok {
return errorf("expected *Expr but got %T", node)
return errorf("expected %T but got %T", expr, node)
}
log.Debugf("found expression: %q", expr.Context().GetText())
seg, ok := expr.Parent().(*SegmentNode)
if !ok {
// The expr is not the direct child of a segment, so we're not interested in it.
return nil
}
log.Debugf("expr parent is *SegmentNode")
if len(seg.Children()) != 1 {
return errorf("SegmentNode with expression - representing a WHERE clause - must only have one child")
return errorf("%T with expression - representing a WHERE clause - must only have one child", seg)
}
// The expr is the direct and only child of a segment.
// We insert a Where between the segment and the expr.
where := &Where{}
// We insert a WhereNode between the segment and the expr.
where := &WhereNode{}
where.ctx = expr.ctx
err := where.AddChild(expr)
if err != nil {
@ -296,10 +291,10 @@ func determineJoinTables(log lg.Log, w *Walker, node Node) error {
return nil
}
// visitCheckRowRange validates the RowRange element.
// visitCheckRowRange validates the RowRangeNode element.
func visitCheckRowRange(log lg.Log, w *Walker, node Node) error {
// node is guaranteed to be FnJoin
rr, ok := node.(*RowRange)
rr, ok := node.(*RowRangeNode)
if !ok {
return errorf("expected %s but got %T", typeRowRangeNode, node)
}

View File

@ -74,8 +74,7 @@ func (ng *engine) prepare(ctx context.Context, qm *queryModel) error {
if qm.Range != nil {
var rangeClause string
rangeClause, err = fragBuilder.Range(qm.Range)
if err != nil {
if rangeClause, err = fragBuilder.Range(qm.Range); err != nil {
return err
}
@ -84,14 +83,22 @@ func (ng *engine) prepare(ctx context.Context, qm *queryModel) error {
if qm.Where != nil {
var whereClause string
whereClause, err = fragBuilder.Where(qm.Where)
if err != nil {
if whereClause, err = fragBuilder.Where(qm.Where); err != nil {
return err
}
qb.SetWhere(whereClause)
}
if qm.OrderBy != nil {
var orderByClause string
if orderByClause, err = fragBuilder.OrderBy(qm.OrderBy); err != nil {
return err
}
qb.SetOrderBy(orderByClause)
}
ng.targetSQL, err = qb.SQL()
if err != nil {
return err
@ -334,8 +341,9 @@ type queryModel struct {
AST *ast.AST
Selectable ast.Selectable
Cols []ast.ResultColumn
Range *ast.RowRange
Where *ast.Where
Range *ast.RowRangeNode
Where *ast.WhereNode
OrderBy *ast.OrderByNode
}
func (qm *queryModel) String() string {
@ -372,7 +380,7 @@ func buildQueryModel(log lg.Log, a *ast.AST) (*queryModel, error) {
// Look for range
for seg := selectableSeg.Next(); seg != nil; seg = seg.Next() {
// Check if the first element of the segment is a row range, if not, just skip
if rr, ok := seg.Children()[0].(*ast.RowRange); ok {
if rr, ok := seg.Children()[0].(*ast.RowRangeNode); ok {
if len(seg.Children()) != 1 {
return nil, errz.Errorf(
"segment [%d] with row range must have exactly one element, but found %d: %q",
@ -420,5 +428,9 @@ func buildQueryModel(log lg.Log, a *ast.AST) (*queryModel, error) {
qm.Where = whereClauses[0]
}
if qm.OrderBy, err = insp.FindOrderByNode(); err != nil {
return nil, err
}
return qm, nil
}

View File

@ -103,8 +103,7 @@ func newEngine(ctx context.Context, log lg.Log, dbOpener driver.DatabaseOpener,
joinDBOpener: joinDBOpener,
}
err = ng.prepare(ctx, qModel)
if err != nil {
if err = ng.prepare(ctx, qModel); err != nil {
return nil, err
}