mirror of
https://github.com/neilotoole/sq.git
synced 2024-11-24 03:45:56 +03:00
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:
parent
d48adeed2e
commit
9746f4c1a2
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
@ -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
@ -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
|
||||
|
@ -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) {}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
)
|
||||
|
@ -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
@ -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{}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
)
|
||||
|
@ -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
118
libsq/ast/orderby.go
Normal 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)
|
||||
}
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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".
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user