diff --git a/Makefile b/Makefile
index 17f24c67..76ac9eb0 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,18 @@ ifeq ($(shell command -v glide 2>/dev/null),)
curl https://glide.sh/get | sh
endif
+.PHONY: goyacc
+goyacc:
+ifeq ($(shell command -v goyacc 2>/dev/null),)
+ go get -u github.com/cznic/goyacc
+endif
+
+.PHONY: yacc
+yacc: goyacc
+ cd lib/parser && \
+ goyacc -o parser.go -v parser.output parser.y && \
+ cd ../..
+
.PHONY: test
test:
go test -cover `glide novendor`
diff --git a/docs/_includes/side_menu.html b/docs/_includes/side_menu.html
index 39d802a5..c811cf04 100644
--- a/docs/_includes/side_menu.html
+++ b/docs/_includes/side_menu.html
@@ -61,6 +61,7 @@
Cryptographic Hash Functions
Cast Functions
System Functions
+ Analytic Functions
diff --git a/docs/_posts/2006-01-02-analytic-functions.md b/docs/_posts/2006-01-02-analytic-functions.md
new file mode 100644
index 00000000..7d2b35a8
--- /dev/null
+++ b/docs/_posts/2006-01-02-analytic-functions.md
@@ -0,0 +1,89 @@
+---
+layout: default
+title: Analytic Functions - Reference Manual - csvq
+category: reference
+---
+
+# Analytic Functions
+
+Analytic functions calculate values of groups.
+Analytic Functions can be used only in [Select Clause]({{ '/reference/select-query.html#select_clause' | relative_url }}) and [Order By Clause]({{ '/reference/select-query.html#order_by_clause' | relative_url }})
+
+| name | description |
+| :- | :- |
+| [ROW_NUMBER](#row_number) | Return sequential numbers |
+| [RANK](#rank) | Return ranks |
+| [DENSE_RANK](#dense_rank) | Return ranks without any gaps in the ranking |
+
+## Syntax
+{: #syntax}
+
+```sql
+analytic_function
+ : function_name([args]) OVER ([partition_clause] [order_by_clause])
+
+args
+ : value [, value ...]
+
+partition_clause
+ : PARTITION BY value [, value ...]
+```
+
+_value_
+: [value]({{ '/reference/value.html' | relative_url }})
+
+_order_by_clause_
+: [Order By Clause]({{ '/reference/select_query.html#order_by_clause' | relative_url }})
+
+Analytic Functions sort the result set by _order_by_clause_ and calculate values within each of groups partitioned by _partition_clause_.
+If there is no _partition_clause_, then all records of result set are dealt with as one group.
+
+## Definitions
+
+### ROW_NUMBER
+{: #row_number}
+
+```
+ROW_NUMBER() OVER ([partition_clause] [order_by_clause])
+```
+
+_partition_clause_
+: [Partition Clause](#syntax)
+
+_order_by_clause_
+: [Order By Clause]({{ '/reference/select_query.html#order_by_clause' | relative_url }})
+
+Return sequential numbers of records in a group.
+
+
+### RANK
+{: #rank}
+
+```
+RANK() OVER ([partition_clause] [order_by_clause])
+```
+
+_partition_clause_
+: [Partition Clause](#syntax)
+
+_order_by_clause_
+: [Order By Clause]({{ '/reference/select_query.html#order_by_clause' | relative_url }})
+
+Returns ranks of records in a group.
+
+
+### DENSE_RANK
+{: #dense_rank}
+
+```
+DENSE_RANK() OVER ([partition_clause] [order_by_clause])
+```
+
+_partition_clause_
+: [Partition Clause](#syntax)
+
+_order_by_clause_
+: [Order By Clause]({{ '/reference/select_query.html#order_by_clause' | relative_url }})
+
+Returns ranks of records without any gaps in the ranking in a group.
+
diff --git a/docs/_posts/2006-01-02-arithmetic-operators.md b/docs/_posts/2006-01-02-arithmetic-operators.md
index 9cc7a9b9..b030355a 100644
--- a/docs/_posts/2006-01-02-arithmetic-operators.md
+++ b/docs/_posts/2006-01-02-arithmetic-operators.md
@@ -6,7 +6,7 @@ category: reference
# Arithmetic Operators
-| name | description |
+| operator | description |
| :- | :- |
| + | Addition |
| \- | Subtraction |
@@ -26,4 +26,4 @@ _float_
An arithmetic operator calculate float values, and return a integer or float value.
If each of operands is not a float value, the value is converted to a float value.
-If either of operands is null or conversion to float failed, return null.
+If either of operands is null or conversions to float failed, return null.
diff --git a/docs/_posts/2006-01-02-comparison-operators.md b/docs/_posts/2006-01-02-comparison-operators.md
index 47340a9e..a2f81120 100644
--- a/docs/_posts/2006-01-02-comparison-operators.md
+++ b/docs/_posts/2006-01-02-comparison-operators.md
@@ -6,7 +6,7 @@ category: reference
# Comparison Operators
-| name | description |
+| operator | description |
| :- | :- |
| [Relational Operators](#relational_operators) | Compare values |
| [IS](#is) | Compare a value with ternary value |
@@ -22,7 +22,7 @@ A comparison operator returns a ternary value.
## Relational Operators
{: #relational_operators}
-| name | description |
+| operator | description |
| :- | :- |
| \= | Equal |
| < | Less than |
@@ -128,7 +128,7 @@ _multiple_fields_subquery_
Check if a _value_ or _row_value_ is in within a set of _values_ or a result set of _select_query_.
-A IN operation is equivalent to a ANY operation that operator is specified as "=".
+A IN operation is equivalent to a [ANY](#any) operation that _relational_operator_ is specified as "=".
## LIKE
{: #like}
@@ -185,7 +185,7 @@ If any of comparison results is TRUE, return TRUE.
If there is no TRUE result and there is at least one UNKNOWN result, return UNKNOWN.
Otherwise return FALSE.
-If _select_query_ returns no values, return FALSE.
+If _select_query_ returns no record, return FALSE.
## ALL
{: #all}
@@ -218,7 +218,7 @@ If any of comparison results is FALSE, return FALSE.
If there is no FALSE result and there is at least one UNKNOWN result, return UNKNOWN.
Otherwise return TRUE.
-If _select_query_ returns no values, return TRUE.
+If _select_query_ returns no record, return TRUE.
## Exists
{: #exists}
diff --git a/docs/_posts/2006-01-02-datetime-functions.md b/docs/_posts/2006-01-02-datetime-functions.md
index 7b394302..4197e7df 100644
--- a/docs/_posts/2006-01-02-datetime-functions.md
+++ b/docs/_posts/2006-01-02-datetime-functions.md
@@ -8,7 +8,7 @@ category: reference
| name | description |
| :- | :- |
-| [NOW](#now) | Return current date and time |
+| [NOW](#now) | Return a datetime value of current date and time |
| [DATETIME_FORMAT](#datetime_format) | Format a datetime |
| [YEAR](#year) | Return year of a datetime |
| [MONTH](#month) | Return month of a datetime |
@@ -48,7 +48,7 @@ NOW()
_return_
: [datetime]({{ '/reference/value.html#datetime' | relative_url }})
-Return current date and time.
+Return a datetime value of current date and time.
### DATETIME_FORMAT
{: #datetime_format}
diff --git a/docs/_posts/2006-01-02-logic-operators.md b/docs/_posts/2006-01-02-logic-operators.md
index 4208222b..119f640d 100644
--- a/docs/_posts/2006-01-02-logic-operators.md
+++ b/docs/_posts/2006-01-02-logic-operators.md
@@ -6,7 +6,7 @@ category: reference
# Logic Operators
-| name | description |
+| operator | description |
| :- | :- |
| [AND](#and) | Logical AND |
| [OR](#or) | Logical OR |
diff --git a/docs/_posts/2006-01-02-numeric-functions.md b/docs/_posts/2006-01-02-numeric-functions.md
index 0788d718..703205e4 100644
--- a/docs/_posts/2006-01-02-numeric-functions.md
+++ b/docs/_posts/2006-01-02-numeric-functions.md
@@ -69,7 +69,7 @@ _return_
: [float]({{ '/reference/value.html#float' | relative_url }}) or [integer]({{ '/reference/value.html#integer' | relative_url }})
Round _number_ up to _place_ decimal place.
-If _place_ is negative number, _place_ representing a place in integer part,
+If _place_ is a negative number, _place_ representing a place in the integer part.
### FLOOR
{: #floor}
@@ -100,7 +100,7 @@ _return_
: [float]({{ '/reference/value.html#float' | relative_url }}) or [integer]({{ '/reference/value.html#integer' | relative_url }})
Round _number_ down to _place_ decimal place.
-If _place_ is negative number, _place_ representing a place in integer part,
+If _place_ is a negative number, _place_ representing a place in the integer part.
### ROUND
{: #round}
@@ -131,7 +131,7 @@ _return_
: [float]({{ '/reference/value.html#float' | relative_url }}) or [integer]({{ '/reference/value.html#integer' | relative_url }})
Round _number_ to _place_ decimal place.
-If _place_ is negative number, _place_ representing a place in integer part,
+If _place_ is a negative number, _place_ representing a place in the integer part.
### ABS
{: #abs}
diff --git a/docs/_posts/2006-01-02-select-query.md b/docs/_posts/2006-01-02-select-query.md
index 4712e48e..da0f062a 100644
--- a/docs/_posts/2006-01-02-select-query.md
+++ b/docs/_posts/2006-01-02-select-query.md
@@ -218,27 +218,27 @@ ORDER BY order_item [, order_item ...]
```sql
order_item
- : field_name
- | field_name [ASC|DESC]
+ : field_name [order_direction] [null_position]
+
+order_direction
+ : {ASC|DESC}
+
+null_position
+ : NULLS {FIRST|LAST}
```
_field_name_
: [value]({{ '/reference/value.html' | relative_url }})
- If DISTINCT keyword is specified in the select clause, you can use only enumerated fields in the select clause as _field_name_.
+ If DISTINCT keyword is specified in the select clause, you can use only enumerated fields in the select clause as _field_name_.
-Default order direction is ASC.
-If order direction is not specified, the next order_item's direction is applied.
+_order_direction_
+: _ASC_ sorts records in ascending order. _DESC_ sorts in descending order. _ASC_ is the default.
-```sql
--- Following expressions return same results
-ORDER BY column1, column2
-ORDER BY column1 ASC, column2 ASC
+_null_position_
+: _FIRST_ puts null values first. _LAST_ puts null values last.
+ If _order_direction_ is specified as _ASC_ then _FIRST_ is the default, otherwise _LAST_ is the default.
--- Following expressions return same results
-ORDER BY column1, column2 ASC, column3, column4 DESC
-ORDER BY column1 ASC, column2 ASC, column3 DESC, column4 DESC
-```
## Limit Clause
{: #limit_clause}
@@ -246,12 +246,21 @@ ORDER BY column1 ASC, column2 ASC, column3 DESC, column4 DESC
The Limit clause is used to specify the maximum number of records to return.
```sql
-LIMIT number
+limit_clause
+ : LIMIT number_of_records [WITH TIES]
+ | LIMIT percent PERCENT [WITH TIES]
```
-_number_
+_number_of_records_
: [integer]({{ '/reference/value.html#integer' | relative_url }})
+_percent_
+: [float]({{ '/reference/value.html#integer' | relative_url }})
+
+If _PERCENT_ keyword is specified, maximum number of records is _percent_ percent of the result set that includes the excluded records by _Offset Clause_.
+
+If _WITH TIES_ keywords are specified, all records that have the same sort keys specified by _Order By Clause_ as the last record of the limited records are included in the records to return.
+If there is no _Order By Clause_ in the query, _WITH TIES_ keywords are ignored.
## Offset Clause
{: #offset_clause}
diff --git a/docs/_posts/2006-01-02-set-operators.md b/docs/_posts/2006-01-02-set-operators.md
index 24b5596d..db3719bf 100644
--- a/docs/_posts/2006-01-02-set-operators.md
+++ b/docs/_posts/2006-01-02-set-operators.md
@@ -6,7 +6,7 @@ category: reference
# Set Operators
-| name | description |
+| operator | description |
| :- | :- |
| [UNION](#union) | Return the union of result sets |
| [EXCEPT](#except) | Return the relative complement of result sets |
@@ -37,7 +37,7 @@ select_query EXCEPT [ALL] select_query
_select_query_
: [select_set_entity]({{ '/reference/select-query.html' | relative_url }})
-Return records of a first result set that do not appear in a second result set.
+Return records of the result set of the left-hand side query that do not appear in the result set of the right-hand side query.
## INTERSECT
{: #intersect}
diff --git a/docs/_posts/2006-01-02-statement.md b/docs/_posts/2006-01-02-statement.md
index c309c26f..c5e1caa7 100644
--- a/docs/_posts/2006-01-02-statement.md
+++ b/docs/_posts/2006-01-02-statement.md
@@ -139,12 +139,12 @@ HAVING
IF IN INNER INSERT INTERSECT INTO IS
JOIN
LAST LEFT LIKE LIMIT
-NATURAL NOT NULL
-OFFSET ON OPEN OR ORDER OUTER
-PRINT
+NATURAL NOT NULL NULLS
+OFFSET ON OPEN OR ORDER OUTER OVER
+PARTITION PERCENT PRINT
RENAME RIGHT ROLLBACK
SELECT SET SEPARATOR STDIN
-TABLE THEN TO
+TABLE THEN TIES TO
UNION UPDATE USING
VALUES VAR
WHEN WHERE WHILE WITH
diff --git a/docs/_posts/2006-01-02-string-operators.md b/docs/_posts/2006-01-02-string-operators.md
index 14e80caf..da364e8c 100644
--- a/docs/_posts/2006-01-02-string-operators.md
+++ b/docs/_posts/2006-01-02-string-operators.md
@@ -6,7 +6,7 @@ category: reference
# String Operators
-| name | description |
+| operator | description |
| :- | :- |
| \|\| | Concatnation |
diff --git a/docs/_posts/2006-01-02-value.md b/docs/_posts/2006-01-02-value.md
index ded438c1..8db75c6b 100644
--- a/docs/_posts/2006-01-02-value.md
+++ b/docs/_posts/2006-01-02-value.md
@@ -107,6 +107,7 @@ user.id -- table name and column name
* [Cryptographic Hash Functions]({{ '/reference/cryptographic-hash-functions.html' | relative_url }})
* [Cast Functions]({{ '/reference/cast-functions.html' | relative_url }})
* [System Functions]({{ '/reference/system-functions.html' | relative_url }})
+* [Analytic Functions]({{ '/reference/analytic-functions.html' | relative_url }})
### Subquery
{: #subquery}
diff --git a/docs/reference.md b/docs/reference.md
index 0acb756c..4e5a7a6e 100644
--- a/docs/reference.md
+++ b/docs/reference.md
@@ -39,3 +39,4 @@ title: Reference Manual - csvq
* [Cryptographic Hash Functions]({{ '/reference/cryptographic-hash-functions.html' | relative_url }})
* [Cast Functions]({{ '/reference/cast-functions.html' | relative_url }})
* [System Functions]({{ '/reference/system-functions.html' | relative_url }})
+ * [Analytic Functions]({{ '/reference/analytic-functions.html' | relative_url }})
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index 07bed01b..94e75646 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -10,7 +10,7 @@
https://mithrandie.github.io/csvq/reference.html
- 2017-06-29T17:08:49+00:00
+ 2017-07-02T23:29:47+00:00
https://mithrandie.github.io/csvq/reference/install.html
@@ -22,15 +22,15 @@
https://mithrandie.github.io/csvq/reference/statement.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T04:36:43+00:00
https://mithrandie.github.io/csvq/reference/value.html
- 2017-06-29T17:08:49+00:00
+ 2017-07-02T23:29:47+00:00
https://mithrandie.github.io/csvq/reference/select-query.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T04:36:43+00:00
https://mithrandie.github.io/csvq/reference/insert-query.html
@@ -86,23 +86,23 @@
https://mithrandie.github.io/csvq/reference/arithmetic-operators.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/comparison-operators.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/logic-operators.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/string-operators.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/set-operators.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/aggregate-functions.html
@@ -118,11 +118,11 @@
https://mithrandie.github.io/csvq/reference/numeric-functions.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/datetime-functions.html
- 2017-06-29T17:08:49+00:00
+ 2017-06-30T20:24:07+00:00
https://mithrandie.github.io/csvq/reference/cryptographic-hash-functions.html
@@ -136,6 +136,10 @@
https://mithrandie.github.io/csvq/reference/system-functions.html
2017-06-29T17:08:49+00:00
+
+ https://mithrandie.github.io/csvq/reference/analytic-functions.html
+ 2017-07-02T23:29:47+00:00
+
https://mithrandie.github.io/csvq/license.html
2017-06-29T17:08:49+00:00
diff --git a/lib/action/calc_test.go b/lib/action/calc_test.go
index 7246d728..e7fd21d6 100644
--- a/lib/action/calc_test.go
+++ b/lib/action/calc_test.go
@@ -37,7 +37,7 @@ var calcTests = []struct {
{
Stdin: "foo",
Input: "error",
- Error: "identifier = error: field does not exist",
+ Error: "field error does not exist",
},
}
diff --git a/lib/action/main_test.go b/lib/action/main_test.go
index 208a5be9..86527138 100644
--- a/lib/action/main_test.go
+++ b/lib/action/main_test.go
@@ -14,10 +14,14 @@ func GetTestFilePath(filename string) string {
}
func TestMain(m *testing.M) {
+ os.Exit(run(m))
+}
+
+func run(m *testing.M) int {
+ defer teardown()
+
setup()
- r := m.Run()
- teardown()
- os.Exit(r)
+ return m.Run()
}
func setup() {
diff --git a/lib/cmd/main_test.go b/lib/cmd/main_test.go
index 7b23dd52..c29142f5 100644
--- a/lib/cmd/main_test.go
+++ b/lib/cmd/main_test.go
@@ -13,10 +13,14 @@ func GetTestFilePath(filename string) string {
}
func TestMain(m *testing.M) {
+ os.Exit(run(m))
+}
+
+func run(m *testing.M) int {
+ defer teardown()
+
setup()
- r := m.Run()
- teardown()
- os.Exit(r)
+ return m.Run()
}
func setup() {
diff --git a/lib/parser/ast.go b/lib/parser/ast.go
index 92adfd08..280f8d77 100644
--- a/lib/parser/ast.go
+++ b/lib/parser/ast.go
@@ -541,22 +541,51 @@ func (ob OrderByClause) String() string {
}
type LimitClause struct {
- Limit string
- Number int64
+ Limit string
+ Value Expression
+ Percent string
+ With Expression
}
-func (l LimitClause) String() string {
- s := []string{l.Limit, strconv.FormatInt(l.Number, 10)}
+func (e LimitClause) String() string {
+ s := []string{e.Limit, e.Value.String()}
+ if e.IsPercentage() {
+ s = append(s, e.Percent)
+ }
+ if e.With != nil {
+ s = append(s, e.With.String())
+ }
+ return joinWithSpace(s)
+}
+
+func (e LimitClause) IsPercentage() bool {
+ return 0 < len(e.Percent)
+}
+
+func (e LimitClause) IsWithTies() bool {
+ if e.With == nil {
+ return false
+ }
+ return e.With.(LimitWith).Type.Token == TIES
+}
+
+type LimitWith struct {
+ With string
+ Type Token
+}
+
+func (e LimitWith) String() string {
+ s := []string{e.With, e.Type.Literal}
return joinWithSpace(s)
}
type OffsetClause struct {
Offset string
- Number int64
+ Value Expression
}
func (e OffsetClause) String() string {
- s := []string{e.Offset, strconv.FormatInt(e.Number, 10)}
+ s := []string{e.Offset, e.Value.String()}
return joinWithSpace(s)
}
@@ -889,14 +918,19 @@ func (si Stdin) String() string {
}
type OrderItem struct {
- Item Expression
+ Value Expression
Direction Token
+ Nulls string
+ Position Token
}
-func (oi OrderItem) String() string {
- s := []string{oi.Item.String()}
- if !oi.Direction.IsEmpty() {
- s = append(s, oi.Direction.Literal)
+func (e OrderItem) String() string {
+ s := []string{e.Value.String()}
+ if !e.Direction.IsEmpty() {
+ s = append(s, e.Direction.Literal)
+ }
+ if 0 < len(e.Nulls) {
+ s = append(s, e.Nulls, e.Position.Literal)
}
return joinWithSpace(s)
}
@@ -973,6 +1007,68 @@ func (gc GroupConcat) String() string {
return gc.GroupConcat + "(" + joinWithSpace(s) + ")"
}
+type AnalyticFunction struct {
+ Name string
+ Option Option
+ Over string
+ AnalyticClause AnalyticClause
+}
+
+func (e AnalyticFunction) String() string {
+ s := []string{
+ e.Name + "(" + e.Option.String() + ")",
+ e.Over,
+ "(" + e.AnalyticClause.String() + ")",
+ }
+ return joinWithSpace(s)
+}
+
+type AnalyticClause struct {
+ Partition Expression
+ OrderByClause Expression
+}
+
+func (e AnalyticClause) String() string {
+ s := []string{}
+ if e.Partition != nil {
+ s = append(s, e.Partition.String())
+ }
+ if e.OrderByClause != nil {
+ s = append(s, e.OrderByClause.String())
+ }
+ return joinWithSpace(s)
+}
+
+func (e AnalyticClause) PartitionValues() []Expression {
+ if e.Partition == nil {
+ return nil
+ }
+ return e.Partition.(Partition).Values
+}
+
+func (e AnalyticClause) OrderValues() []Expression {
+ if e.OrderByClause == nil {
+ return nil
+ }
+
+ items := e.OrderByClause.(OrderByClause).Items
+ result := make([]Expression, len(items))
+ for i, v := range items {
+ result[i] = v.(OrderItem).Value
+ }
+ return result
+}
+
+type Partition struct {
+ PartitionBy string
+ Values []Expression
+}
+
+func (e Partition) String() string {
+ s := []string{e.PartitionBy, listExpressions(e.Values)}
+ return joinWithSpace(s)
+}
+
type Variable struct {
Name string
}
diff --git a/lib/parser/ast_test.go b/lib/parser/ast_test.go
index c972b2ae..1196337c 100644
--- a/lib/parser/ast_test.go
+++ b/lib/parser/ast_test.go
@@ -5,6 +5,7 @@ import (
"time"
"github.com/mithrandie/csvq/lib/ternary"
+ "reflect"
)
func TestIsPrimary(t *testing.T) {
@@ -516,17 +517,17 @@ func TestSelectQuery_String(t *testing.T) {
OrderBy: "order by",
Items: []Expression{
OrderItem{
- Item: Identifier{Literal: "column"},
+ Value: Identifier{Literal: "column"},
},
},
},
LimitClause: LimitClause{
- Limit: "limit",
- Number: 10,
+ Limit: "limit",
+ Value: NewInteger(10),
},
OffsetClause: OffsetClause{
Offset: "offset",
- Number: 10,
+ Value: NewInteger(10),
},
}
expect := "select column from table order by column limit 10 offset 10"
@@ -694,10 +695,10 @@ func TestOrderByClause_String(t *testing.T) {
OrderBy: "order by",
Items: []Expression{
OrderItem{
- Item: Identifier{Literal: "column1"},
+ Value: Identifier{Literal: "column1"},
},
OrderItem{
- Item: Identifier{Literal: "column2"},
+ Value: Identifier{Literal: "column2"},
Direction: Token{Token: ASC, Literal: "asc"},
},
},
@@ -709,15 +710,53 @@ func TestOrderByClause_String(t *testing.T) {
}
func TestLimitClause_String(t *testing.T) {
- e := LimitClause{Limit: "limit", Number: 10}
- expect := "limit 10"
+ e := LimitClause{Limit: "limit", Value: NewInteger(10), With: LimitWith{With: "with", Type: Token{Token: TIES, Literal: "ties"}}}
+ expect := "limit 10 with ties"
+ if e.String() != expect {
+ t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
+ }
+
+ e = LimitClause{Limit: "limit", Value: NewInteger(10), Percent: "percent"}
+ expect = "limit 10 percent"
+ if e.String() != expect {
+ t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
+ }
+}
+
+func TestLimitClause_IsPercentage(t *testing.T) {
+ e := LimitClause{Limit: "limit", Value: NewInteger(10)}
+ if e.IsPercentage() {
+ t.Errorf("percentage = %t, want %t for %#v", e.IsPercentage(), false, e)
+ }
+
+ e = LimitClause{Limit: "limit", Value: NewInteger(10), Percent: "percent"}
+ if !e.IsPercentage() {
+ t.Errorf("percentage = %t, want %t for %#v", e.IsPercentage(), true, e)
+ }
+}
+
+func TestLimitClause_IsWithTies(t *testing.T) {
+ e := LimitClause{Limit: "limit", Value: NewInteger(10)}
+ if e.IsWithTies() {
+ t.Errorf("with ties = %t, want %t for %#v", e.IsWithTies(), false, e)
+ }
+
+ e = LimitClause{Limit: "limit", Value: NewInteger(10), With: LimitWith{With: "with", Type: Token{Token: TIES, Literal: "ties"}}}
+ if !e.IsWithTies() {
+ t.Errorf("with ties = %t, want %t for %#v", e.IsWithTies(), true, e)
+ }
+}
+
+func TestLimitWith_String(t *testing.T) {
+ e := LimitWith{With: "with", Type: Token{Token: TIES, Literal: "ties"}}
+ expect := "with ties"
if e.String() != expect {
t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
}
}
func TestOffsetClause_String(t *testing.T) {
- e := OffsetClause{Offset: "offset", Number: 10}
+ e := OffsetClause{Offset: "offset", Value: NewInteger(10)}
expect := "offset 10"
if e.String() != expect {
t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
@@ -1269,7 +1308,7 @@ func TestStdin_String(t *testing.T) {
func TestOrderItem_String(t *testing.T) {
e := OrderItem{
- Item: Identifier{Literal: "column"},
+ Value: Identifier{Literal: "column"},
Direction: Token{Token: DESC, Literal: "desc"},
}
expect := "column desc"
@@ -1278,12 +1317,22 @@ func TestOrderItem_String(t *testing.T) {
}
e = OrderItem{
- Item: Identifier{Literal: "column"},
+ Value: Identifier{Literal: "column"},
}
expect = "column"
if e.String() != expect {
t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
}
+
+ e = OrderItem{
+ Value: Identifier{Literal: "column"},
+ Nulls: "nulls",
+ Position: Token{Token: FIRST, Literal: "first"},
+ }
+ expect = "column nulls first"
+ if e.String() != expect {
+ t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
+ }
}
func TestCase_String(t *testing.T) {
@@ -1376,6 +1425,121 @@ func TestGroupConcat_String(t *testing.T) {
}
}
+func TestAnalyticFunction_String(t *testing.T) {
+ e := AnalyticFunction{
+ Name: "avg",
+ Option: Option{
+ Args: []Expression{
+ Identifier{Literal: "column4"},
+ },
+ },
+ Over: "over",
+ AnalyticClause: AnalyticClause{
+ Partition: Partition{
+ PartitionBy: "partition by",
+ Values: []Expression{
+ Identifier{Literal: "column1"},
+ Identifier{Literal: "column2"},
+ },
+ },
+ OrderByClause: OrderByClause{
+ OrderBy: "order by",
+ Items: []Expression{
+ OrderItem{Value: Identifier{Literal: "column3"}},
+ },
+ },
+ },
+ }
+ expect := "avg(column4) over (partition by column1, column2 order by column3)"
+ if e.String() != expect {
+ t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
+ }
+}
+
+func TestAnalyticClause_String(t *testing.T) {
+ e := AnalyticClause{
+ Partition: Partition{
+ PartitionBy: "partition by",
+ Values: []Expression{
+ Identifier{Literal: "column1"},
+ Identifier{Literal: "column2"},
+ },
+ },
+ OrderByClause: OrderByClause{
+ OrderBy: "order by",
+ Items: []Expression{
+ OrderItem{Value: Identifier{Literal: "column3"}},
+ },
+ },
+ }
+ expect := "partition by column1, column2 order by column3"
+ if e.String() != expect {
+ t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
+ }
+}
+
+func TestAnalyticClause_PartitionValues(t *testing.T) {
+ e := AnalyticClause{
+ Partition: Partition{
+ PartitionBy: "partition by",
+ Values: []Expression{
+ Identifier{Literal: "column1"},
+ Identifier{Literal: "column2"},
+ },
+ },
+ }
+ expect := []Expression{
+ Identifier{Literal: "column1"},
+ Identifier{Literal: "column2"},
+ }
+ if !reflect.DeepEqual(e.PartitionValues(), expect) {
+ t.Errorf("partition values = %q, want %q for %#v", e.PartitionValues(), expect, e)
+ }
+
+ e = AnalyticClause{}
+ expect = []Expression(nil)
+ if !reflect.DeepEqual(e.PartitionValues(), expect) {
+ t.Errorf("partition values = %q, want %q for %#v", e.PartitionValues(), expect, e)
+ }
+}
+
+func TestAnalyticClause_OrderValues(t *testing.T) {
+ e := AnalyticClause{
+ OrderByClause: OrderByClause{
+ OrderBy: "order by",
+ Items: []Expression{
+ OrderItem{Value: Identifier{Literal: "column3"}},
+ },
+ },
+ }
+ expect := []Expression{
+ Identifier{Literal: "column3"},
+ }
+ if !reflect.DeepEqual(e.OrderValues(), expect) {
+ t.Errorf("order values = %q, want %q for %#v", e.OrderValues(), expect, e)
+ }
+
+ e = AnalyticClause{}
+ expect = []Expression(nil)
+ if !reflect.DeepEqual(e.OrderValues(), expect) {
+ t.Errorf("order values = %q, want %q for %#v", e.OrderValues(), expect, e)
+ }
+}
+
+func TestPartition_String(t *testing.T) {
+ e := Partition{
+ PartitionBy: "partition by",
+ Values: []Expression{
+ Identifier{Literal: "column1"},
+ Identifier{Literal: "column2"},
+ },
+ }
+ expect := "partition by column1, column2"
+ if e.String() != expect {
+ t.Errorf("string = %q, want %q for %#v", e.String(), expect, e)
+ }
+}
+
func TestVariable_String(t *testing.T) {
e := Variable{
Name: "@var",
diff --git a/lib/parser/conv.go b/lib/parser/conv.go
index c5ed1344..bd389d4f 100644
--- a/lib/parser/conv.go
+++ b/lib/parser/conv.go
@@ -38,11 +38,6 @@ func Float64ToStr(f float64) string {
return strconv.FormatFloat(f, 'f', -1, 64)
}
-func StrToInt64(s string) int64 {
- i, _ := strconv.ParseInt(s, 10, 64)
- return i
-}
-
func Float64ToPrimary(f float64) Primary {
s := Float64ToStr(f)
if i, e := strconv.ParseInt(s, 10, 64); e == nil {
@@ -55,9 +50,13 @@ func PrimaryToInteger(p Primary) Primary {
switch p.(type) {
case Integer:
return p
+ case Float:
+ if i, e := strconv.ParseInt(p.(Float).literal, 10, 64); e == nil {
+ return NewInteger(i)
+ }
case String:
- if f, e := strconv.ParseFloat(p.(String).Value(), 64); e == nil {
- return NewInteger(int64(f))
+ if i, e := strconv.ParseInt(p.(String).Value(), 10, 64); e == nil {
+ return NewInteger(i)
}
}
diff --git a/lib/parser/conv_test.go b/lib/parser/conv_test.go
index 2c913820..d943c456 100644
--- a/lib/parser/conv_test.go
+++ b/lib/parser/conv_test.go
@@ -70,16 +70,34 @@ func TestPrimaryToInteger(t *testing.T) {
t.Errorf("primary type = %T, want Integer for %#v", i, p)
}
+ p = NewFloat(1)
+ i = PrimaryToInteger(p)
+ if _, ok := i.(Integer); !ok {
+ t.Errorf("primary type = %T, want Integer for %#v", i, p)
+ }
+
+ p = NewFloat(1.6)
+ i = PrimaryToInteger(p)
+ if _, ok := i.(Null); !ok {
+ t.Errorf("primary type = %T, want Null for %#v", i, p)
+ }
+
p = NewString("1")
i = PrimaryToInteger(p)
if _, ok := i.(Integer); !ok {
t.Errorf("primary type = %T, want Integer for %#v", i, p)
}
+ p = NewString("1.5")
+ i = PrimaryToInteger(p)
+ if _, ok := i.(Null); !ok {
+ t.Errorf("primary type = %T, want Null for %#v", i, p)
+ }
+
p = NewString("error")
i = PrimaryToInteger(p)
if _, ok := i.(Null); !ok {
- t.Errorf("primary type = %T, want Integer for %#v", i, p)
+ t.Errorf("primary type = %T, want Null for %#v", i, p)
}
}
diff --git a/lib/parser/parser.go b/lib/parser/parser.go
index b23ac6be..4c08f110 100644
--- a/lib/parser/parser.go
+++ b/lib/parser/parser.go
@@ -67,60 +67,65 @@ const ASC = 57383
const DESC = 57384
const LIMIT = 57385
const OFFSET = 57386
-const JOIN = 57387
-const INNER = 57388
-const OUTER = 57389
-const LEFT = 57390
-const RIGHT = 57391
-const FULL = 57392
-const CROSS = 57393
-const ON = 57394
-const USING = 57395
-const NATURAL = 57396
-const UNION = 57397
-const INTERSECT = 57398
-const EXCEPT = 57399
-const ALL = 57400
-const ANY = 57401
-const EXISTS = 57402
-const IN = 57403
-const AND = 57404
-const OR = 57405
-const NOT = 57406
-const BETWEEN = 57407
-const LIKE = 57408
-const IS = 57409
-const NULL = 57410
-const DISTINCT = 57411
-const WITH = 57412
-const CASE = 57413
-const IF = 57414
-const ELSEIF = 57415
-const WHILE = 57416
-const WHEN = 57417
-const THEN = 57418
-const ELSE = 57419
-const DO = 57420
-const END = 57421
-const DECLARE = 57422
-const CURSOR = 57423
-const FOR = 57424
-const FETCH = 57425
-const OPEN = 57426
-const CLOSE = 57427
-const DISPOSE = 57428
-const GROUP_CONCAT = 57429
-const SEPARATOR = 57430
-const COMMIT = 57431
-const ROLLBACK = 57432
-const CONTINUE = 57433
-const BREAK = 57434
-const EXIT = 57435
-const PRINT = 57436
-const VAR = 57437
-const COMPARISON_OP = 57438
-const STRING_OP = 57439
-const SUBSTITUTION_OP = 57440
+const TIES = 57387
+const PERCENT = 57388
+const JOIN = 57389
+const INNER = 57390
+const OUTER = 57391
+const LEFT = 57392
+const RIGHT = 57393
+const FULL = 57394
+const CROSS = 57395
+const ON = 57396
+const USING = 57397
+const NATURAL = 57398
+const UNION = 57399
+const INTERSECT = 57400
+const EXCEPT = 57401
+const ALL = 57402
+const ANY = 57403
+const EXISTS = 57404
+const IN = 57405
+const AND = 57406
+const OR = 57407
+const NOT = 57408
+const BETWEEN = 57409
+const LIKE = 57410
+const IS = 57411
+const NULL = 57412
+const NULLS = 57413
+const DISTINCT = 57414
+const WITH = 57415
+const CASE = 57416
+const IF = 57417
+const ELSEIF = 57418
+const WHILE = 57419
+const WHEN = 57420
+const THEN = 57421
+const ELSE = 57422
+const DO = 57423
+const END = 57424
+const DECLARE = 57425
+const CURSOR = 57426
+const FOR = 57427
+const FETCH = 57428
+const OPEN = 57429
+const CLOSE = 57430
+const DISPOSE = 57431
+const GROUP_CONCAT = 57432
+const SEPARATOR = 57433
+const PARTITION = 57434
+const OVER = 57435
+const COMMIT = 57436
+const ROLLBACK = 57437
+const CONTINUE = 57438
+const BREAK = 57439
+const EXIT = 57440
+const PRINT = 57441
+const VAR = 57442
+const COMPARISON_OP = 57443
+const STRING_OP = 57444
+const SUBSTITUTION_OP = 57445
var yyToknames = [...]string{
"$end",
@@ -167,6 +172,8 @@ var yyToknames = [...]string{
"DESC",
"LIMIT",
"OFFSET",
+ "TIES",
+ "PERCENT",
"JOIN",
"INNER",
"OUTER",
@@ -191,6 +198,7 @@ var yyToknames = [...]string{
"LIKE",
"IS",
"NULL",
+ "NULLS",
"DISTINCT",
"WITH",
"CASE",
@@ -211,6 +219,8 @@ var yyToknames = [...]string{
"DISPOSE",
"GROUP_CONCAT",
"SEPARATOR",
+ "PARTITION",
+ "OVER",
"COMMIT",
"ROLLBACK",
"CONTINUE",
@@ -239,7 +249,7 @@ const yyEofCode = 1
const yyErrCode = 2
const yyInitialStackSize = 16
-//line parser.y:1325
+//line parser.y:1395
func SetDebugLevel(level int, verbose bool) {
yyDebug = level
@@ -259,300 +269,316 @@ var yyExca = [...]int{
1, -1,
-2, 0,
-1, 16,
- 55, 45,
- 56, 45,
57, 45,
+ 58, 45,
+ 59, 45,
-2, 56,
-1, 113,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 236,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 249,
-1, 132,
- 45, 224,
- 47, 228,
- -2, 160,
+ 47, 237,
+ 49, 241,
+ -2, 173,
-1, 167,
- 55, 46,
- 56, 46,
57, 46,
- -2, 74,
+ 58, 46,
+ 59, 46,
+ -2, 77,
-1, 169,
- 107, 121,
- -2, 220,
+ 112, 131,
+ -2, 233,
-1, 171,
- 75, 151,
- -2, 222,
+ 78, 166,
+ -2, 235,
-1, 180,
- 37, 121,
- 88, 121,
- 107, 121,
- -2, 220,
+ 37, 131,
+ 91, 131,
+ 112, 131,
+ -2, 233,
-1, 197,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 145,
- -1, 205,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 87,
- -1, 217,
- 47, 228,
- -2, 224,
- -1, 233,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 217,
- -1, 239,
- 67, 0,
- 96, 0,
- 99, 0,
- -2, 92,
- -1, 240,
- 67, 0,
- 96, 0,
- 99, 0,
- -2, 94,
- -1, 283,
- 61, 222,
- 65, 222,
- 66, 222,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 159,
+ -1, 204,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 61,
+ -1, 208,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 93,
+ -1, 221,
+ 49, 241,
+ -2, 237,
+ -1, 237,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 230,
+ -1, 243,
+ 69, 0,
+ 101, 0,
+ 104, 0,
+ -2, 102,
+ -1, 244,
+ 69, 0,
+ 101, 0,
+ 104, 0,
+ -2, 104,
+ -1, 287,
+ 63, 235,
+ 67, 235,
+ 68, 235,
-2, 51,
- -1, 329,
- 67, 0,
- 96, 0,
- 99, 0,
- -2, 103,
- -1, 333,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 156,
- -1, 367,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 175,
- -1, 393,
- 79, 153,
- -2, 222,
- -1, 397,
- 107, 83,
- 108, 83,
- -2, 46,
+ -1, 294,
+ 112, 131,
+ -2, 233,
+ -1, 295,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 64,
+ -1, 337,
+ 69, 0,
+ 101, 0,
+ 104, 0,
+ -2, 113,
+ -1, 341,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 171,
+ -1, 379,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 188,
-1, 405,
- 61, 222,
- 65, 222,
- 66, 222,
+ 82, 168,
+ -2, 235,
+ -1, 409,
+ 112, 86,
+ 113, 86,
+ -2, 46,
+ -1, 417,
+ 63, 235,
+ 67, 235,
+ 68, 235,
-2, 55,
- -1, 422,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 184,
- -1, 429,
- 75, 168,
- 77, 168,
- 79, 168,
- -2, 222,
- -1, 437,
- 91, 18,
- 92, 18,
+ -1, 438,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 197,
+ -1, 445,
+ 78, 181,
+ 80, 181,
+ 82, 181,
+ -2, 235,
+ -1, 453,
+ 96, 18,
+ 97, 18,
-2, 1,
- -1, 440,
- 61, 222,
- 65, 222,
- 66, 222,
- -2, 143,
+ -1, 457,
+ 63, 235,
+ 67, 235,
+ 68, 235,
+ -2, 157,
}
const yyPrivate = 57344
-const yyLast = 1132
+const yyLast = 1142
var yyAct = [...]int{
- 80, 40, 450, 40, 311, 459, 375, 44, 76, 380,
- 305, 321, 46, 47, 48, 49, 50, 51, 52, 297,
- 411, 2, 186, 94, 209, 132, 166, 203, 271, 194,
- 92, 67, 68, 69, 53, 43, 1, 388, 218, 216,
- 131, 111, 114, 40, 381, 258, 109, 86, 23, 77,
- 23, 338, 189, 64, 155, 133, 56, 45, 59, 119,
- 221, 137, 222, 223, 224, 219, 421, 374, 217, 183,
- 364, 362, 142, 183, 57, 57, 61, 136, 138, 146,
- 147, 148, 401, 300, 291, 288, 151, 59, 167, 157,
- 158, 159, 160, 161, 39, 39, 39, 37, 143, 176,
- 128, 400, 408, 206, 463, 16, 449, 433, 163, 162,
- 164, 432, 431, 154, 423, 420, 137, 39, 373, 363,
- 334, 185, 220, 59, 39, 59, 256, 40, 85, 38,
- 199, 38, 168, 169, 441, 295, 211, 263, 346, 344,
- 137, 342, 152, 151, 228, 153, 157, 158, 159, 160,
- 161, 40, 174, 180, 215, 45, 188, 159, 160, 161,
- 42, 110, 157, 158, 159, 160, 161, 42, 168, 164,
- 191, 192, 301, 264, 264, 184, 101, 103, 91, 156,
- 227, 234, 40, 119, 57, 213, 237, 42, 207, 42,
- 40, 144, 40, 40, 145, 465, 235, 232, 23, 90,
- 354, 172, 457, 273, 173, 438, 426, 264, 40, 241,
- 263, 392, 386, 349, 453, 324, 298, 42, 452, 323,
- 261, 137, 260, 454, 402, 317, 270, 314, 453, 23,
- 279, 261, 324, 339, 280, 40, 468, 464, 447, 316,
- 318, 425, 121, 320, 264, 104, 264, 264, 164, 243,
- 310, 267, 299, 242, 244, 266, 304, 303, 395, 182,
- 333, 308, 97, 190, 167, 326, 117, 264, 343, 345,
- 347, 102, 325, 40, 313, 322, 306, 175, 236, 38,
- 415, 179, 332, 371, 352, 353, 336, 284, 355, 286,
- 287, 369, 75, 108, 273, 285, 113, 285, 285, 269,
- 268, 350, 178, 137, 106, 348, 246, 245, 137, 211,
- 38, 307, 236, 302, 201, 370, 124, 358, 359, 361,
- 23, 125, 365, 357, 40, 366, 298, 385, 368, 116,
- 117, 118, 282, 372, 387, 259, 221, 383, 222, 223,
- 224, 219, 54, 397, 217, 397, 384, 397, 165, 221,
- 382, 222, 223, 224, 63, 40, 62, 171, 289, 389,
- 177, 149, 55, 264, 40, 229, 230, 187, 127, 115,
- 137, 23, 137, 298, 231, 120, 273, 139, 112, 417,
- 193, 197, 59, 404, 410, 406, 205, 418, 419, 376,
- 377, 378, 379, 59, 41, 414, 264, 416, 59, 66,
- 226, 38, 23, 290, 40, 233, 202, 434, 60, 264,
- 435, 130, 238, 239, 240, 59, 137, 292, 247, 248,
- 249, 250, 251, 252, 253, 437, 65, 444, 40, 93,
- 88, 445, 436, 446, 89, 262, 265, 443, 40, 237,
- 10, 442, 451, 9, 8, 7, 455, 6, 283, 58,
- 58, 23, 38, 40, 458, 456, 210, 70, 71, 72,
- 73, 74, 462, 448, 5, 4, 337, 40, 170, 296,
- 82, 195, 467, 196, 273, 23, 470, 135, 396, 134,
- 398, 460, 399, 38, 95, 23, 126, 3, 273, 129,
- 81, 58, 84, 140, 141, 469, 78, 83, 407, 79,
- 23, 204, 200, 327, 123, 329, 328, 356, 330, 331,
- 281, 36, 15, 274, 23, 100, 101, 103, 14, 104,
- 105, 13, 340, 12, 11, 272, 0, 0, 0, 341,
- 122, 0, 38, 0, 0, 221, 351, 222, 223, 224,
- 219, 412, 413, 217, 439, 0, 58, 0, 0, 197,
- 0, 0, 205, 0, 0, 0, 38, 0, 212, 58,
- 0, 214, 367, 0, 0, 225, 38, 0, 0, 0,
- 58, 0, 0, 0, 0, 122, 0, 0, 106, 0,
- 0, 38, 163, 162, 164, 390, 0, 154, 0, 0,
- 0, 0, 0, 0, 0, 38, 466, 0, 0, 257,
- 393, 0, 0, 0, 0, 296, 0, 296, 0, 296,
- 0, 102, 0, 278, 208, 0, 152, 151, 405, 153,
- 157, 158, 159, 160, 161, 296, 0, 0, 41, 0,
- 39, 0, 18, 34, 19, 0, 17, 0, 212, 0,
- 0, 0, 20, 422, 0, 21, 0, 0, 0, 0,
- 0, 58, 428, 0, 0, 429, 0, 309, 430, 312,
- 315, 212, 212, 0, 0, 0, 0, 0, 0, 0,
- 0, 296, 0, 440, 0, 0, 0, 0, 0, 59,
- 100, 101, 103, 0, 104, 105, 41, 0, 0, 275,
- 0, 32, 0, 0, 0, 122, 0, 26, 0, 0,
- 30, 27, 28, 29, 0, 0, 24, 25, 276, 277,
- 33, 35, 22, 0, 461, 0, 0, 0, 0, 0,
- 360, 0, 319, 42, 0, 0, 0, 0, 0, 0,
- 0, 212, 0, 58, 0, 98, 0, 0, 58, 99,
- 0, 0, 0, 106, 0, 315, 96, 0, 212, 0,
- 0, 122, 163, 162, 164, 0, 0, 154, 0, 0,
- 0, 0, 107, 0, 0, 0, 41, 0, 39, 0,
- 18, 34, 19, 0, 17, 0, 102, 198, 0, 0,
- 20, 87, 0, 21, 0, 0, 152, 151, 0, 153,
- 157, 158, 159, 160, 161, 212, 0, 254, 255, 0,
- 58, 0, 58, 0, 0, 312, 0, 0, 0, 212,
- 212, 0, 0, 0, 0, 424, 0, 59, 100, 101,
- 103, 0, 104, 105, 41, 0, 39, 31, 0, 32,
- 122, 0, 122, 0, 122, 26, 0, 0, 30, 27,
- 28, 29, 0, 0, 24, 25, 58, 0, 33, 35,
- 22, 409, 315, 163, 162, 164, 0, 0, 154, 0,
- 0, 42, 59, 100, 101, 103, 0, 104, 105, 41,
- 0, 0, 312, 98, 0, 0, 0, 99, 0, 0,
- 0, 106, 0, 0, 96, 0, 0, 152, 151, 0,
- 153, 157, 158, 159, 160, 161, 0, 0, 0, 255,
- 107, 59, 100, 101, 103, 0, 104, 105, 41, 0,
- 0, 293, 294, 0, 102, 0, 0, 0, 98, 87,
- 0, 0, 99, 0, 0, 0, 106, 0, 0, 96,
- 0, 0, 163, 162, 164, 0, 0, 154, 0, 0,
- 0, 163, 162, 164, 0, 107, 154, 0, 0, 0,
- 0, 0, 0, 0, 0, 427, 0, 98, 0, 102,
- 335, 99, 0, 0, 87, 106, 152, 151, 96, 153,
- 157, 158, 159, 160, 161, 152, 151, 0, 153, 157,
- 158, 159, 160, 161, 107, 163, 162, 164, 0, 0,
- 154, 0, 0, 0, 0, 163, 162, 164, 102, 403,
- 154, 0, 0, 87, 0, 163, 162, 164, 0, 394,
- 154, 0, 0, 0, 0, 0, 0, 0, 0, 152,
- 151, 181, 153, 157, 158, 159, 160, 161, 0, 152,
- 151, 0, 153, 157, 158, 159, 160, 161, 0, 152,
- 151, 0, 153, 157, 158, 159, 160, 161, 163, 162,
- 164, 0, 0, 154, 0, 0, 0, 0, 163, 162,
- 164, 0, 150, 154, 0, 0, 0, 391, 162, 164,
- 0, 0, 154, 0, 0, 0, 163, 0, 164, 0,
+ 80, 40, 392, 40, 53, 166, 44, 467, 319, 477,
+ 387, 46, 47, 48, 49, 50, 51, 52, 329, 305,
+ 43, 1, 313, 198, 205, 85, 38, 275, 38, 186,
+ 67, 68, 69, 427, 213, 194, 2, 94, 303, 92,
+ 111, 296, 400, 40, 393, 132, 262, 77, 222, 86,
+ 23, 37, 23, 220, 109, 346, 131, 64, 110, 155,
+ 45, 137, 114, 59, 16, 133, 56, 163, 162, 164,
+ 189, 142, 154, 437, 386, 413, 376, 119, 146, 147,
+ 148, 374, 136, 138, 57, 57, 61, 183, 167, 39,
+ 183, 308, 59, 163, 162, 164, 412, 424, 154, 176,
+ 299, 39, 292, 143, 152, 151, 128, 153, 157, 158,
+ 159, 160, 161, 488, 484, 39, 137, 45, 466, 449,
+ 185, 225, 448, 226, 227, 228, 223, 40, 447, 221,
+ 152, 151, 439, 153, 157, 158, 159, 160, 161, 436,
+ 137, 258, 259, 157, 158, 159, 160, 161, 419, 209,
+ 472, 40, 385, 375, 39, 342, 59, 174, 260, 59,
+ 39, 219, 210, 168, 294, 76, 201, 3, 168, 169,
+ 42, 241, 188, 268, 268, 240, 38, 458, 267, 163,
+ 162, 164, 40, 354, 154, 352, 224, 42, 191, 192,
+ 40, 350, 40, 40, 57, 217, 231, 232, 180, 42,
+ 23, 236, 42, 168, 239, 101, 103, 38, 309, 240,
+ 122, 268, 40, 267, 245, 184, 152, 151, 277, 153,
+ 157, 158, 159, 160, 161, 137, 264, 274, 259, 164,
+ 151, 23, 284, 157, 158, 159, 160, 161, 283, 40,
+ 119, 288, 144, 290, 291, 91, 328, 90, 268, 156,
+ 268, 268, 211, 455, 289, 122, 289, 289, 42, 483,
+ 238, 318, 145, 325, 172, 340, 322, 173, 167, 344,
+ 312, 268, 351, 353, 355, 311, 307, 40, 321, 356,
+ 486, 316, 475, 334, 330, 333, 454, 360, 361, 442,
+ 404, 363, 398, 215, 212, 357, 362, 341, 159, 160,
+ 161, 265, 38, 470, 358, 102, 332, 469, 471, 414,
+ 331, 137, 265, 277, 347, 470, 137, 332, 492, 485,
+ 464, 441, 298, 209, 372, 121, 23, 373, 367, 75,
+ 108, 104, 40, 113, 397, 382, 271, 377, 164, 370,
+ 270, 369, 407, 378, 182, 395, 190, 175, 179, 399,
+ 178, 409, 401, 409, 247, 409, 380, 38, 246, 248,
+ 117, 384, 97, 40, 273, 272, 250, 249, 116, 117,
+ 118, 371, 418, 314, 431, 268, 40, 306, 383, 122,
+ 381, 23, 137, 315, 137, 165, 310, 203, 38, 408,
+ 416, 410, 106, 411, 171, 433, 426, 177, 124, 277,
+ 324, 326, 301, 302, 490, 366, 327, 225, 268, 226,
+ 227, 228, 23, 423, 125, 365, 40, 193, 197, 286,
+ 54, 451, 204, 208, 396, 268, 394, 430, 263, 432,
+ 233, 234, 137, 421, 422, 122, 241, 63, 62, 235,
+ 462, 38, 237, 452, 40, 293, 149, 461, 463, 242,
+ 243, 244, 453, 88, 40, 251, 252, 253, 254, 255,
+ 256, 257, 468, 456, 465, 23, 460, 473, 120, 38,
+ 40, 474, 58, 58, 215, 55, 476, 459, 480, 38,
+ 70, 71, 72, 73, 74, 287, 59, 489, 40, 59,
+ 187, 306, 491, 23, 127, 38, 494, 478, 59, 495,
+ 115, 295, 139, 23, 230, 112, 277, 130, 60, 126,
+ 41, 66, 129, 38, 58, 493, 140, 141, 122, 23,
+ 122, 450, 122, 59, 277, 59, 100, 101, 103, 65,
+ 104, 105, 41, 93, 89, 266, 269, 23, 388, 389,
+ 390, 391, 306, 425, 335, 10, 337, 9, 8, 7,
+ 100, 101, 103, 6, 104, 105, 434, 435, 214, 5,
+ 4, 345, 225, 348, 226, 227, 228, 223, 170, 58,
+ 221, 82, 195, 304, 200, 196, 135, 359, 134, 200,
+ 482, 216, 58, 98, 218, 481, 95, 99, 229, 81,
+ 197, 106, 84, 58, 78, 96, 225, 208, 226, 227,
+ 228, 223, 428, 429, 221, 83, 79, 379, 420, 300,
+ 336, 107, 338, 339, 207, 106, 206, 202, 123, 364,
+ 285, 36, 261, 15, 278, 14, 13, 102, 199, 163,
+ 402, 164, 87, 349, 154, 12, 282, 11, 276, 0,
+ 0, 0, 0, 0, 41, 405, 39, 0, 18, 34,
+ 19, 102, 17, 0, 0, 0, 0, 0, 20, 0,
+ 0, 21, 0, 417, 0, 216, 152, 151, 0, 153,
+ 157, 158, 159, 160, 161, 0, 0, 0, 58, 0,
+ 0, 0, 0, 0, 317, 0, 320, 323, 216, 216,
+ 0, 0, 438, 0, 0, 0, 0, 0, 0, 0,
+ 0, 444, 0, 0, 445, 0, 0, 0, 279, 0,
+ 32, 0, 0, 304, 0, 304, 26, 304, 0, 30,
+ 27, 28, 29, 0, 0, 0, 457, 24, 25, 280,
+ 281, 33, 35, 22, 41, 0, 39, 304, 18, 34,
+ 19, 0, 17, 0, 42, 0, 200, 368, 20, 0,
+ 0, 21, 0, 200, 0, 0, 0, 0, 0, 0,
+ 0, 0, 216, 0, 58, 0, 0, 0, 479, 58,
+ 446, 0, 0, 0, 0, 0, 323, 0, 0, 216,
+ 0, 0, 0, 0, 0, 0, 0, 304, 0, 0,
+ 59, 100, 101, 103, 0, 104, 105, 41, 31, 39,
+ 32, 0, 0, 0, 0, 0, 26, 0, 0, 30,
+ 27, 28, 29, 0, 0, 0, 0, 24, 25, 0,
+ 0, 33, 35, 22, 0, 0, 0, 0, 0, 0,
+ 216, 0, 0, 0, 42, 58, 0, 58, 0, 0,
+ 320, 0, 0, 0, 216, 216, 0, 0, 98, 0,
+ 440, 0, 99, 0, 0, 0, 106, 0, 0, 0,
+ 96, 59, 100, 101, 103, 0, 104, 105, 41, 0,
+ 0, 0, 59, 100, 101, 103, 107, 104, 105, 41,
+ 0, 0, 0, 0, 0, 58, 0, 0, 0, 0,
+ 297, 323, 102, 0, 0, 0, 0, 87, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 163, 162,
+ 164, 0, 320, 154, 0, 0, 0, 298, 0, 98,
+ 0, 0, 0, 99, 0, 0, 0, 106, 0, 0,
+ 98, 96, 0, 0, 99, 0, 0, 0, 106, 0,
+ 0, 0, 96, 0, 0, 152, 151, 107, 153, 157,
+ 158, 159, 160, 161, 163, 162, 164, 0, 107, 154,
+ 0, 0, 0, 102, 343, 163, 162, 164, 87, 487,
+ 154, 0, 0, 0, 102, 0, 0, 0, 0, 87,
+ 443, 0, 0, 0, 0, 163, 162, 164, 0, 0,
+ 154, 152, 151, 0, 153, 157, 158, 159, 160, 161,
+ 415, 0, 152, 151, 0, 153, 157, 158, 159, 160,
+ 161, 0, 0, 0, 0, 0, 163, 162, 164, 0,
0, 154, 152, 151, 0, 153, 157, 158, 159, 160,
- 161, 164, 152, 151, 154, 153, 157, 158, 159, 160,
- 161, 152, 151, 0, 153, 157, 158, 159, 160, 161,
- 152, 151, 0, 153, 157, 158, 159, 160, 161, 0,
+ 161, 406, 163, 162, 164, 0, 0, 154, 0, 0,
+ 0, 163, 162, 164, 0, 0, 154, 0, 0, 181,
+ 163, 162, 164, 152, 151, 154, 153, 157, 158, 159,
+ 160, 161, 403, 162, 164, 150, 0, 154, 0, 152,
+ 151, 0, 153, 157, 158, 159, 160, 161, 152, 151,
+ 0, 153, 157, 158, 159, 160, 161, 152, 151, 0,
+ 153, 157, 158, 159, 160, 161, 0, 0, 164, 152,
+ 151, 154, 153, 157, 158, 159, 160, 161, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 152, 151, 0, 153, 157, 158, 159,
160, 161,
}
var yyPact = [...]int{
- 755, -1000, 755, -52, -52, -52, -52, -52, -52, -52,
- -52, -1000, -1000, -1000, -1000, -1000, 305, 342, 411, 394,
- 327, 325, 388, -52, -52, -52, 411, 411, 411, 411,
- 411, 897, 897, -52, 366, 897, 355, 274, 85, 173,
- -1000, -1000, 111, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, 273, 281, 411, 352, -8, 389, -1000,
- 54, 363, 411, 411, -52, -10, 93, -1000, -1000, -1000,
- 113, -52, -52, -52, 341, 986, -1000, -1000, -1000, -1000,
- -1000, -1000, -1000, -1000, -1000, 85, -1000, 813, 27, -1000,
- -1000, -1000, -1000, -1000, -1000, -1000, 897, 105, 61, 897,
- -1000, -1000, 170, -1000, -1000, -1000, -1000, 47, 943, 198,
- -39, -1000, 76, 46, 349, 54, 205, 205, 205, 897,
- 675, -1000, 23, 270, 400, 897, 82, 411, 411, -1000,
- 411, 349, 14, -1000, 378, -1000, -1000, -1000, -1000, 54,
- 38, 339, -1000, 388, 897, 99, -1000, -1000, -1000, 383,
- 755, 897, 897, 897, 184, 188, 248, 897, 897, 897,
- 897, 897, 897, 897, -1000, 690, 19, -1000, 411, 173,
- 145, 996, 31, 31, 190, 241, -1000, 1027, -1000, -1000,
- 173, 617, 411, 383, 510, -1000, 294, 897, -1000, 111,
- -1000, 111, 111, 996, -1000, -23, 336, 996, -1000, -1000,
- -1000, 397, -1000, -1000, -24, 870, 31, 83, -1000, 355,
- -25, 73, 63, -1000, -1000, -1000, 268, 303, 229, 266,
- 54, -1000, -1000, -1000, -1000, -1000, 411, 349, 411, 121,
- 119, 411, -1000, 996, 111, -52, -35, 142, 62, -11,
- -11, 236, 897, 31, 897, 31, 31, 55, 55, -1000,
- -1000, -1000, 1014, 1027, -1000, 897, -1000, -1000, 13, 858,
- 156, 897, -1000, 813, -1000, -1000, 31, 35, 33, 32,
- 305, 134, 617, -1000, -1000, 897, -52, -52, 122, -1000,
- -52, 284, 277, 996, 210, -1000, -1000, 210, 675, 411,
- -1000, 897, -1000, -1000, -1000, -1000, -37, 12, -38, 349,
- 411, 897, 54, 246, 229, 238, -1000, 54, -1000, -1000,
- -1000, 11, -41, 359, 411, 316, -1000, 411, 310, -52,
- -1000, 133, 142, 755, 897, -1000, -1000, 1005, -1000, -11,
- -1000, -1000, -1000, 791, -1000, -1000, -1000, 132, 145, 897,
- 933, 196, 104, -1000, 104, -1000, 104, -1000, -6, 150,
- -1000, 923, -1000, -1000, 617, -1000, -1000, 897, 897, -1000,
- -1000, -1000, 31, 81, 411, -1000, -1000, 996, 489, 54,
- 235, 54, 290, -1000, 411, -1000, -1000, -1000, 411, 411,
- 8, -42, 897, 7, 411, -1000, 169, 127, 159, -1000,
- 879, 897, -1000, 996, 897, 31, 5, -1000, 4, 0,
- -1000, 402, -52, 617, 126, 996, -1000, -1000, 31, -1000,
- -1000, -1000, 897, 28, 290, 54, 489, -1000, -1000, -1000,
- 359, 411, 996, -1000, -1000, -52, 166, 755, 1027, 996,
- -1000, -1000, -1000, -1000, -1, -1000, 141, 755, 149, -1000,
- 996, 411, 290, -1000, -1000, -1000, -1000, -52, -1000, -1000,
- 123, 141, 617, 897, -52, -3, -1000, 165, 116, 155,
- -1000, 520, -1000, -1000, -52, 164, 617, -1000, -52, -1000,
- -1000,
+ 723, -1000, 723, -54, -54, -54, -54, -54, -54, -54,
+ -54, -1000, -1000, -1000, -1000, -1000, 383, 455, 519, 494,
+ 409, 408, 500, -54, -54, -54, 519, 519, 519, 519,
+ 519, 868, 868, -54, 493, 868, 486, 311, 137, 253,
+ -1000, -1000, 147, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, 355, 374, 519, 478, -7, 485, -1000,
+ 59, 488, 519, 519, -54, -10, 139, -1000, -1000, -1000,
+ 178, -54, -54, -54, 426, 986, -1000, -1000, -1000, -1000,
+ -1000, -1000, -1000, -1000, -1000, 137, -1000, 786, 58, -1000,
+ -1000, -1000, -1000, -1000, -1000, -1000, 868, 163, 91, 868,
+ -1000, -1000, 199, -1000, -1000, -1000, -1000, 87, 968, 281,
+ -26, -1000, 111, 3, 472, 59, 286, 286, 286, 868,
+ 521, -1000, 54, 343, 868, 868, 141, 519, 519, -1000,
+ 519, 472, 73, -1000, 482, -1000, -1000, -1000, -1000, 59,
+ 86, 404, -1000, 500, 868, 175, -1000, -1000, -1000, 499,
+ 723, 868, 868, 868, 272, 291, 306, 868, 868, 868,
+ 868, 868, 868, 868, -1000, 29, 46, -1000, 519, 253,
+ 223, 977, 67, 67, 273, 304, -1000, 1032, -1000, -1000,
+ 253, 633, 519, 499, 545, -1000, 381, 868, -1000, 147,
+ -1000, 147, 147, 977, -1000, -11, 423, 977, -1000, -1000,
+ 53, -1000, -1000, 868, 844, -1000, -13, 361, 977, -1000,
+ 67, 88, -1000, 486, -22, 104, 93, -1000, -1000, -1000,
+ 339, 359, 324, 336, 59, -1000, -1000, -1000, -1000, -1000,
+ 519, 472, 519, 155, 152, 519, -1000, 977, 147, -54,
+ -23, 230, 38, 128, 128, 322, 868, 67, 868, 67,
+ 67, 191, 191, -1000, -1000, -1000, 565, 1032, -1000, 868,
+ -1000, -1000, 43, 857, 234, 868, -1000, 786, -1000, -1000,
+ 67, 80, 74, 72, 383, 213, 633, -1000, -1000, 868,
+ -54, -54, 215, -1000, -54, 376, 365, 977, 302, -1000,
+ -1000, 302, 521, 519, 253, 977, -1000, 249, 326, 868,
+ 256, -1000, -1000, -1000, -32, 41, -37, 472, 519, 868,
+ 59, 333, 324, 331, -1000, 59, -1000, -1000, -1000, 40,
+ -39, 508, 519, 392, -1000, 519, 388, -54, -1000, 210,
+ 230, 723, 868, -1000, -1000, 998, -1000, 128, -1000, -1000,
+ -1000, 115, -1000, -1000, -1000, 208, 223, 868, 952, 278,
+ 102, -1000, 102, -1000, 102, -1000, -16, 232, -1000, 921,
+ -1000, -1000, 633, -1000, -1000, 868, 868, -1000, -1000, 36,
+ -1000, -1000, -1000, 403, 67, 76, 519, -1000, -1000, 977,
+ 548, 59, 327, 59, 514, -1000, 519, -1000, -1000, -1000,
+ 519, 519, 27, -40, 868, 20, 519, -1000, 246, 207,
+ 241, -1000, 901, 868, -1000, 977, 868, 67, 16, -1000,
+ 10, 7, -1000, 516, -54, 633, 204, 977, -1000, 160,
+ -1000, -1000, -1000, -1000, 67, -1000, -1000, -1000, 868, 66,
+ 514, 59, 548, -1000, -1000, -1000, 508, 519, 977, -1000,
+ -1000, -54, 245, 723, 1032, 977, -1000, -1000, -1000, -1000,
+ 6, -1000, 227, 723, 231, 39, -1000, 977, 519, 514,
+ -1000, -1000, -1000, -1000, -54, -1000, -1000, 200, 227, 633,
+ 868, -54, 167, 2, -1000, 244, 198, 239, -1000, 890,
+ -1000, 1, 383, 364, -1000, -54, 243, 633, -1000, -1000,
+ 868, -1000, -54, -1000, -1000, -1000,
}
var yyPgo = [...]int{
- 0, 35, 28, 21, 525, 524, 523, 521, 518, 513,
- 512, 487, 105, 97, 511, 42, 22, 510, 507, 34,
- 504, 502, 49, 8, 260, 262, 135, 501, 0, 499,
- 497, 496, 492, 490, 45, 484, 55, 479, 25, 477,
- 20, 473, 471, 470, 468, 466, 19, 26, 27, 40,
- 56, 4, 29, 51, 465, 464, 456, 24, 447, 445,
- 444, 44, 9, 6, 443, 440, 37, 11, 5, 2,
- 430, 434, 199, 178, 30, 429, 23, 128, 46, 47,
- 426, 53, 335, 54, 417, 39, 10, 38, 52, 179,
- 7,
+ 0, 20, 27, 36, 638, 637, 635, 626, 625, 624,
+ 623, 167, 64, 51, 621, 62, 29, 620, 619, 4,
+ 618, 41, 617, 47, 165, 297, 362, 38, 24, 616,
+ 614, 609, 608, 0, 606, 605, 594, 592, 589, 46,
+ 586, 23, 585, 580, 65, 578, 45, 576, 33, 575,
+ 572, 571, 568, 561, 19, 5, 56, 66, 8, 35,
+ 55, 560, 559, 558, 34, 553, 549, 548, 44, 2,
+ 10, 547, 545, 42, 18, 9, 7, 453, 534, 247,
+ 245, 39, 533, 37, 25, 54, 49, 529, 57, 428,
+ 59, 53, 22, 48, 70, 249, 6,
}
var yyR1 = [...]int{
@@ -562,24 +588,26 @@ var yyR1 = [...]int{
8, 8, 8, 8, 9, 9, 9, 9, 10, 10,
11, 12, 12, 12, 12, 13, 13, 14, 15, 15,
16, 16, 17, 17, 18, 18, 19, 19, 20, 20,
- 21, 21, 22, 22, 22, 22, 22, 22, 23, 23,
- 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
- 24, 24, 25, 25, 26, 26, 27, 84, 84, 84,
- 28, 29, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 31, 31, 31, 31, 31, 32, 32, 32, 33,
- 33, 34, 34, 34, 35, 35, 36, 36, 36, 37,
- 37, 38, 38, 38, 38, 38, 38, 39, 39, 39,
- 39, 39, 40, 40, 40, 41, 41, 42, 42, 43,
- 44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
- 49, 49, 50, 50, 51, 51, 52, 52, 53, 53,
- 54, 54, 54, 54, 55, 56, 57, 57, 58, 58,
- 59, 60, 60, 61, 61, 62, 62, 63, 63, 63,
- 63, 63, 64, 64, 65, 66, 66, 67, 67, 68,
- 68, 69, 69, 70, 71, 72, 72, 73, 73, 74,
- 75, 76, 77, 78, 78, 79, 80, 80, 81, 81,
- 82, 82, 83, 83, 85, 85, 86, 86, 87, 87,
- 87, 87, 88, 88, 89, 89, 90, 90,
+ 20, 21, 21, 22, 22, 23, 23, 23, 23, 23,
+ 23, 24, 24, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 26, 26, 27, 27, 28,
+ 28, 29, 29, 30, 30, 31, 31, 31, 32, 32,
+ 33, 34, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+ 35, 36, 36, 36, 36, 36, 37, 37, 37, 38,
+ 38, 39, 39, 39, 40, 40, 41, 42, 43, 43,
+ 44, 44, 44, 45, 45, 46, 46, 46, 46, 46,
+ 46, 47, 47, 47, 47, 47, 48, 48, 48, 49,
+ 49, 49, 50, 50, 51, 52, 52, 53, 53, 54,
+ 54, 55, 55, 56, 56, 57, 57, 58, 58, 59,
+ 59, 60, 60, 61, 61, 61, 61, 62, 63, 64,
+ 64, 65, 65, 66, 67, 67, 68, 68, 69, 69,
+ 70, 70, 70, 70, 70, 71, 71, 72, 73, 73,
+ 74, 74, 75, 75, 76, 76, 77, 78, 79, 79,
+ 80, 80, 81, 82, 83, 84, 85, 85, 86, 87,
+ 87, 88, 88, 89, 89, 90, 90, 91, 91, 92,
+ 92, 93, 93, 93, 93, 94, 94, 95, 95, 96,
+ 96,
}
var yyR2 = [...]int{
@@ -588,137 +616,143 @@ var yyR2 = [...]int{
3, 2, 2, 2, 6, 3, 3, 3, 5, 8,
9, 7, 9, 2, 8, 9, 2, 2, 5, 3,
4, 5, 4, 4, 4, 1, 1, 3, 0, 2,
- 0, 2, 0, 3, 0, 2, 0, 3, 0, 2,
- 0, 2, 1, 1, 1, 1, 1, 1, 1, 3,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 3, 3, 1, 1, 3, 2, 0, 1, 1,
+ 0, 2, 0, 3, 0, 2, 0, 3, 0, 3,
+ 4, 0, 2, 0, 2, 1, 1, 1, 1, 1,
+ 1, 1, 3, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 3, 1, 1, 3, 1,
+ 3, 2, 4, 1, 1, 0, 1, 1, 1, 1,
3, 3, 3, 3, 3, 3, 4, 4, 6, 6,
4, 6, 4, 4, 4, 6, 4, 4, 6, 4,
2, 3, 3, 3, 3, 3, 3, 3, 2, 4,
- 1, 0, 2, 2, 5, 7, 1, 2, 3, 1,
- 1, 1, 1, 2, 3, 1, 1, 5, 5, 6,
- 6, 4, 0, 2, 4, 1, 1, 1, 3, 5,
- 0, 1, 0, 2, 1, 3, 1, 3, 1, 3,
- 1, 3, 1, 3, 1, 3, 1, 3, 4, 2,
- 5, 8, 4, 7, 6, 3, 1, 3, 4, 5,
- 6, 6, 8, 1, 3, 1, 3, 0, 1, 1,
- 2, 2, 5, 7, 7, 4, 2, 0, 2, 4,
- 2, 0, 2, 1, 1, 1, 2, 1, 2, 1,
- 1, 1, 1, 1, 3, 3, 1, 3, 1, 3,
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
- 1, 1, 0, 1, 1, 1, 0, 1,
+ 1, 0, 2, 2, 5, 7, 8, 2, 0, 3,
+ 1, 2, 3, 1, 1, 1, 1, 2, 3, 1,
+ 1, 5, 5, 6, 6, 4, 0, 2, 4, 1,
+ 1, 1, 1, 3, 5, 0, 1, 0, 2, 1,
+ 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
+ 3, 4, 2, 5, 8, 4, 7, 6, 3, 1,
+ 3, 4, 5, 6, 6, 8, 1, 3, 1, 3,
+ 0, 1, 1, 2, 2, 5, 7, 7, 4, 2,
+ 0, 2, 4, 2, 0, 2, 1, 1, 1, 2,
+ 1, 2, 1, 1, 1, 1, 1, 3, 3, 1,
+ 3, 1, 3, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 1, 1, 0, 1, 1, 1, 0,
+ 1,
}
var yyChk = [...]int{
- -1000, -1, -3, -11, -54, -55, -58, -59, -60, -64,
- -65, -5, -6, -7, -8, -10, -12, 19, 15, 17,
- 25, 28, 95, -79, 89, 90, 80, 84, 85, 86,
- 83, 72, 74, 93, 16, 94, -14, -13, -77, 13,
- -28, 11, 106, -1, -90, 109, -90, -90, -90, -90,
- -90, -90, -90, -19, 37, 20, -50, -36, -70, 4,
- 14, -50, 29, 29, -81, -80, 11, -90, -90, -90,
- -70, -70, -70, -70, -70, -24, -23, -22, -31, -29,
- -28, -33, -43, -30, -32, -77, -79, 106, -70, -71,
- -72, -73, -74, -75, -76, -35, 71, -25, 60, 64,
- 5, 6, 101, 7, 9, 10, 68, 87, -24, -78,
- -77, -90, 12, -24, -15, 14, 55, 56, 57, 98,
- -82, 69, -11, -20, 43, 40, -70, 16, 108, -70,
- 22, -49, -38, -36, -37, -39, 23, -28, 24, 14,
- -70, -70, -90, 108, 98, 81, -90, -90, -90, 20,
- 76, 97, 96, 99, 67, -83, -89, 100, 101, 102,
- 103, 104, 63, 62, 64, -24, -47, -28, 105, 106,
- -44, -24, 96, 99, -83, -89, -28, -24, -72, -73,
- 106, 78, 61, 108, 99, -90, -16, 18, -49, -88,
- 58, -88, -88, -24, -52, -42, -41, -24, 102, 107,
- -21, 44, 6, -48, -27, -24, 21, 106, -11, -57,
- -56, -23, -70, -50, -70, -16, -85, 54, -87, 51,
- 108, 46, 48, 49, 50, -70, 22, -49, 106, 26,
- 27, 35, -81, -24, 82, -78, -77, -1, -24, -24,
- -24, -83, 65, 61, 66, 59, 58, -24, -24, -24,
- -24, -24, -24, -24, 107, 108, 107, -70, -34, -82,
- -53, 75, -25, 106, -28, -25, 65, 61, 59, 58,
- -34, -2, -4, -3, -9, 72, 91, 92, -70, -78,
- -22, -17, 38, -24, -13, -12, -13, -13, 108, 22,
- 6, 108, -84, 41, 42, -26, -25, -46, -23, -15,
- 108, 99, 45, -85, -87, -86, 47, 45, -49, -70,
- -16, -51, -70, -61, 106, -70, -23, 106, -23, -11,
- -90, -67, -66, 77, 73, -74, -76, -24, -25, -24,
- -25, -25, -47, -24, 107, 102, -47, -45, -53, 77,
- -24, -25, 106, -28, 106, -28, 106, -28, -19, 79,
- -2, -24, -90, -90, 78, -90, -18, 39, 40, -52,
- -70, -48, 108, 107, 108, -16, -57, -24, -38, 45,
- -86, 45, -38, 107, 108, -63, 30, 31, 32, 33,
- -62, -61, 34, -46, 36, -90, 79, -67, -66, -1,
- -24, 62, 79, -24, 76, 62, -26, -28, -26, -26,
- 107, 88, 74, 76, -2, -24, -47, -26, 21, -11,
- -46, -40, 52, 53, -38, 45, -38, -51, -23, -23,
- 107, 108, -24, 107, -70, 72, 79, 76, -24, -24,
- -25, 107, 107, 107, 5, -90, -2, -3, 79, -26,
- -24, 106, -38, -40, -63, -62, -90, 72, -1, 107,
- -69, -68, 77, 73, 74, -51, -90, 79, -69, -68,
- -2, -24, -90, 107, 72, 79, 76, -90, 72, -2,
- -90,
+ -1000, -1, -3, -11, -61, -62, -65, -66, -67, -71,
+ -72, -5, -6, -7, -8, -10, -12, 19, 15, 17,
+ 25, 28, 100, -86, 94, 95, 83, 87, 88, 89,
+ 86, 75, 77, 98, 16, 99, -14, -13, -84, 13,
+ -33, 11, 111, -1, -96, 114, -96, -96, -96, -96,
+ -96, -96, -96, -19, 37, 20, -57, -44, -77, 4,
+ 14, -57, 29, 29, -88, -87, 11, -96, -96, -96,
+ -77, -77, -77, -77, -77, -25, -24, -23, -36, -34,
+ -33, -38, -51, -35, -37, -84, -86, 111, -77, -78,
+ -79, -80, -81, -82, -83, -40, 74, -26, 62, 66,
+ 5, 6, 106, 7, 9, 10, 70, 90, -25, -85,
+ -84, -96, 12, -25, -15, 14, 57, 58, 59, 103,
+ -89, 72, -11, -20, 43, 40, -77, 16, 113, -77,
+ 22, -56, -46, -44, -45, -47, 23, -33, 24, 14,
+ -77, -77, -96, 113, 103, 84, -96, -96, -96, 20,
+ 79, 102, 101, 104, 69, -90, -95, 105, 106, 107,
+ 108, 109, 65, 64, 66, -25, -55, -33, 110, 111,
+ -52, -25, 101, 104, -90, -95, -33, -25, -79, -80,
+ 111, 81, 63, 113, 104, -96, -16, 18, -56, -94,
+ 60, -94, -94, -25, -59, -50, -49, -25, -41, 107,
+ -77, 112, -22, 44, -25, -28, -29, -30, -25, -41,
+ 21, 111, -11, -64, -63, -24, -77, -57, -77, -16,
+ -91, 56, -93, 53, 113, 48, 50, 51, 52, -77,
+ 22, -56, 111, 26, 27, 35, -88, -25, 85, -85,
+ -84, -1, -25, -25, -25, -90, 67, 63, 68, 61,
+ 60, -25, -25, -25, -25, -25, -25, -25, 112, 113,
+ 112, -77, -39, -89, -60, 78, -26, 111, -33, -26,
+ 67, 63, 61, 60, -39, -2, -4, -3, -9, 75,
+ 96, 97, -77, -85, -23, -17, 38, -25, -13, -12,
+ -13, -13, 113, 22, 111, -25, -21, 46, 73, 113,
+ -31, 41, 42, -27, -26, -54, -24, -15, 113, 104,
+ 47, -91, -93, -92, 49, 47, -56, -77, -16, -58,
+ -77, -68, 111, -77, -24, 111, -24, -11, -96, -74,
+ -73, 80, 76, -81, -83, -25, -26, -25, -26, -26,
+ -55, -25, 112, 107, -55, -53, -60, 80, -25, -26,
+ 111, -33, 111, -33, 111, -33, -19, 82, -2, -25,
+ -96, -96, 81, -96, -18, 39, 40, -59, -77, -39,
+ -21, 45, -28, 71, 113, 112, 113, -16, -64, -25,
+ -46, 47, -92, 47, -46, 112, 113, -70, 30, 31,
+ 32, 33, -69, -68, 34, -54, 36, -96, 82, -74,
+ -73, -1, -25, 64, 82, -25, 79, 64, -27, -33,
+ -27, -27, 112, 91, 77, 79, -2, -25, -55, 112,
+ -32, 30, 31, -27, 21, -11, -54, -48, 54, 55,
+ -46, 47, -46, -58, -24, -24, 112, 113, -25, 112,
+ -77, 75, 82, 79, -25, -25, -26, 112, 112, 112,
+ 5, -96, -2, -3, 82, 93, -27, -25, 111, -46,
+ -48, -70, -69, -96, 75, -1, 112, -76, -75, 80,
+ 76, 77, 111, -58, -96, 82, -76, -75, -2, -25,
+ -96, -42, -43, 92, 112, 75, 82, 79, 112, -19,
+ 40, -96, 75, -2, -55, -96,
}
var yyDef = [...]int{
- 1, -2, 1, 236, 236, 236, 236, 236, 236, 236,
- 236, 13, 14, 15, 16, 17, -2, 0, 0, 0,
- 0, 0, 0, 236, 236, 236, 0, 0, 0, 0,
- 0, 0, 0, 236, 0, 0, 48, 0, 0, 220,
- 46, 212, 0, 2, 5, 237, 6, 7, 8, 9,
- 10, 11, 12, 58, 0, 0, 0, 162, 126, 203,
- 0, 0, 0, 0, 236, 218, 216, 21, 22, 23,
- 0, 236, 236, 236, 0, 222, 70, 71, 72, 73,
- 74, 75, 76, 77, 78, 79, 80, 0, 68, 62,
- 63, 64, 65, 66, 67, 120, 150, 222, 0, 0,
- 204, 205, 0, 207, 209, 210, 211, 0, 222, 0,
- 79, 33, 0, -2, 50, 0, 232, 232, 232, 0,
- 0, 221, 0, 60, 0, 0, 0, 0, 0, 127,
- 0, 50, -2, 131, 132, 135, 136, 129, 130, 0,
+ 1, -2, 1, 249, 249, 249, 249, 249, 249, 249,
+ 249, 13, 14, 15, 16, 17, -2, 0, 0, 0,
+ 0, 0, 0, 249, 249, 249, 0, 0, 0, 0,
+ 0, 0, 0, 249, 0, 0, 48, 0, 0, 233,
+ 46, 225, 0, 2, 5, 250, 6, 7, 8, 9,
+ 10, 11, 12, 58, 0, 0, 0, 175, 140, 216,
+ 0, 0, 0, 0, 249, 231, 229, 21, 22, 23,
+ 0, 249, 249, 249, 0, 235, 73, 74, 75, 76,
+ 77, 78, 79, 80, 81, 82, 83, 0, 71, 65,
+ 66, 67, 68, 69, 70, 130, 165, 235, 0, 0,
+ 217, 218, 0, 220, 222, 223, 224, 0, 235, 0,
+ 82, 33, 0, -2, 50, 0, 245, 245, 245, 0,
+ 0, 234, 0, 63, 0, 0, 0, 0, 0, 141,
+ 0, 50, -2, 145, 146, 149, 150, 143, 144, 0,
0, 0, 20, 0, 0, 0, 25, 26, 27, 0,
- 1, 0, 234, 235, 222, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 223, 222, 0, -2, 0, -2,
- 0, -2, 234, 235, 0, 0, 110, 118, 206, 208,
+ 1, 0, 247, 248, 235, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 236, 235, 0, -2, 0, -2,
+ 0, -2, 247, 248, 0, 0, 120, 128, 219, 221,
-2, 3, 0, 0, 0, 39, 52, 0, 49, 0,
- 233, 0, 0, 215, 47, 166, 147, -2, 146, 90,
- 40, 0, 59, 57, 158, -2, 0, 0, 172, 48,
- 176, 0, 68, 163, 128, 178, 0, -2, 226, 0,
- 0, 225, 229, 230, 231, 133, 0, 50, 0, 0,
- 0, 0, 219, -2, 0, 236, 213, 197, 91, -2,
- -2, 0, 0, 0, 0, 0, 0, 111, 112, 113,
- 114, 115, 116, 117, 81, 0, 82, 69, 0, 0,
- 152, 0, 93, 0, 83, 95, 0, 0, 0, 0,
- 56, 0, 3, 18, 19, 0, 236, 236, 0, 214,
- 236, 54, 0, -2, 42, 45, 43, 44, 0, 0,
- 61, 0, 86, 88, 89, 170, 84, 0, 154, 50,
- 0, 0, 0, 0, 226, 0, 227, 0, 161, 134,
- 179, 0, 164, 187, 0, 183, 192, 0, 0, 236,
- 28, 0, 197, 1, 0, 96, 97, 222, 100, -2,
- 104, 107, 157, -2, 119, 122, 123, 0, 169, 0,
- 222, 0, 0, 102, 0, 106, 0, 109, 0, 0,
- 4, 222, 36, 37, 3, 38, 41, 0, 0, 167,
- 148, 159, 0, 0, 0, 174, 177, -2, 142, 0,
- 0, 0, 141, 180, 0, 181, 188, 189, 0, 0,
- 0, 185, 0, 0, 0, 24, 0, 0, 196, 198,
- 222, 0, 149, -2, 0, 0, 0, -2, 0, 0,
- 124, 0, 236, 1, 0, -2, 53, 85, 0, 173,
- 155, 137, 0, 0, 138, 0, 142, 165, 190, 191,
- 187, 0, -2, 193, 194, 236, 0, 1, 98, -2,
- 99, 101, 105, 108, 0, 31, 201, -2, 0, 171,
- -2, 0, 140, 139, 182, 186, 29, 236, 195, 125,
- 0, 201, 3, 0, 236, 0, 30, 0, 0, 200,
- 202, 222, 32, 144, 236, 0, 3, 34, 236, 199,
- 35,
+ 246, 0, 0, 228, 47, 179, 162, -2, 160, 161,
+ 71, 100, 40, 0, -2, 57, 89, 95, -2, 94,
+ 0, 0, 185, 48, 189, 0, 71, 176, 142, 191,
+ 0, -2, 239, 0, 0, 238, 242, 243, 244, 147,
+ 0, 50, 0, 0, 0, 0, 232, -2, 0, 249,
+ 226, 210, 101, -2, -2, 0, 0, 0, 0, 0,
+ 0, 121, 122, 123, 124, 125, 126, 127, 84, 0,
+ 85, 72, 0, 0, 167, 0, 103, 0, 86, 105,
+ 0, 0, 0, 0, 56, 0, 3, 18, 19, 0,
+ 249, 249, 0, 227, 249, 54, 0, -2, 42, 45,
+ 43, 44, 0, 0, -2, -2, 59, 61, 0, 0,
+ 91, 96, 97, 183, 87, 0, 169, 50, 0, 0,
+ 0, 0, 239, 0, 240, 0, 174, 148, 192, 0,
+ 177, 200, 0, 196, 205, 0, 0, 249, 28, 0,
+ 210, 1, 0, 106, 107, 235, 110, -2, 114, 117,
+ 172, -2, 129, 132, 133, 0, 182, 0, 235, 0,
+ 0, 112, 0, 116, 0, 119, 0, 0, 4, 235,
+ 36, 37, 3, 38, 41, 0, 0, 180, 163, 0,
+ 60, 62, 90, 0, 0, 0, 0, 187, 190, -2,
+ 156, 0, 0, 0, 155, 193, 0, 194, 201, 202,
+ 0, 0, 0, 198, 0, 0, 0, 24, 0, 0,
+ 209, 211, 235, 0, 164, -2, 0, 0, 0, -2,
+ 0, 0, 134, 0, 249, 1, 0, -2, 53, 129,
+ 92, 98, 99, 88, 0, 186, 170, 151, 0, 0,
+ 152, 0, 156, 178, 203, 204, 200, 0, -2, 206,
+ 207, 249, 0, 1, 108, -2, 109, 111, 115, 118,
+ 0, 31, 214, -2, 0, 0, 184, -2, 0, 154,
+ 153, 195, 199, 29, 249, 208, 135, 0, 214, 3,
+ 0, 249, 138, 0, 30, 0, 0, 213, 215, 235,
+ 32, 0, 56, 0, 158, 249, 0, 3, 136, 137,
+ 0, 34, 249, 212, 139, 35,
}
var yyTok1 = [...]int{
1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 104, 3, 3,
- 106, 107, 102, 100, 108, 101, 105, 103, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 109,
- 3, 99,
+ 3, 3, 3, 3, 3, 3, 3, 109, 3, 3,
+ 111, 112, 107, 105, 113, 106, 110, 108, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 114,
+ 3, 104,
}
var yyTok2 = [...]int{
@@ -731,7 +765,8 @@ var yyTok2 = [...]int{
62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
- 92, 93, 94, 95, 96, 97, 98,
+ 92, 93, 94, 95, 96, 97, 98, 99, 100, 101,
+ 102, 103,
}
var yyTok3 = [...]int{
0,
@@ -1076,245 +1111,245 @@ yydefault:
case 1:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:148
+ //line parser.y:154
{
yyVAL.program = nil
yylex.(*Lexer).program = yyVAL.program
}
case 2:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:153
+ //line parser.y:159
{
yyVAL.program = append([]Statement{yyDollar[1].statement}, yyDollar[2].program...)
yylex.(*Lexer).program = yyVAL.program
}
case 3:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:160
+ //line parser.y:166
{
yyVAL.program = nil
yylex.(*Lexer).program = yyVAL.program
}
case 4:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:165
+ //line parser.y:171
{
yyVAL.program = append([]Statement{yyDollar[1].statement}, yyDollar[2].program...)
yylex.(*Lexer).program = yyVAL.program
}
case 5:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:172
+ //line parser.y:178
{
yyVAL.statement = yyDollar[1].expression
}
case 6:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:176
+ //line parser.y:182
{
yyVAL.statement = yyDollar[1].expression
}
case 7:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:180
+ //line parser.y:186
{
yyVAL.statement = yyDollar[1].expression
}
case 8:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:184
+ //line parser.y:190
{
yyVAL.statement = yyDollar[1].expression
}
case 9:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:188
+ //line parser.y:194
{
yyVAL.statement = yyDollar[1].expression
}
case 10:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:192
+ //line parser.y:198
{
yyVAL.statement = yyDollar[1].expression
}
case 11:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:196
+ //line parser.y:202
{
yyVAL.statement = yyDollar[1].expression
}
case 12:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:200
+ //line parser.y:206
{
yyVAL.statement = yyDollar[1].expression
}
case 13:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:204
+ //line parser.y:210
{
yyVAL.statement = yyDollar[1].statement
}
case 14:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:208
+ //line parser.y:214
{
yyVAL.statement = yyDollar[1].statement
}
case 15:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:212
+ //line parser.y:218
{
yyVAL.statement = yyDollar[1].statement
}
case 16:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:216
+ //line parser.y:222
{
yyVAL.statement = yyDollar[1].statement
}
case 17:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:220
+ //line parser.y:226
{
yyVAL.statement = yyDollar[1].statement
}
case 18:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:226
+ //line parser.y:232
{
yyVAL.statement = yyDollar[1].statement
}
case 19:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:230
+ //line parser.y:236
{
yyVAL.statement = yyDollar[1].statement
}
case 20:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:236
+ //line parser.y:242
{
yyVAL.statement = VariableDeclaration{Assignments: yyDollar[2].expressions}
}
case 21:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:240
+ //line parser.y:246
{
yyVAL.statement = yyDollar[1].expression
}
case 22:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:246
+ //line parser.y:252
{
yyVAL.statement = TransactionControl{Token: yyDollar[1].token.Token}
}
case 23:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:250
+ //line parser.y:256
{
yyVAL.statement = TransactionControl{Token: yyDollar[1].token.Token}
}
case 24:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:256
+ //line parser.y:262
{
yyVAL.statement = CursorDeclaration{Cursor: yyDollar[2].identifier, Query: yyDollar[5].expression.(SelectQuery)}
}
case 25:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:260
+ //line parser.y:266
{
yyVAL.statement = OpenCursor{Cursor: yyDollar[2].identifier}
}
case 26:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:264
+ //line parser.y:270
{
yyVAL.statement = CloseCursor{Cursor: yyDollar[2].identifier}
}
case 27:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:268
+ //line parser.y:274
{
yyVAL.statement = DisposeCursor{Cursor: yyDollar[2].identifier}
}
case 28:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:272
+ //line parser.y:278
{
yyVAL.statement = FetchCursor{Cursor: yyDollar[2].identifier, Variables: yyDollar[4].variables}
}
case 29:
yyDollar = yyS[yypt-8 : yypt+1]
- //line parser.y:278
+ //line parser.y:284
{
yyVAL.statement = If{Condition: yyDollar[2].expression, Statements: yyDollar[4].program, Else: yyDollar[5].procexpr}
}
case 30:
yyDollar = yyS[yypt-9 : yypt+1]
- //line parser.y:282
+ //line parser.y:288
{
yyVAL.statement = If{Condition: yyDollar[2].expression, Statements: yyDollar[4].program, ElseIf: yyDollar[5].procexprs, Else: yyDollar[6].procexpr}
}
case 31:
yyDollar = yyS[yypt-7 : yypt+1]
- //line parser.y:286
+ //line parser.y:292
{
yyVAL.statement = While{Condition: yyDollar[2].expression, Statements: yyDollar[4].program}
}
case 32:
yyDollar = yyS[yypt-9 : yypt+1]
- //line parser.y:290
+ //line parser.y:296
{
yyVAL.statement = WhileInCursor{Variables: yyDollar[2].variables, Cursor: yyDollar[4].identifier, Statements: yyDollar[6].program}
}
case 33:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:294
+ //line parser.y:300
{
yyVAL.statement = FlowControl{Token: yyDollar[1].token.Token}
}
case 34:
yyDollar = yyS[yypt-8 : yypt+1]
- //line parser.y:300
+ //line parser.y:306
{
yyVAL.statement = If{Condition: yyDollar[2].expression, Statements: yyDollar[4].program, Else: yyDollar[5].procexpr}
}
case 35:
yyDollar = yyS[yypt-9 : yypt+1]
- //line parser.y:304
+ //line parser.y:310
{
yyVAL.statement = If{Condition: yyDollar[2].expression, Statements: yyDollar[4].program, ElseIf: yyDollar[5].procexprs, Else: yyDollar[6].procexpr}
}
case 36:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:308
+ //line parser.y:314
{
yyVAL.statement = FlowControl{Token: yyDollar[1].token.Token}
}
case 37:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:312
+ //line parser.y:318
{
yyVAL.statement = FlowControl{Token: yyDollar[1].token.Token}
}
case 38:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:318
+ //line parser.y:324
{
yyVAL.statement = SetFlag{Name: yyDollar[2].token.Literal, Value: yyDollar[4].primary}
}
case 39:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:322
+ //line parser.y:328
{
yyVAL.statement = Print{Value: yyDollar[2].expression}
}
case 40:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:328
+ //line parser.y:334
{
yyVAL.expression = SelectQuery{
SelectEntity: yyDollar[1].expression,
@@ -1325,7 +1360,7 @@ yydefault:
}
case 41:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:339
+ //line parser.y:345
{
yyVAL.expression = SelectEntity{
SelectClause: yyDollar[1].expression,
@@ -1337,7 +1372,7 @@ yydefault:
}
case 42:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:349
+ //line parser.y:355
{
yyVAL.expression = SelectSet{
LHS: yyDollar[1].expression,
@@ -1348,7 +1383,7 @@ yydefault:
}
case 43:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:358
+ //line parser.y:364
{
yyVAL.expression = SelectSet{
LHS: yyDollar[1].expression,
@@ -1359,7 +1394,7 @@ yydefault:
}
case 44:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:367
+ //line parser.y:373
{
yyVAL.expression = SelectSet{
LHS: yyDollar[1].expression,
@@ -1370,283 +1405,343 @@ yydefault:
}
case 45:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:378
+ //line parser.y:384
{
yyVAL.expression = yyDollar[1].expression
}
case 46:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:382
+ //line parser.y:388
{
yyVAL.expression = yyDollar[1].expression
}
case 47:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:388
+ //line parser.y:394
{
yyVAL.expression = SelectClause{Select: yyDollar[1].token.Literal, Distinct: yyDollar[2].token, Fields: yyDollar[3].expressions}
}
case 48:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:394
+ //line parser.y:400
{
yyVAL.expression = nil
}
case 49:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:398
+ //line parser.y:404
{
yyVAL.expression = FromClause{From: yyDollar[1].token.Literal, Tables: yyDollar[2].expressions}
}
case 50:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:404
+ //line parser.y:410
{
yyVAL.expression = nil
}
case 51:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:408
+ //line parser.y:414
{
yyVAL.expression = WhereClause{Where: yyDollar[1].token.Literal, Filter: yyDollar[2].expression}
}
case 52:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:414
+ //line parser.y:420
{
yyVAL.expression = nil
}
case 53:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:418
+ //line parser.y:424
{
yyVAL.expression = GroupByClause{GroupBy: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Items: yyDollar[3].expressions}
}
case 54:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:424
+ //line parser.y:430
{
yyVAL.expression = nil
}
case 55:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:428
+ //line parser.y:434
{
yyVAL.expression = HavingClause{Having: yyDollar[1].token.Literal, Filter: yyDollar[2].expression}
}
case 56:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:434
+ //line parser.y:440
{
yyVAL.expression = nil
}
case 57:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:438
+ //line parser.y:444
{
yyVAL.expression = OrderByClause{OrderBy: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Items: yyDollar[3].expressions}
}
case 58:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:444
+ //line parser.y:450
{
yyVAL.expression = nil
}
case 59:
- yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:448
+ yyDollar = yyS[yypt-3 : yypt+1]
+ //line parser.y:454
{
- yyVAL.expression = LimitClause{Limit: yyDollar[1].token.Literal, Number: StrToInt64(yyDollar[2].token.Literal)}
+ yyVAL.expression = LimitClause{Limit: yyDollar[1].token.Literal, Value: yyDollar[2].expression, With: yyDollar[3].expression}
}
case 60:
- yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:454
+ yyDollar = yyS[yypt-4 : yypt+1]
+ //line parser.y:458
{
- yyVAL.expression = nil
+ yyVAL.expression = LimitClause{Limit: yyDollar[1].token.Literal, Value: yyDollar[2].expression, Percent: yyDollar[3].token.Literal, With: yyDollar[4].expression}
}
case 61:
- yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:458
+ yyDollar = yyS[yypt-0 : yypt+1]
+ //line parser.y:464
{
- yyVAL.expression = OffsetClause{Offset: yyDollar[1].token.Literal, Number: StrToInt64(yyDollar[2].token.Literal)}
+ yyVAL.expression = nil
}
case 62:
- yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:464
+ yyDollar = yyS[yypt-2 : yypt+1]
+ //line parser.y:468
{
- yyVAL.primary = yyDollar[1].text
+ yyVAL.expression = LimitWith{With: yyDollar[1].token.Literal, Type: yyDollar[2].token}
}
case 63:
- yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:468
+ yyDollar = yyS[yypt-0 : yypt+1]
+ //line parser.y:474
{
- yyVAL.primary = yyDollar[1].integer
+ yyVAL.expression = nil
}
case 64:
- yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:472
+ yyDollar = yyS[yypt-2 : yypt+1]
+ //line parser.y:478
{
- yyVAL.primary = yyDollar[1].float
+ yyVAL.expression = OffsetClause{Offset: yyDollar[1].token.Literal, Value: yyDollar[2].expression}
}
case 65:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:476
+ //line parser.y:484
{
- yyVAL.primary = yyDollar[1].ternary
+ yyVAL.primary = yyDollar[1].text
}
case 66:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:480
+ //line parser.y:488
{
- yyVAL.primary = yyDollar[1].datetime
+ yyVAL.primary = yyDollar[1].integer
}
case 67:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:484
+ //line parser.y:492
{
- yyVAL.primary = yyDollar[1].null
+ yyVAL.primary = yyDollar[1].float
}
case 68:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:490
+ //line parser.y:496
{
- yyVAL.expression = FieldReference{Column: yyDollar[1].identifier}
+ yyVAL.primary = yyDollar[1].ternary
}
case 69:
- yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:494
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:500
{
- yyVAL.expression = FieldReference{View: yyDollar[1].identifier, Column: yyDollar[3].identifier}
+ yyVAL.primary = yyDollar[1].datetime
}
case 70:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:500
+ //line parser.y:504
{
- yyVAL.expression = yyDollar[1].expression
+ yyVAL.primary = yyDollar[1].null
}
case 71:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:504
+ //line parser.y:510
{
- yyVAL.expression = yyDollar[1].primary
+ yyVAL.expression = FieldReference{Column: yyDollar[1].identifier}
}
case 72:
- yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:508
+ yyDollar = yyS[yypt-3 : yypt+1]
+ //line parser.y:514
{
- yyVAL.expression = yyDollar[1].expression
+ yyVAL.expression = FieldReference{View: yyDollar[1].identifier, Column: yyDollar[3].identifier}
}
case 73:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:512
+ //line parser.y:520
{
yyVAL.expression = yyDollar[1].expression
}
case 74:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:516
+ //line parser.y:524
{
- yyVAL.expression = yyDollar[1].expression
+ yyVAL.expression = yyDollar[1].primary
}
case 75:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:520
+ //line parser.y:528
{
yyVAL.expression = yyDollar[1].expression
}
case 76:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:524
+ //line parser.y:532
{
yyVAL.expression = yyDollar[1].expression
}
case 77:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:528
+ //line parser.y:536
{
yyVAL.expression = yyDollar[1].expression
}
case 78:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:532
+ //line parser.y:540
{
yyVAL.expression = yyDollar[1].expression
}
case 79:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:536
+ //line parser.y:544
{
- yyVAL.expression = yyDollar[1].variable
+ yyVAL.expression = yyDollar[1].expression
}
case 80:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:540
+ //line parser.y:548
{
yyVAL.expression = yyDollar[1].expression
}
case 81:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:552
+ {
+ yyVAL.expression = yyDollar[1].expression
+ }
+ case 82:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:556
+ {
+ yyVAL.expression = yyDollar[1].variable
+ }
+ case 83:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:560
+ {
+ yyVAL.expression = yyDollar[1].expression
+ }
+ case 84:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:544
+ //line parser.y:564
{
yyVAL.expression = Parentheses{Expr: yyDollar[2].expression}
}
- case 82:
+ case 85:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:550
+ //line parser.y:570
{
yyVAL.expression = RowValue{Value: ValueList{Values: yyDollar[2].expressions}}
}
- case 83:
+ case 86:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:554
+ //line parser.y:574
{
yyVAL.expression = RowValue{Value: yyDollar[1].expression}
}
- case 84:
+ case 87:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:560
+ //line parser.y:580
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 85:
+ case 88:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:564
+ //line parser.y:584
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 86:
+ case 89:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:590
+ {
+ yyVAL.expressions = []Expression{yyDollar[1].expression}
+ }
+ case 90:
+ yyDollar = yyS[yypt-3 : yypt+1]
+ //line parser.y:594
+ {
+ yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
+ }
+ case 91:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:570
+ //line parser.y:600
{
- yyVAL.expression = OrderItem{Item: yyDollar[1].expression, Direction: yyDollar[2].token}
+ yyVAL.expression = OrderItem{Value: yyDollar[1].expression, Direction: yyDollar[2].token}
}
- case 87:
+ case 92:
+ yyDollar = yyS[yypt-4 : yypt+1]
+ //line parser.y:604
+ {
+ yyVAL.expression = OrderItem{Value: yyDollar[1].expression, Direction: yyDollar[2].token, Nulls: yyDollar[3].token.Literal, Position: yyDollar[4].token}
+ }
+ case 93:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:610
+ {
+ yyVAL.expression = yyDollar[1].expression
+ }
+ case 94:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:614
+ {
+ yyVAL.expression = yyDollar[1].expression
+ }
+ case 95:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:576
+ //line parser.y:620
{
yyVAL.token = Token{}
}
- case 88:
+ case 96:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:580
+ //line parser.y:624
{
yyVAL.token = yyDollar[1].token
}
- case 89:
+ case 97:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:584
+ //line parser.y:628
{
yyVAL.token = yyDollar[1].token
}
- case 90:
+ case 98:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:634
+ {
+ yyVAL.token = yyDollar[1].token
+ }
+ case 99:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:638
+ {
+ yyVAL.token = yyDollar[1].token
+ }
+ case 100:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:590
+ //line parser.y:644
{
yyVAL.expression = Subquery{Query: yyDollar[2].expression.(SelectQuery)}
}
- case 91:
+ case 101:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:596
+ //line parser.y:650
{
var item1 []Expression
var item2 []Expression
@@ -1667,883 +1762,901 @@ yydefault:
yyVAL.expression = Concat{Items: append(item1, item2...)}
}
- case 92:
+ case 102:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:619
+ //line parser.y:673
{
yyVAL.expression = Comparison{LHS: yyDollar[1].expression, Operator: yyDollar[2].token, RHS: yyDollar[3].expression}
}
- case 93:
+ case 103:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:623
+ //line parser.y:677
{
yyVAL.expression = Comparison{LHS: yyDollar[1].expression, Operator: yyDollar[2].token, RHS: yyDollar[3].expression}
}
- case 94:
+ case 104:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:627
+ //line parser.y:681
{
yyVAL.expression = Comparison{LHS: yyDollar[1].expression, Operator: Token{Token: COMPARISON_OP, Literal: "="}, RHS: yyDollar[3].expression}
}
- case 95:
+ case 105:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:631
+ //line parser.y:685
{
yyVAL.expression = Comparison{LHS: yyDollar[1].expression, Operator: Token{Token: COMPARISON_OP, Literal: "="}, RHS: yyDollar[3].expression}
}
- case 96:
+ case 106:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:635
+ //line parser.y:689
{
yyVAL.expression = Is{Is: yyDollar[2].token.Literal, LHS: yyDollar[1].expression, RHS: yyDollar[4].ternary, Negation: yyDollar[3].token}
}
- case 97:
+ case 107:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:639
+ //line parser.y:693
{
yyVAL.expression = Is{Is: yyDollar[2].token.Literal, LHS: yyDollar[1].expression, RHS: yyDollar[4].null, Negation: yyDollar[3].token}
}
- case 98:
+ case 108:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:643
+ //line parser.y:697
{
yyVAL.expression = Between{Between: yyDollar[3].token.Literal, And: yyDollar[5].token.Literal, LHS: yyDollar[1].expression, Low: yyDollar[4].expression, High: yyDollar[6].expression, Negation: yyDollar[2].token}
}
- case 99:
+ case 109:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:647
+ //line parser.y:701
{
yyVAL.expression = Between{Between: yyDollar[3].token.Literal, And: yyDollar[5].token.Literal, LHS: yyDollar[1].expression, Low: yyDollar[4].expression, High: yyDollar[6].expression, Negation: yyDollar[2].token}
}
- case 100:
+ case 110:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:651
+ //line parser.y:705
{
yyVAL.expression = In{In: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Values: yyDollar[4].expression, Negation: yyDollar[2].token}
}
- case 101:
+ case 111:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:655
+ //line parser.y:709
{
yyVAL.expression = In{In: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Values: RowValueList{RowValues: yyDollar[5].expressions}, Negation: yyDollar[2].token}
}
- case 102:
+ case 112:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:659
+ //line parser.y:713
{
yyVAL.expression = In{In: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Values: yyDollar[4].expression, Negation: yyDollar[2].token}
}
- case 103:
+ case 113:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:663
+ //line parser.y:717
{
yyVAL.expression = Like{Like: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Pattern: yyDollar[4].expression, Negation: yyDollar[2].token}
}
- case 104:
+ case 114:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:667
+ //line parser.y:721
{
yyVAL.expression = Any{Any: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Operator: yyDollar[2].token, Values: yyDollar[4].expression}
}
- case 105:
+ case 115:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:671
+ //line parser.y:725
{
yyVAL.expression = Any{Any: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Operator: yyDollar[2].token, Values: RowValueList{RowValues: yyDollar[5].expressions}}
}
- case 106:
+ case 116:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:675
+ //line parser.y:729
{
yyVAL.expression = Any{Any: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Operator: yyDollar[2].token, Values: yyDollar[4].expression}
}
- case 107:
+ case 117:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:679
+ //line parser.y:733
{
yyVAL.expression = All{All: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Operator: yyDollar[2].token, Values: yyDollar[4].expression}
}
- case 108:
+ case 118:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:683
+ //line parser.y:737
{
yyVAL.expression = All{All: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Operator: yyDollar[2].token, Values: RowValueList{RowValues: yyDollar[5].expressions}}
}
- case 109:
+ case 119:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:687
+ //line parser.y:741
{
yyVAL.expression = All{All: yyDollar[3].token.Literal, LHS: yyDollar[1].expression, Operator: yyDollar[2].token, Values: yyDollar[4].expression}
}
- case 110:
+ case 120:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:691
+ //line parser.y:745
{
yyVAL.expression = Exists{Exists: yyDollar[1].token.Literal, Query: yyDollar[2].expression.(Subquery)}
}
- case 111:
+ case 121:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:697
+ //line parser.y:751
{
yyVAL.expression = Arithmetic{LHS: yyDollar[1].expression, Operator: int('+'), RHS: yyDollar[3].expression}
}
- case 112:
+ case 122:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:701
+ //line parser.y:755
{
yyVAL.expression = Arithmetic{LHS: yyDollar[1].expression, Operator: int('-'), RHS: yyDollar[3].expression}
}
- case 113:
+ case 123:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:705
+ //line parser.y:759
{
yyVAL.expression = Arithmetic{LHS: yyDollar[1].expression, Operator: int('*'), RHS: yyDollar[3].expression}
}
- case 114:
+ case 124:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:709
+ //line parser.y:763
{
yyVAL.expression = Arithmetic{LHS: yyDollar[1].expression, Operator: int('/'), RHS: yyDollar[3].expression}
}
- case 115:
+ case 125:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:713
+ //line parser.y:767
{
yyVAL.expression = Arithmetic{LHS: yyDollar[1].expression, Operator: int('%'), RHS: yyDollar[3].expression}
}
- case 116:
+ case 126:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:719
+ //line parser.y:773
{
yyVAL.expression = Logic{LHS: yyDollar[1].expression, Operator: yyDollar[2].token, RHS: yyDollar[3].expression}
}
- case 117:
+ case 127:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:723
+ //line parser.y:777
{
yyVAL.expression = Logic{LHS: yyDollar[1].expression, Operator: yyDollar[2].token, RHS: yyDollar[3].expression}
}
- case 118:
+ case 128:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:727
+ //line parser.y:781
{
yyVAL.expression = Logic{LHS: nil, Operator: yyDollar[1].token, RHS: yyDollar[2].expression}
}
- case 119:
+ case 129:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:733
+ //line parser.y:787
{
yyVAL.expression = Function{Name: yyDollar[1].identifier.Literal, Option: yyDollar[3].expression.(Option)}
}
- case 120:
+ case 130:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:737
+ //line parser.y:791
{
yyVAL.expression = yyDollar[1].expression
}
- case 121:
+ case 131:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:743
+ //line parser.y:797
{
yyVAL.expression = Option{}
}
- case 122:
+ case 132:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:747
+ //line parser.y:801
{
yyVAL.expression = Option{Distinct: yyDollar[1].token, Args: []Expression{AllColumns{}}}
}
- case 123:
+ case 133:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:751
+ //line parser.y:805
{
yyVAL.expression = Option{Distinct: yyDollar[1].token, Args: yyDollar[2].expressions}
}
- case 124:
+ case 134:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:757
+ //line parser.y:811
{
yyVAL.expression = GroupConcat{GroupConcat: yyDollar[1].token.Literal, Option: yyDollar[3].expression.(Option), OrderBy: yyDollar[4].expression}
}
- case 125:
+ case 135:
yyDollar = yyS[yypt-7 : yypt+1]
- //line parser.y:761
+ //line parser.y:815
{
yyVAL.expression = GroupConcat{GroupConcat: yyDollar[1].token.Literal, Option: yyDollar[3].expression.(Option), OrderBy: yyDollar[4].expression, SeparatorLit: yyDollar[5].token.Literal, Separator: yyDollar[6].token.Literal}
}
- case 126:
+ case 136:
+ yyDollar = yyS[yypt-8 : yypt+1]
+ //line parser.y:821
+ {
+ yyVAL.expression = AnalyticFunction{Name: yyDollar[1].identifier.Literal, Option: yyDollar[3].expression.(Option), Over: yyDollar[5].token.Literal, AnalyticClause: yyDollar[7].expression.(AnalyticClause)}
+ }
+ case 137:
+ yyDollar = yyS[yypt-2 : yypt+1]
+ //line parser.y:827
+ {
+ yyVAL.expression = AnalyticClause{Partition: yyDollar[1].expression, OrderByClause: yyDollar[2].expression}
+ }
+ case 138:
+ yyDollar = yyS[yypt-0 : yypt+1]
+ //line parser.y:833
+ {
+ yyVAL.expression = nil
+ }
+ case 139:
+ yyDollar = yyS[yypt-3 : yypt+1]
+ //line parser.y:837
+ {
+ yyVAL.expression = Partition{PartitionBy: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Values: yyDollar[3].expressions}
+ }
+ case 140:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:767
+ //line parser.y:843
{
yyVAL.expression = Table{Object: yyDollar[1].identifier}
}
- case 127:
+ case 141:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:771
+ //line parser.y:847
{
yyVAL.expression = Table{Object: yyDollar[1].identifier, Alias: yyDollar[2].identifier}
}
- case 128:
+ case 142:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:775
+ //line parser.y:851
{
yyVAL.expression = Table{Object: yyDollar[1].identifier, As: yyDollar[2].token, Alias: yyDollar[3].identifier}
}
- case 129:
+ case 143:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:781
+ //line parser.y:857
{
yyVAL.expression = yyDollar[1].expression
}
- case 130:
+ case 144:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:785
+ //line parser.y:861
{
yyVAL.expression = Stdin{Stdin: yyDollar[1].token.Literal}
}
- case 131:
+ case 145:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:791
+ //line parser.y:867
{
yyVAL.expression = yyDollar[1].expression
}
- case 132:
+ case 146:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:795
+ //line parser.y:871
{
yyVAL.expression = Table{Object: yyDollar[1].expression}
}
- case 133:
+ case 147:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:799
+ //line parser.y:875
{
yyVAL.expression = Table{Object: yyDollar[1].expression, Alias: yyDollar[2].identifier}
}
- case 134:
+ case 148:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:803
+ //line parser.y:879
{
yyVAL.expression = Table{Object: yyDollar[1].expression, As: yyDollar[2].token, Alias: yyDollar[3].identifier}
}
- case 135:
+ case 149:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:807
+ //line parser.y:883
{
yyVAL.expression = Table{Object: yyDollar[1].expression}
}
- case 136:
+ case 150:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:811
+ //line parser.y:887
{
yyVAL.expression = Table{Object: Dual{Dual: yyDollar[1].token.Literal}}
}
- case 137:
+ case 151:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:817
+ //line parser.y:893
{
yyVAL.expression = Join{Join: yyDollar[3].token.Literal, Table: yyDollar[1].expression.(Table), JoinTable: yyDollar[4].expression.(Table), Natural: Token{}, JoinType: yyDollar[2].token, Condition: yyDollar[5].expression}
}
- case 138:
+ case 152:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:821
+ //line parser.y:897
{
yyVAL.expression = Join{Join: yyDollar[4].token.Literal, Table: yyDollar[1].expression.(Table), JoinTable: yyDollar[5].expression.(Table), Natural: yyDollar[2].token, JoinType: yyDollar[3].token, Condition: nil}
}
- case 139:
+ case 153:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:825
+ //line parser.y:901
{
yyVAL.expression = Join{Join: yyDollar[4].token.Literal, Table: yyDollar[1].expression.(Table), JoinTable: yyDollar[5].expression.(Table), Natural: Token{}, JoinType: yyDollar[3].token, Direction: yyDollar[2].token, Condition: yyDollar[6].expression}
}
- case 140:
+ case 154:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:829
+ //line parser.y:905
{
yyVAL.expression = Join{Join: yyDollar[5].token.Literal, Table: yyDollar[1].expression.(Table), JoinTable: yyDollar[6].expression.(Table), Natural: yyDollar[2].token, JoinType: yyDollar[4].token, Direction: yyDollar[3].token, Condition: nil}
}
- case 141:
+ case 155:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:833
+ //line parser.y:909
{
yyVAL.expression = Join{Join: yyDollar[3].token.Literal, Table: yyDollar[1].expression.(Table), JoinTable: yyDollar[4].expression.(Table), Natural: Token{}, JoinType: yyDollar[2].token, Condition: nil}
}
- case 142:
+ case 156:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:839
+ //line parser.y:915
{
yyVAL.expression = nil
}
- case 143:
+ case 157:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:843
+ //line parser.y:919
{
yyVAL.expression = JoinCondition{Literal: yyDollar[1].token.Literal, On: yyDollar[2].expression}
}
- case 144:
+ case 158:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:847
+ //line parser.y:923
{
yyVAL.expression = JoinCondition{Literal: yyDollar[1].token.Literal, Using: yyDollar[3].expressions}
}
- case 145:
+ case 159:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:853
+ //line parser.y:929
{
yyVAL.expression = yyDollar[1].expression
}
- case 146:
+ case 160:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:857
+ //line parser.y:933
+ {
+ yyVAL.expression = yyDollar[1].expression
+ }
+ case 161:
+ yyDollar = yyS[yypt-1 : yypt+1]
+ //line parser.y:937
{
yyVAL.expression = AllColumns{}
}
- case 147:
+ case 162:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:863
+ //line parser.y:943
{
yyVAL.expression = Field{Object: yyDollar[1].expression}
}
- case 148:
+ case 163:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:867
+ //line parser.y:947
{
yyVAL.expression = Field{Object: yyDollar[1].expression, As: yyDollar[2].token, Alias: yyDollar[3].identifier}
}
- case 149:
+ case 164:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:873
+ //line parser.y:953
{
yyVAL.expression = Case{Case: yyDollar[1].token.Literal, End: yyDollar[5].token.Literal, Value: yyDollar[2].expression, When: yyDollar[3].expressions, Else: yyDollar[4].expression}
}
- case 150:
+ case 165:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:879
+ //line parser.y:959
{
yyVAL.expression = nil
}
- case 151:
+ case 166:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:883
+ //line parser.y:963
{
yyVAL.expression = yyDollar[1].expression
}
- case 152:
+ case 167:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:889
+ //line parser.y:969
{
yyVAL.expression = nil
}
- case 153:
+ case 168:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:893
+ //line parser.y:973
{
yyVAL.expression = CaseElse{Else: yyDollar[1].token.Literal, Result: yyDollar[2].expression}
}
- case 154:
- yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:899
- {
- yyVAL.expressions = []Expression{yyDollar[1].expression}
- }
- case 155:
- yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:903
- {
- yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
- }
- case 156:
+ case 169:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:909
+ //line parser.y:979
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 157:
+ case 170:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:913
+ //line parser.y:983
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 158:
+ case 171:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:919
+ //line parser.y:989
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 159:
+ case 172:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:923
+ //line parser.y:993
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 160:
+ case 173:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:929
+ //line parser.y:999
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 161:
+ case 174:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:933
+ //line parser.y:1003
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 162:
+ case 175:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:939
+ //line parser.y:1009
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 163:
+ case 176:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:943
+ //line parser.y:1013
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 164:
+ case 177:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:949
+ //line parser.y:1019
{
yyVAL.expressions = []Expression{yyDollar[1].identifier}
}
- case 165:
+ case 178:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:953
+ //line parser.y:1023
{
yyVAL.expressions = append([]Expression{yyDollar[1].identifier}, yyDollar[3].expressions...)
}
- case 166:
+ case 179:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:959
+ //line parser.y:1029
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 167:
+ case 180:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:963
+ //line parser.y:1033
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 168:
+ case 181:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:969
+ //line parser.y:1039
{
yyVAL.expressions = []Expression{CaseWhen{When: yyDollar[1].token.Literal, Then: yyDollar[3].token.Literal, Condition: yyDollar[2].expression, Result: yyDollar[4].expression}}
}
- case 169:
+ case 182:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:973
+ //line parser.y:1043
{
yyVAL.expressions = append(yyDollar[1].expressions, yyDollar[2].expressions...)
}
- case 170:
+ case 183:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:979
+ //line parser.y:1049
{
yyVAL.expression = InsertQuery{Insert: yyDollar[1].token.Literal, Into: yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Values: yyDollar[4].token.Literal, ValuesList: yyDollar[5].expressions}
}
- case 171:
+ case 184:
yyDollar = yyS[yypt-8 : yypt+1]
- //line parser.y:983
+ //line parser.y:1053
{
yyVAL.expression = InsertQuery{Insert: yyDollar[1].token.Literal, Into: yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Fields: yyDollar[5].expressions, Values: yyDollar[7].token.Literal, ValuesList: yyDollar[8].expressions}
}
- case 172:
+ case 185:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:987
+ //line parser.y:1057
{
yyVAL.expression = InsertQuery{Insert: yyDollar[1].token.Literal, Into: yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Query: yyDollar[4].expression.(SelectQuery)}
}
- case 173:
+ case 186:
yyDollar = yyS[yypt-7 : yypt+1]
- //line parser.y:991
+ //line parser.y:1061
{
yyVAL.expression = InsertQuery{Insert: yyDollar[1].token.Literal, Into: yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Fields: yyDollar[5].expressions, Query: yyDollar[7].expression.(SelectQuery)}
}
- case 174:
+ case 187:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:997
+ //line parser.y:1067
{
yyVAL.expression = UpdateQuery{Update: yyDollar[1].token.Literal, Tables: yyDollar[2].expressions, Set: yyDollar[3].token.Literal, SetList: yyDollar[4].expressions, FromClause: yyDollar[5].expression, WhereClause: yyDollar[6].expression}
}
- case 175:
+ case 188:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1003
+ //line parser.y:1073
{
yyVAL.expression = UpdateSet{Field: yyDollar[1].expression.(FieldReference), Value: yyDollar[3].expression}
}
- case 176:
+ case 189:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1009
+ //line parser.y:1079
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 177:
+ case 190:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1013
+ //line parser.y:1083
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 178:
+ case 191:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:1019
+ //line parser.y:1089
{
from := FromClause{From: yyDollar[2].token.Literal, Tables: yyDollar[3].expressions}
yyVAL.expression = DeleteQuery{Delete: yyDollar[1].token.Literal, FromClause: from, WhereClause: yyDollar[4].expression}
}
- case 179:
+ case 192:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:1024
+ //line parser.y:1094
{
from := FromClause{From: yyDollar[3].token.Literal, Tables: yyDollar[4].expressions}
yyVAL.expression = DeleteQuery{Delete: yyDollar[1].token.Literal, Tables: yyDollar[2].expressions, FromClause: from, WhereClause: yyDollar[5].expression}
}
- case 180:
+ case 193:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:1031
+ //line parser.y:1101
{
yyVAL.expression = CreateTable{CreateTable: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Fields: yyDollar[5].expressions}
}
- case 181:
+ case 194:
yyDollar = yyS[yypt-6 : yypt+1]
- //line parser.y:1037
+ //line parser.y:1107
{
yyVAL.expression = AddColumns{AlterTable: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Add: yyDollar[4].token.Literal, Columns: []Expression{yyDollar[5].expression}, Position: yyDollar[6].expression}
}
- case 182:
+ case 195:
yyDollar = yyS[yypt-8 : yypt+1]
- //line parser.y:1041
+ //line parser.y:1111
{
yyVAL.expression = AddColumns{AlterTable: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Add: yyDollar[4].token.Literal, Columns: yyDollar[6].expressions, Position: yyDollar[8].expression}
}
- case 183:
+ case 196:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1047
+ //line parser.y:1117
{
yyVAL.expression = ColumnDefault{Column: yyDollar[1].identifier}
}
- case 184:
+ case 197:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1051
+ //line parser.y:1121
{
yyVAL.expression = ColumnDefault{Column: yyDollar[1].identifier, Default: yyDollar[2].token.Literal, Value: yyDollar[3].expression}
}
- case 185:
+ case 198:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1057
+ //line parser.y:1127
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 186:
+ case 199:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1061
+ //line parser.y:1131
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 187:
+ case 200:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1067
+ //line parser.y:1137
{
yyVAL.expression = nil
}
- case 188:
+ case 201:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1071
+ //line parser.y:1141
{
yyVAL.expression = ColumnPosition{Position: yyDollar[1].token}
}
- case 189:
+ case 202:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1075
+ //line parser.y:1145
{
yyVAL.expression = ColumnPosition{Position: yyDollar[1].token}
}
- case 190:
+ case 203:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1079
+ //line parser.y:1149
{
yyVAL.expression = ColumnPosition{Position: yyDollar[1].token, Column: yyDollar[2].expression}
}
- case 191:
+ case 204:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1083
+ //line parser.y:1153
{
yyVAL.expression = ColumnPosition{Position: yyDollar[1].token, Column: yyDollar[2].expression}
}
- case 192:
+ case 205:
yyDollar = yyS[yypt-5 : yypt+1]
- //line parser.y:1089
+ //line parser.y:1159
{
yyVAL.expression = DropColumns{AlterTable: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Drop: yyDollar[4].token.Literal, Columns: []Expression{yyDollar[5].expression}}
}
- case 193:
+ case 206:
yyDollar = yyS[yypt-7 : yypt+1]
- //line parser.y:1093
+ //line parser.y:1163
{
yyVAL.expression = DropColumns{AlterTable: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Drop: yyDollar[4].token.Literal, Columns: yyDollar[6].expressions}
}
- case 194:
+ case 207:
yyDollar = yyS[yypt-7 : yypt+1]
- //line parser.y:1099
+ //line parser.y:1169
{
yyVAL.expression = RenameColumn{AlterTable: yyDollar[1].token.Literal + " " + yyDollar[2].token.Literal, Table: yyDollar[3].identifier, Rename: yyDollar[4].token.Literal, Old: yyDollar[5].expression.(FieldReference), To: yyDollar[6].token.Literal, New: yyDollar[7].identifier}
}
- case 195:
+ case 208:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:1105
+ //line parser.y:1175
{
yyVAL.procexprs = []ProcExpr{ElseIf{Condition: yyDollar[2].expression, Statements: yyDollar[4].program}}
}
- case 196:
+ case 209:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1109
+ //line parser.y:1179
{
yyVAL.procexprs = append(yyDollar[1].procexprs, yyDollar[2].procexprs...)
}
- case 197:
+ case 210:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1115
+ //line parser.y:1185
{
yyVAL.procexpr = nil
}
- case 198:
+ case 211:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1119
+ //line parser.y:1189
{
yyVAL.procexpr = Else{Statements: yyDollar[2].program}
}
- case 199:
+ case 212:
yyDollar = yyS[yypt-4 : yypt+1]
- //line parser.y:1125
+ //line parser.y:1195
{
yyVAL.procexprs = []ProcExpr{ElseIf{Condition: yyDollar[2].expression, Statements: yyDollar[4].program}}
}
- case 200:
+ case 213:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1129
+ //line parser.y:1199
{
yyVAL.procexprs = append(yyDollar[1].procexprs, yyDollar[2].procexprs...)
}
- case 201:
+ case 214:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1135
+ //line parser.y:1205
{
yyVAL.procexpr = nil
}
- case 202:
+ case 215:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1139
+ //line parser.y:1209
{
yyVAL.procexpr = Else{Statements: yyDollar[2].program}
}
- case 203:
+ case 216:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1145
+ //line parser.y:1215
{
yyVAL.identifier = Identifier{Literal: yyDollar[1].token.Literal, Quoted: yyDollar[1].token.Quoted}
}
- case 204:
+ case 217:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1151
+ //line parser.y:1221
{
yyVAL.text = NewString(yyDollar[1].token.Literal)
}
- case 205:
+ case 218:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1157
+ //line parser.y:1227
{
yyVAL.integer = NewIntegerFromString(yyDollar[1].token.Literal)
}
- case 206:
+ case 219:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1161
+ //line parser.y:1231
{
i := yyDollar[2].integer.Value() * -1
yyVAL.integer = NewInteger(i)
}
- case 207:
+ case 220:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1168
+ //line parser.y:1238
{
yyVAL.float = NewFloatFromString(yyDollar[1].token.Literal)
}
- case 208:
+ case 221:
yyDollar = yyS[yypt-2 : yypt+1]
- //line parser.y:1172
+ //line parser.y:1242
{
f := yyDollar[2].float.Value() * -1
yyVAL.float = NewFloat(f)
}
- case 209:
+ case 222:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1179
+ //line parser.y:1249
{
yyVAL.ternary = NewTernaryFromString(yyDollar[1].token.Literal)
}
- case 210:
+ case 223:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1185
+ //line parser.y:1255
{
yyVAL.datetime = NewDatetimeFromString(yyDollar[1].token.Literal)
}
- case 211:
+ case 224:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1191
+ //line parser.y:1261
{
yyVAL.null = NewNullFromString(yyDollar[1].token.Literal)
}
- case 212:
+ case 225:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1197
+ //line parser.y:1267
{
yyVAL.variable = Variable{Name: yyDollar[1].token.Literal}
}
- case 213:
+ case 226:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1203
+ //line parser.y:1273
{
yyVAL.variables = []Variable{yyDollar[1].variable}
}
- case 214:
+ case 227:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1207
+ //line parser.y:1277
{
yyVAL.variables = append([]Variable{yyDollar[1].variable}, yyDollar[3].variables...)
}
- case 215:
+ case 228:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1213
+ //line parser.y:1283
{
yyVAL.expression = VariableSubstitution{Variable: yyDollar[1].variable, Value: yyDollar[3].expression}
}
- case 216:
+ case 229:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1219
+ //line parser.y:1289
{
yyVAL.expression = VariableAssignment{Name: yyDollar[1].token.Literal}
}
- case 217:
+ case 230:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1223
+ //line parser.y:1293
{
yyVAL.expression = VariableAssignment{Name: yyDollar[1].token.Literal, Value: yyDollar[3].expression}
}
- case 218:
+ case 231:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1229
+ //line parser.y:1299
{
yyVAL.expressions = []Expression{yyDollar[1].expression}
}
- case 219:
+ case 232:
yyDollar = yyS[yypt-3 : yypt+1]
- //line parser.y:1233
+ //line parser.y:1303
{
yyVAL.expressions = append([]Expression{yyDollar[1].expression}, yyDollar[3].expressions...)
}
- case 220:
+ case 233:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1239
+ //line parser.y:1309
{
yyVAL.token = Token{}
}
- case 221:
+ case 234:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1243
+ //line parser.y:1313
{
yyVAL.token = yyDollar[1].token
}
- case 222:
+ case 235:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1249
+ //line parser.y:1319
{
yyVAL.token = Token{}
}
- case 223:
+ case 236:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1253
+ //line parser.y:1323
{
yyVAL.token = yyDollar[1].token
}
- case 224:
+ case 237:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1259
+ //line parser.y:1329
{
yyVAL.token = Token{}
}
- case 225:
+ case 238:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1263
+ //line parser.y:1333
{
yyVAL.token = yyDollar[1].token
}
- case 226:
+ case 239:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1269
+ //line parser.y:1339
{
yyVAL.token = Token{}
}
- case 227:
+ case 240:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1273
+ //line parser.y:1343
{
yyVAL.token = yyDollar[1].token
}
- case 228:
+ case 241:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1279
+ //line parser.y:1349
{
yyVAL.token = Token{}
}
- case 229:
+ case 242:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1283
+ //line parser.y:1353
{
yyVAL.token = yyDollar[1].token
}
- case 230:
+ case 243:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1287
+ //line parser.y:1357
{
yyVAL.token = yyDollar[1].token
}
- case 231:
+ case 244:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1291
+ //line parser.y:1361
{
yyVAL.token = yyDollar[1].token
}
- case 232:
+ case 245:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1297
+ //line parser.y:1367
{
yyVAL.token = Token{}
}
- case 233:
+ case 246:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1301
+ //line parser.y:1371
{
yyVAL.token = yyDollar[1].token
}
- case 234:
+ case 247:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1307
+ //line parser.y:1377
{
yyVAL.token = yyDollar[1].token
}
- case 235:
+ case 248:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1311
+ //line parser.y:1381
{
yyVAL.token = Token{Token: COMPARISON_OP, Literal: string('=')}
}
- case 236:
+ case 249:
yyDollar = yyS[yypt-0 : yypt+1]
- //line parser.y:1317
+ //line parser.y:1387
{
yyVAL.token = Token{}
}
- case 237:
+ case 250:
yyDollar = yyS[yypt-1 : yypt+1]
- //line parser.y:1321
+ //line parser.y:1391
{
yyVAL.token = Token{Token: ';', Literal: string(';')}
}
diff --git a/lib/parser/parser.output b/lib/parser/parser.output
index 478a714a..e07851fc 100644
--- a/lib/parser/parser.output
+++ b/lib/parser/parser.output
@@ -24,7 +24,7 @@ state 0
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
program goto 1
statement goto 2
@@ -80,7 +80,7 @@ state 2
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
program goto 43
statement goto 2
@@ -106,104 +106,104 @@ state 2
state 3
statement: select_query.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 44
state 4
statement: insert_query.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 46
state 5
statement: update_query.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 47
state 6
statement: delete_query.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 48
state 7
statement: create_table.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 49
state 8
statement: add_columns.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 50
state 9
statement: drop_columns.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 51
state 10
statement: rename_column.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 52
state 11
statement: variable_statement. (13)
- . reduce 13 (src line 203)
+ . reduce 13 (src line 209)
state 12
statement: transaction_statement. (14)
- . reduce 14 (src line 207)
+ . reduce 14 (src line 213)
state 13
statement: cursor_statement. (15)
- . reduce 15 (src line 211)
+ . reduce 15 (src line 217)
state 14
statement: flow_control_statement. (16)
- . reduce 16 (src line 215)
+ . reduce 16 (src line 221)
state 15
statement: command_statement. (17)
- . reduce 17 (src line 219)
+ . reduce 17 (src line 225)
state 16
@@ -212,10 +212,10 @@ state 16
order_by_clause: . (56)
ORDER shift 54
- UNION reduce 45 (src line 376)
- INTERSECT reduce 45 (src line 376)
- EXCEPT reduce 45 (src line 376)
- . reduce 56 (src line 432)
+ UNION reduce 45 (src line 382)
+ INTERSECT reduce 45 (src line 382)
+ EXCEPT reduce 45 (src line 382)
+ . reduce 56 (src line 438)
order_by_clause goto 53
@@ -280,28 +280,28 @@ state 22
state 23
variable_statement: variable_substitution.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 67
state 24
transaction_statement: COMMIT.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 68
state 25
transaction_statement: ROLLBACK.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 69
@@ -432,10 +432,10 @@ state 32
state 33
flow_control_statement: EXIT.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 111
@@ -492,7 +492,7 @@ state 36
from_clause: . (48)
FROM shift 115
- . reduce 48 (src line 392)
+ . reduce 48 (src line 398)
from_clause goto 114
@@ -516,23 +516,23 @@ state 38
state 39
select_clause: SELECT.distinct fields
- distinct: . (220)
+ distinct: . (233)
DISTINCT shift 121
- . reduce 220 (src line 1237)
+ . reduce 233 (src line 1307)
distinct goto 120
state 40
select_set_entity: subquery. (46)
- . reduce 46 (src line 381)
+ . reduce 46 (src line 387)
state 41
- variable: VARIABLE. (212)
+ variable: VARIABLE. (225)
- . reduce 212 (src line 1195)
+ . reduce 225 (src line 1265)
state 42
@@ -551,61 +551,61 @@ state 42
state 43
program: statement program. (2)
- . reduce 2 (src line 152)
+ . reduce 2 (src line 158)
state 44
statement: select_query statement_terminal. (5)
- . reduce 5 (src line 170)
+ . reduce 5 (src line 176)
state 45
- statement_terminal: ';'. (237)
+ statement_terminal: ';'. (250)
- . reduce 237 (src line 1320)
+ . reduce 250 (src line 1390)
state 46
statement: insert_query statement_terminal. (6)
- . reduce 6 (src line 175)
+ . reduce 6 (src line 181)
state 47
statement: update_query statement_terminal. (7)
- . reduce 7 (src line 179)
+ . reduce 7 (src line 185)
state 48
statement: delete_query statement_terminal. (8)
- . reduce 8 (src line 183)
+ . reduce 8 (src line 189)
state 49
statement: create_table statement_terminal. (9)
- . reduce 9 (src line 187)
+ . reduce 9 (src line 193)
state 50
statement: add_columns statement_terminal. (10)
- . reduce 10 (src line 191)
+ . reduce 10 (src line 197)
state 51
statement: drop_columns statement_terminal. (11)
- . reduce 11 (src line 195)
+ . reduce 11 (src line 201)
state 52
statement: rename_column statement_terminal. (12)
- . reduce 12 (src line 199)
+ . reduce 12 (src line 205)
state 53
@@ -613,7 +613,7 @@ state 53
limit_clause: . (58)
LIMIT shift 124
- . reduce 58 (src line 442)
+ . reduce 58 (src line 448)
limit_clause goto 123
@@ -643,28 +643,28 @@ state 56
state 57
- identified_tables: identified_table. (162)
+ identified_tables: identified_table. (175)
identified_tables: identified_table.',' identified_tables
',' shift 128
- . reduce 162 (src line 937)
+ . reduce 175 (src line 1007)
state 58
- identified_table: identifier. (126)
+ identified_table: identifier. (140)
identified_table: identifier.identifier
identified_table: identifier.AS identifier
IDENTIFIER shift 59
AS shift 130
- . reduce 126 (src line 765)
+ . reduce 140 (src line 841)
identifier goto 129
state 59
- identifier: IDENTIFIER. (203)
+ identifier: IDENTIFIER. (216)
- . reduce 203 (src line 1143)
+ . reduce 216 (src line 1213)
state 60
@@ -713,45 +713,45 @@ state 63
state 64
variable_statement: VAR variable_assignments.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 142
state 65
- variable_assignments: variable_assignment. (218)
+ variable_assignments: variable_assignment. (231)
variable_assignments: variable_assignment.',' variable_assignments
',' shift 143
- . reduce 218 (src line 1227)
+ . reduce 231 (src line 1297)
state 66
- variable_assignment: VARIABLE. (216)
+ variable_assignment: VARIABLE. (229)
variable_assignment: VARIABLE.SUBSTITUTION_OP value
SUBSTITUTION_OP shift 144
- . reduce 216 (src line 1217)
+ . reduce 229 (src line 1287)
state 67
variable_statement: variable_substitution statement_terminal. (21)
- . reduce 21 (src line 239)
+ . reduce 21 (src line 245)
state 68
transaction_statement: COMMIT statement_terminal. (22)
- . reduce 22 (src line 244)
+ . reduce 22 (src line 250)
state 69
transaction_statement: ROLLBACK statement_terminal. (23)
- . reduce 23 (src line 249)
+ . reduce 23 (src line 255)
state 70
@@ -763,28 +763,28 @@ state 70
state 71
cursor_statement: OPEN identifier.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 146
state 72
cursor_statement: CLOSE identifier.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 147
state 73
cursor_statement: DISPOSE identifier.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
statement_terminal goto 148
@@ -815,7 +815,7 @@ state 75
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
@@ -830,83 +830,83 @@ state 75
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
state 76
- value: field_reference. (70)
+ value: field_reference. (73)
- . reduce 70 (src line 498)
+ . reduce 73 (src line 518)
state 77
- value: primary. (71)
+ value: primary. (74)
- . reduce 71 (src line 503)
+ . reduce 74 (src line 523)
state 78
- value: arithmetic. (72)
+ value: arithmetic. (75)
- . reduce 72 (src line 507)
+ . reduce 75 (src line 527)
state 79
- value: string_operation. (73)
+ value: string_operation. (76)
- . reduce 73 (src line 511)
+ . reduce 76 (src line 531)
- 80: reduce/reduce conflict (red'ns 74 and 83) on IN
- 80: reduce/reduce conflict (red'ns 74 and 83) on NOT
- 80: reduce/reduce conflict (red'ns 74 and 83) on BETWEEN
- 80: reduce/reduce conflict (red'ns 74 and 83) on COMPARISON_OP
- 80: reduce/reduce conflict (red'ns 74 and 83) on '='
+ 80: reduce/reduce conflict (red'ns 77 and 86) on IN
+ 80: reduce/reduce conflict (red'ns 77 and 86) on NOT
+ 80: reduce/reduce conflict (red'ns 77 and 86) on BETWEEN
+ 80: reduce/reduce conflict (red'ns 77 and 86) on COMPARISON_OP
+ 80: reduce/reduce conflict (red'ns 77 and 86) on '='
state 80
- value: subquery. (74)
- row_value: subquery. (83)
+ value: subquery. (77)
+ row_value: subquery. (86)
- . reduce 74 (src line 515)
+ . reduce 77 (src line 535)
state 81
- value: function. (75)
+ value: function. (78)
- . reduce 75 (src line 519)
+ . reduce 78 (src line 539)
state 82
- value: case. (76)
+ value: case. (79)
- . reduce 76 (src line 523)
+ . reduce 79 (src line 543)
state 83
- value: comparison. (77)
+ value: comparison. (80)
- . reduce 77 (src line 527)
+ . reduce 80 (src line 547)
state 84
- value: logic. (78)
+ value: logic. (81)
- . reduce 78 (src line 531)
+ . reduce 81 (src line 551)
state 85
- value: variable. (79)
+ value: variable. (82)
variable_substitution: variable.SUBSTITUTION_OP value
SUBSTITUTION_OP shift 119
- . reduce 79 (src line 535)
+ . reduce 82 (src line 555)
state 86
- value: variable_substitution. (80)
+ value: variable_substitution. (83)
- . reduce 80 (src line 539)
+ . reduce 83 (src line 559)
state 87
@@ -958,62 +958,62 @@ state 87
variable goto 85
variable_substitution goto 86
-88: shift/reduce conflict (shift 169(0), red'n 68(0)) on '('
+88: shift/reduce conflict (shift 169(0), red'n 71(0)) on '('
state 88
- field_reference: identifier. (68)
+ field_reference: identifier. (71)
field_reference: identifier.'.' identifier
function: identifier.'(' option ')'
'.' shift 168
'(' shift 169
- . reduce 68 (src line 488)
+ . reduce 71 (src line 508)
state 89
- primary: text. (62)
+ primary: text. (65)
- . reduce 62 (src line 462)
+ . reduce 65 (src line 482)
state 90
- primary: integer. (63)
+ primary: integer. (66)
- . reduce 63 (src line 467)
+ . reduce 66 (src line 487)
state 91
- primary: float. (64)
+ primary: float. (67)
- . reduce 64 (src line 471)
+ . reduce 67 (src line 491)
state 92
- primary: ternary. (65)
+ primary: ternary. (68)
- . reduce 65 (src line 475)
+ . reduce 68 (src line 495)
state 93
- primary: datetime. (66)
+ primary: datetime. (69)
- . reduce 66 (src line 479)
+ . reduce 69 (src line 499)
state 94
- primary: null. (67)
+ primary: null. (70)
- . reduce 67 (src line 483)
+ . reduce 70 (src line 503)
state 95
- function: group_concat. (120)
+ function: group_concat. (130)
- . reduce 120 (src line 736)
+ . reduce 130 (src line 790)
state 96
case: CASE.case_value case_when case_else END
- case_value: . (150)
+ case_value: . (165)
IDENTIFIER shift 59
STRING shift 100
@@ -1029,7 +1029,7 @@ state 96
GROUP_CONCAT shift 107
'-' shift 102
'(' shift 87
- . reduce 150 (src line 877)
+ . reduce 165 (src line 957)
primary goto 77
field_reference goto 76
@@ -1064,12 +1064,12 @@ state 97
comparison: row_value.comparison_operator ANY subquery
comparison: row_value.comparison_operator ALL '(' row_values ')'
comparison: row_value.comparison_operator ALL subquery
- negation: . (222)
+ negation: . (235)
NOT shift 164
COMPARISON_OP shift 172
'=' shift 173
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 174
comparison_operator goto 175
@@ -1124,15 +1124,15 @@ state 99
variable_substitution goto 86
state 100
- text: STRING. (204)
+ text: STRING. (217)
- . reduce 204 (src line 1149)
+ . reduce 217 (src line 1219)
state 101
- integer: INTEGER. (205)
+ integer: INTEGER. (218)
- . reduce 205 (src line 1155)
+ . reduce 218 (src line 1225)
state 102
@@ -1148,27 +1148,27 @@ state 102
float goto 179
state 103
- float: FLOAT. (207)
+ float: FLOAT. (220)
- . reduce 207 (src line 1166)
+ . reduce 220 (src line 1236)
state 104
- ternary: TERNARY. (209)
+ ternary: TERNARY. (222)
- . reduce 209 (src line 1177)
+ . reduce 222 (src line 1247)
state 105
- datetime: DATETIME. (210)
+ datetime: DATETIME. (223)
- . reduce 210 (src line 1183)
+ . reduce 223 (src line 1253)
state 106
- null: NULL. (211)
+ null: NULL. (224)
- . reduce 211 (src line 1189)
+ . reduce 224 (src line 1259)
state 107
@@ -1198,7 +1198,7 @@ state 108
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
@@ -1213,7 +1213,7 @@ state 108
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
@@ -1225,22 +1225,22 @@ state 109
. error
- 110: reduce/reduce conflict (red'ns 79 and 213) on IN
+ 110: reduce/reduce conflict (red'ns 82 and 226) on IN
state 110
- value: variable. (79)
- variables: variable. (213)
+ value: variable. (82)
+ variables: variable. (226)
variables: variable.',' variables
variable_substitution: variable.SUBSTITUTION_OP value
SUBSTITUTION_OP shift 119
',' shift 183
- . reduce 79 (src line 535)
+ . reduce 82 (src line 555)
state 111
flow_control_statement: EXIT statement_terminal. (33)
- . reduce 33 (src line 293)
+ . reduce 33 (src line 299)
state 112
@@ -1269,15 +1269,15 @@ state 113
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- statement_terminal: . (236)
- negation: . (222)
+ statement_terminal: . (249)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -1288,7 +1288,7 @@ state 113
'/' shift 160
'%' shift 161
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
negation goto 155
comparison_operator goto 156
@@ -1299,7 +1299,7 @@ state 114
where_clause: . (50)
WHERE shift 187
- . reduce 50 (src line 402)
+ . reduce 50 (src line 408)
where_clause goto 186
@@ -1322,28 +1322,28 @@ state 115
state 116
select_entity: select_set_entity UNION.all select_set_entity
- all: . (232)
+ all: . (245)
ALL shift 190
- . reduce 232 (src line 1295)
+ . reduce 245 (src line 1365)
all goto 189
state 117
select_entity: select_set_entity INTERSECT.all select_set_entity
- all: . (232)
+ all: . (245)
ALL shift 190
- . reduce 232 (src line 1295)
+ . reduce 245 (src line 1365)
all goto 191
state 118
select_entity: select_set_entity EXCEPT.all select_set_entity
- all: . (232)
+ all: . (245)
ALL shift 190
- . reduce 232 (src line 1295)
+ . reduce 245 (src line 1365)
all goto 192
@@ -1404,7 +1404,7 @@ state 120
CASE shift 96
GROUP_CONCAT shift 107
'-' shift 102
- '*' shift 198
+ '*' shift 199
'(' shift 87
. error
@@ -1419,11 +1419,12 @@ state 120
logic goto 84
function goto 81
group_concat goto 95
+ analytic_function goto 198
field_object goto 196
field goto 195
case goto 82
fields goto 194
- identifier goto 88
+ identifier goto 200
text goto 89
integer goto 90
float goto 91
@@ -1434,33 +1435,68 @@ state 120
variable_substitution goto 86
state 121
- distinct: DISTINCT. (221)
+ distinct: DISTINCT. (234)
- . reduce 221 (src line 1242)
+ . reduce 234 (src line 1312)
state 122
subquery: '(' select_query.')'
- ')' shift 199
+ ')' shift 201
. error
state 123
select_query: select_entity order_by_clause limit_clause.offset_clause
- offset_clause: . (60)
+ offset_clause: . (63)
- OFFSET shift 201
- . reduce 60 (src line 452)
+ OFFSET shift 203
+ . reduce 63 (src line 472)
- offset_clause goto 200
+ offset_clause goto 202
state 124
- limit_clause: LIMIT.INTEGER
+ limit_clause: LIMIT.value limit_with
+ limit_clause: LIMIT.value PERCENT limit_with
- INTEGER shift 202
+ IDENTIFIER shift 59
+ STRING shift 100
+ INTEGER shift 101
+ FLOAT shift 103
+ TERNARY shift 104
+ DATETIME shift 105
+ VARIABLE shift 41
+ EXISTS shift 98
+ NOT shift 99
+ NULL shift 106
+ CASE shift 96
+ GROUP_CONCAT shift 107
+ '-' shift 102
+ '(' shift 87
. error
+ primary goto 77
+ field_reference goto 76
+ value goto 204
+ row_value goto 97
+ subquery goto 80
+ string_operation goto 79
+ comparison goto 83
+ arithmetic goto 78
+ logic goto 84
+ function goto 81
+ group_concat goto 95
+ case goto 82
+ identifier goto 88
+ text goto 89
+ integer goto 90
+ float goto 91
+ ternary goto 92
+ datetime goto 93
+ null goto 94
+ variable goto 85
+ variable_substitution goto 86
state 125
order_by_clause: ORDER BY.order_items
@@ -1483,9 +1519,11 @@ state 125
primary goto 77
field_reference goto 76
- value goto 205
+ value goto 208
row_value goto 97
- order_item goto 204
+ order_items goto 205
+ order_item goto 206
+ order_value goto 207
subquery goto 80
string_operation goto 79
comparison goto 83
@@ -1493,9 +1531,9 @@ state 125
logic goto 84
function goto 81
group_concat goto 95
+ analytic_function goto 209
case goto 82
- order_items goto 203
- identifier goto 88
+ identifier goto 200
text goto 89
integer goto 90
float goto 91
@@ -1512,11 +1550,11 @@ state 126
insert_query: INSERT INTO identifier.'(' field_references ')' select_query
SELECT shift 39
- VALUES shift 206
- '(' shift 207
+ VALUES shift 210
+ '(' shift 211
. error
- select_query goto 208
+ select_query goto 212
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
@@ -1528,10 +1566,10 @@ state 127
IDENTIFIER shift 59
. error
- field_reference goto 211
- update_set goto 210
- update_set_list goto 209
- identifier goto 212
+ field_reference goto 215
+ update_set goto 214
+ update_set_list goto 213
+ identifier goto 216
state 128
identified_tables: identified_table ','.identified_tables
@@ -1540,13 +1578,13 @@ state 128
. error
identified_table goto 57
- identified_tables goto 213
+ identified_tables goto 217
identifier goto 58
state 129
- identified_table: identifier identifier. (127)
+ identified_table: identifier identifier. (141)
- . reduce 127 (src line 770)
+ . reduce 141 (src line 846)
state 130
@@ -1555,82 +1593,82 @@ state 130
IDENTIFIER shift 59
. error
- identifier goto 214
+ identifier goto 218
state 131
delete_query: DELETE FROM tables.where_clause
where_clause: . (50)
WHERE shift 187
- . reduce 50 (src line 402)
+ . reduce 50 (src line 408)
- where_clause goto 215
+ where_clause goto 219
- 132: reduce/reduce conflict (red'ns 224 and 228) on JOIN
+ 132: reduce/reduce conflict (red'ns 237 and 241) on JOIN
state 132
join: table.join_inner JOIN table join_condition
join: table.NATURAL join_inner JOIN table
join: table.join_direction join_outer JOIN table join_condition
join: table.NATURAL join_direction join_outer JOIN table
join: table.CROSS JOIN table
- tables: table. (160)
+ tables: table. (173)
tables: table.',' tables
- join_inner: . (224)
- join_direction: . (228)
-
- JOIN reduce 224 (src line 1257)
- INNER shift 221
- OUTER reduce 228 (src line 1277)
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- CROSS shift 219
- NATURAL shift 217
- ',' shift 220
- . reduce 160 (src line 927)
-
- join_inner goto 216
- join_direction goto 218
+ join_inner: . (237)
+ join_direction: . (241)
+
+ JOIN reduce 237 (src line 1327)
+ INNER shift 225
+ OUTER reduce 241 (src line 1347)
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ CROSS shift 223
+ NATURAL shift 221
+ ',' shift 224
+ . reduce 173 (src line 997)
+
+ join_inner goto 220
+ join_direction goto 222
state 133
- table: identified_table. (131)
+ table: identified_table. (145)
- . reduce 131 (src line 789)
+ . reduce 145 (src line 865)
state 134
- table: virtual_table. (132)
+ table: virtual_table. (146)
table: virtual_table.identifier
table: virtual_table.AS identifier
IDENTIFIER shift 59
- AS shift 226
- . reduce 132 (src line 794)
+ AS shift 230
+ . reduce 146 (src line 870)
- identifier goto 225
+ identifier goto 229
state 135
- table: join. (135)
+ table: join. (149)
- . reduce 135 (src line 806)
+ . reduce 149 (src line 882)
state 136
- table: DUAL. (136)
+ table: DUAL. (150)
- . reduce 136 (src line 810)
+ . reduce 150 (src line 886)
state 137
- virtual_table: subquery. (129)
+ virtual_table: subquery. (143)
- . reduce 129 (src line 779)
+ . reduce 143 (src line 855)
state 138
- virtual_table: STDIN. (130)
+ virtual_table: STDIN. (144)
- . reduce 130 (src line 784)
+ . reduce 144 (src line 860)
state 139
@@ -1647,13 +1685,13 @@ state 139
virtual_table goto 134
table goto 132
join goto 135
- tables goto 227
+ tables goto 231
identifier goto 58
state 140
create_table: CREATE TABLE identifier.'(' using_fields ')'
- '(' shift 228
+ '(' shift 232
. error
@@ -1664,16 +1702,16 @@ state 141
drop_columns: ALTER TABLE identifier.DROP '(' field_references ')'
rename_column: ALTER TABLE identifier.RENAME field_reference TO identifier
- ADD shift 229
- DROP shift 230
- RENAME shift 231
+ ADD shift 233
+ DROP shift 234
+ RENAME shift 235
. error
state 142
variable_statement: VAR variable_assignments statement_terminal. (20)
- . reduce 20 (src line 234)
+ . reduce 20 (src line 240)
state 143
@@ -1683,7 +1721,7 @@ state 143
. error
variable_assignment goto 65
- variable_assignments goto 232
+ variable_assignments goto 236
state 144
variable_assignment: VARIABLE SUBSTITUTION_OP.value
@@ -1706,7 +1744,7 @@ state 144
primary goto 77
field_reference goto 76
- value goto 233
+ value goto 237
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -1729,26 +1767,26 @@ state 144
state 145
cursor_statement: DECLARE identifier CURSOR.FOR select_query statement_terminal
- FOR shift 234
+ FOR shift 238
. error
state 146
cursor_statement: OPEN identifier statement_terminal. (25)
- . reduce 25 (src line 259)
+ . reduce 25 (src line 265)
state 147
cursor_statement: CLOSE identifier statement_terminal. (26)
- . reduce 26 (src line 263)
+ . reduce 26 (src line 269)
state 148
cursor_statement: DISPOSE identifier statement_terminal. (27)
- . reduce 27 (src line 267)
+ . reduce 27 (src line 273)
state 149
@@ -1757,8 +1795,8 @@ state 149
VARIABLE shift 41
. error
- variable goto 236
- variables goto 235
+ variable goto 240
+ variables goto 239
state 150
flow_control_statement: IF value THEN.program else END IF statement_terminal
@@ -1786,9 +1824,9 @@ state 150
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
- program goto 237
+ program goto 241
statement goto 2
variable_statement goto 11
transaction_statement goto 12
@@ -1831,7 +1869,7 @@ state 151
primary goto 77
field_reference goto 76
- value goto 238
+ value goto 242
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -1853,7 +1891,7 @@ state 151
state 152
comparison: value COMPARISON_OP.value
- comparison_operator: COMPARISON_OP. (234)
+ comparison_operator: COMPARISON_OP. (247)
IDENTIFIER shift 59
STRING shift 100
@@ -1869,11 +1907,11 @@ state 152
GROUP_CONCAT shift 107
'-' shift 102
'(' shift 87
- . reduce 234 (src line 1305)
+ . reduce 247 (src line 1375)
primary goto 77
field_reference goto 76
- value goto 239
+ value goto 243
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -1895,7 +1933,7 @@ state 152
state 153
comparison: value '='.value
- comparison_operator: '='. (235)
+ comparison_operator: '='. (248)
IDENTIFIER shift 59
STRING shift 100
@@ -1911,11 +1949,11 @@ state 153
GROUP_CONCAT shift 107
'-' shift 102
'(' shift 87
- . reduce 235 (src line 1310)
+ . reduce 248 (src line 1380)
primary goto 77
field_reference goto 76
- value goto 240
+ value goto 244
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -1938,21 +1976,21 @@ state 153
state 154
comparison: value IS.negation ternary
comparison: value IS.negation null
- negation: . (222)
+ negation: . (235)
NOT shift 164
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
- negation goto 241
+ negation goto 245
state 155
comparison: value negation.BETWEEN value AND value
comparison: value negation.IN row_value
comparison: value negation.LIKE value
- IN shift 243
- BETWEEN shift 242
- LIKE shift 244
+ IN shift 247
+ BETWEEN shift 246
+ LIKE shift 248
. error
@@ -1960,8 +1998,8 @@ state 156
comparison: value comparison_operator.ANY row_value
comparison: value comparison_operator.ALL row_value
- ALL shift 246
- ANY shift 245
+ ALL shift 250
+ ANY shift 249
. error
@@ -1986,7 +2024,7 @@ state 157
primary goto 77
field_reference goto 76
- value goto 247
+ value goto 251
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2027,7 +2065,7 @@ state 158
primary goto 77
field_reference goto 76
- value goto 248
+ value goto 252
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2068,7 +2106,7 @@ state 159
primary goto 77
field_reference goto 76
- value goto 249
+ value goto 253
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2109,7 +2147,7 @@ state 160
primary goto 77
field_reference goto 76
- value goto 250
+ value goto 254
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2150,7 +2188,7 @@ state 161
primary goto 77
field_reference goto 76
- value goto 251
+ value goto 255
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2191,7 +2229,7 @@ state 162
primary goto 77
field_reference goto 76
- value goto 252
+ value goto 256
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2232,7 +2270,7 @@ state 163
primary goto 77
field_reference goto 76
- value goto 253
+ value goto 257
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2253,12 +2291,12 @@ state 163
variable_substitution goto 86
state 164
- negation: NOT. (223)
+ negation: NOT. (236)
- . reduce 223 (src line 1252)
+ . reduce 236 (src line 1322)
-165: shift/reduce conflict (shift 254(0), red'n 156(0)) on ')'
+165: shift/reduce conflict (shift 258(0), red'n 171(0)) on ')'
state 165
value: '(' value.')'
string_operation: value.STRING_OP value
@@ -2278,9 +2316,9 @@ state 165
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- values: value. (156)
+ values: value. (171)
values: value.',' values
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
@@ -2294,9 +2332,9 @@ state 165
'*' shift 159
'/' shift 160
'%' shift 161
- ')' shift 254
- ',' shift 255
- . reduce 222 (src line 1247)
+ ')' shift 258
+ ',' shift 259
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
@@ -2304,24 +2342,24 @@ state 165
state 166
row_value: '(' values.')'
- ')' shift 256
+ ')' shift 260
. error
- 167: reduce/reduce conflict (red'ns 74 and 83) on IN
- 167: reduce/reduce conflict (red'ns 74 and 83) on NOT
- 167: reduce/reduce conflict (red'ns 74 and 83) on BETWEEN
- 167: reduce/reduce conflict (red'ns 74 and 83) on COMPARISON_OP
- 167: reduce/reduce conflict (red'ns 74 and 83) on '='
+ 167: reduce/reduce conflict (red'ns 77 and 86) on IN
+ 167: reduce/reduce conflict (red'ns 77 and 86) on NOT
+ 167: reduce/reduce conflict (red'ns 77 and 86) on BETWEEN
+ 167: reduce/reduce conflict (red'ns 77 and 86) on COMPARISON_OP
+ 167: reduce/reduce conflict (red'ns 77 and 86) on '='
state 167
select_set_entity: subquery. (46)
- value: subquery. (74)
- row_value: subquery. (83)
+ value: subquery. (77)
+ row_value: subquery. (86)
- UNION reduce 46 (src line 381)
- INTERSECT reduce 46 (src line 381)
- EXCEPT reduce 46 (src line 381)
- . reduce 74 (src line 515)
+ UNION reduce 46 (src line 387)
+ INTERSECT reduce 46 (src line 387)
+ EXCEPT reduce 46 (src line 387)
+ . reduce 77 (src line 535)
state 168
@@ -2330,27 +2368,27 @@ state 168
IDENTIFIER shift 59
. error
- identifier goto 257
+ identifier goto 261
state 169
function: identifier '('.option ')'
- option: . (121)
- distinct: . (220)
+ option: . (131)
+ distinct: . (233)
DISTINCT shift 121
- ')' reduce 121 (src line 741)
- . reduce 220 (src line 1237)
+ ')' reduce 131 (src line 795)
+ . reduce 233 (src line 1307)
- option goto 258
- distinct goto 259
+ option goto 262
+ distinct goto 263
state 170
case: CASE case_value.case_when case_else END
- WHEN shift 261
+ WHEN shift 265
. error
- case_when goto 260
+ case_when goto 264
state 171
string_operation: value.STRING_OP value
@@ -2370,14 +2408,14 @@ state 171
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- case_value: value. (151)
- negation: . (222)
+ case_value: value. (166)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- WHEN reduce 151 (src line 882)
+ WHEN reduce 166 (src line 962)
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -2386,38 +2424,38 @@ state 171
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
state 172
comparison: row_value COMPARISON_OP.row_value
- comparison_operator: COMPARISON_OP. (234)
+ comparison_operator: COMPARISON_OP. (247)
- '(' shift 263
- . reduce 234 (src line 1305)
+ '(' shift 267
+ . reduce 247 (src line 1375)
- row_value goto 262
- subquery goto 264
+ row_value goto 266
+ subquery goto 268
state 173
comparison: row_value '='.row_value
- comparison_operator: '='. (235)
+ comparison_operator: '='. (248)
- '(' shift 263
- . reduce 235 (src line 1310)
+ '(' shift 267
+ . reduce 248 (src line 1380)
- row_value goto 265
- subquery goto 264
+ row_value goto 269
+ subquery goto 268
state 174
comparison: row_value negation.BETWEEN row_value AND row_value
comparison: row_value negation.IN '(' row_values ')'
comparison: row_value negation.IN subquery
- IN shift 267
- BETWEEN shift 266
+ IN shift 271
+ BETWEEN shift 270
. error
@@ -2427,20 +2465,20 @@ state 175
comparison: row_value comparison_operator.ALL '(' row_values ')'
comparison: row_value comparison_operator.ALL subquery
- ALL shift 269
- ANY shift 268
+ ALL shift 273
+ ANY shift 272
. error
state 176
- comparison: EXISTS subquery. (110)
+ comparison: EXISTS subquery. (120)
- . reduce 110 (src line 690)
+ . reduce 120 (src line 744)
- 177: reduce/reduce conflict (red'ns 118 and 222) on IN
- 177: reduce/reduce conflict (red'ns 118 and 222) on BETWEEN
- 177: reduce/reduce conflict (red'ns 118 and 222) on LIKE
+ 177: reduce/reduce conflict (red'ns 128 and 235) on IN
+ 177: reduce/reduce conflict (red'ns 128 and 235) on BETWEEN
+ 177: reduce/reduce conflict (red'ns 128 and 235) on LIKE
state 177
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
@@ -2459,8 +2497,8 @@ state 177
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- logic: NOT value. (118)
- negation: . (222)
+ logic: NOT value. (128)
+ negation: . (235)
NOT shift 164
IS shift 154
@@ -2472,37 +2510,37 @@ state 177
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 118 (src line 726)
+ . reduce 128 (src line 780)
negation goto 155
comparison_operator goto 156
state 178
- integer: '-' integer. (206)
+ integer: '-' integer. (219)
- . reduce 206 (src line 1160)
+ . reduce 219 (src line 1230)
state 179
- float: '-' float. (208)
+ float: '-' float. (221)
- . reduce 208 (src line 1171)
+ . reduce 221 (src line 1241)
state 180
group_concat: GROUP_CONCAT '('.option order_by_clause ')'
group_concat: GROUP_CONCAT '('.option order_by_clause SEPARATOR STRING ')'
- option: . (121)
- distinct: . (220)
+ option: . (131)
+ distinct: . (233)
- ORDER reduce 121 (src line 741)
+ ORDER reduce 131 (src line 795)
DISTINCT shift 121
- SEPARATOR reduce 121 (src line 741)
- ')' reduce 121 (src line 741)
- . reduce 220 (src line 1237)
+ SEPARATOR reduce 131 (src line 795)
+ ')' reduce 131 (src line 795)
+ . reduce 233 (src line 1307)
- option goto 270
- distinct goto 259
+ option goto 274
+ distinct goto 263
state 181
flow_control_statement: WHILE value DO.in_loop_program END WHILE statement_terminal
@@ -2516,7 +2554,7 @@ state 181
INSERT shift 17
CREATE shift 20
ALTER shift 21
- IF shift 275
+ IF shift 279
WHILE shift 32
DECLARE shift 26
FETCH shift 30
@@ -2525,22 +2563,22 @@ state 181
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE shift 276
- BREAK shift 277
+ CONTINUE shift 280
+ BREAK shift 281
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 3 (src line 158)
+ . reduce 3 (src line 164)
- in_loop_program goto 271
- statement goto 273
- in_loop_statement goto 272
+ in_loop_program goto 275
+ statement goto 277
+ in_loop_statement goto 276
variable_statement goto 11
transaction_statement goto 12
cursor_statement goto 13
flow_control_statement goto 14
- in_loop_flow_control_statement goto 274
+ in_loop_flow_control_statement goto 278
command_statement goto 15
select_query goto 3
select_entity goto 16
@@ -2563,7 +2601,7 @@ state 182
IDENTIFIER shift 59
. error
- identifier goto 278
+ identifier goto 282
state 183
variables: variable ','.variables
@@ -2571,8 +2609,8 @@ state 183
VARIABLE shift 41
. error
- variable goto 236
- variables goto 279
+ variable goto 240
+ variables goto 283
state 184
command_statement: SET FLAG '='.primary statement_terminal
@@ -2586,7 +2624,7 @@ state 184
'-' shift 102
. error
- primary goto 280
+ primary goto 284
text goto 89
integer goto 90
float goto 91
@@ -2597,17 +2635,17 @@ state 184
state 185
command_statement: PRINT value statement_terminal. (39)
- . reduce 39 (src line 321)
+ . reduce 39 (src line 327)
state 186
select_entity: select_clause from_clause where_clause.group_by_clause having_clause
group_by_clause: . (52)
- GROUP shift 282
- . reduce 52 (src line 412)
+ GROUP shift 286
+ . reduce 52 (src line 418)
- group_by_clause goto 281
+ group_by_clause goto 285
state 187
where_clause: WHERE.value
@@ -2630,7 +2668,7 @@ state 187
primary goto 77
field_reference goto 76
- value goto 283
+ value goto 287
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -2653,7 +2691,7 @@ state 187
state 188
from_clause: FROM tables. (49)
- . reduce 49 (src line 397)
+ . reduce 49 (src line 403)
state 189
@@ -2663,15 +2701,15 @@ state 189
'(' shift 42
. error
- select_entity goto 285
- select_set_entity goto 284
+ select_entity goto 289
+ select_set_entity goto 288
select_clause goto 36
subquery goto 40
state 190
- all: ALL. (233)
+ all: ALL. (246)
- . reduce 233 (src line 1300)
+ . reduce 246 (src line 1370)
state 191
@@ -2681,8 +2719,8 @@ state 191
'(' shift 42
. error
- select_entity goto 285
- select_set_entity goto 286
+ select_entity goto 289
+ select_set_entity goto 290
select_clause goto 36
subquery goto 40
@@ -2693,26 +2731,26 @@ state 192
'(' shift 42
. error
- select_entity goto 285
- select_set_entity goto 287
+ select_entity goto 289
+ select_set_entity goto 291
select_clause goto 36
subquery goto 40
-193: shift/reduce conflict (shift 163(4), red'n 215(0)) on AND
-193: shift/reduce conflict (shift 162(3), red'n 215(0)) on OR
-193: shift/reduce conflict (shift 164(5), red'n 215(0)) on NOT
-193: shift/reduce conflict (shift 154(6), red'n 215(0)) on IS
-193: shift/reduce conflict (shift 152(6), red'n 215(0)) on COMPARISON_OP
-193: shift/reduce conflict (shift 151(7), red'n 215(0)) on STRING_OP
-193: shift/reduce conflict (shift 153(6), red'n 215(0)) on '='
-193: shift/reduce conflict (shift 157(8), red'n 215(0)) on '+'
-193: shift/reduce conflict (shift 158(8), red'n 215(0)) on '-'
-193: shift/reduce conflict (shift 159(9), red'n 215(0)) on '*'
-193: shift/reduce conflict (shift 160(9), red'n 215(0)) on '/'
-193: shift/reduce conflict (shift 161(9), red'n 215(0)) on '%'
- 193: reduce/reduce conflict (red'ns 215 and 222) on IN
- 193: reduce/reduce conflict (red'ns 215 and 222) on BETWEEN
- 193: reduce/reduce conflict (red'ns 215 and 222) on LIKE
+193: shift/reduce conflict (shift 163(4), red'n 228(0)) on AND
+193: shift/reduce conflict (shift 162(3), red'n 228(0)) on OR
+193: shift/reduce conflict (shift 164(5), red'n 228(0)) on NOT
+193: shift/reduce conflict (shift 154(6), red'n 228(0)) on IS
+193: shift/reduce conflict (shift 152(6), red'n 228(0)) on COMPARISON_OP
+193: shift/reduce conflict (shift 151(7), red'n 228(0)) on STRING_OP
+193: shift/reduce conflict (shift 153(6), red'n 228(0)) on '='
+193: shift/reduce conflict (shift 157(8), red'n 228(0)) on '+'
+193: shift/reduce conflict (shift 158(8), red'n 228(0)) on '-'
+193: shift/reduce conflict (shift 159(9), red'n 228(0)) on '*'
+193: shift/reduce conflict (shift 160(9), red'n 228(0)) on '/'
+193: shift/reduce conflict (shift 161(9), red'n 228(0)) on '%'
+ 193: reduce/reduce conflict (red'ns 228 and 235) on IN
+ 193: reduce/reduce conflict (red'ns 228 and 235) on BETWEEN
+ 193: reduce/reduce conflict (red'ns 228 and 235) on LIKE
state 193
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
@@ -2731,8 +2769,8 @@ state 193
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- variable_substitution: variable SUBSTITUTION_OP value. (215)
- negation: . (222)
+ variable_substitution: variable SUBSTITUTION_OP value. (228)
+ negation: . (235)
AND shift 163
OR shift 162
@@ -2746,7 +2784,7 @@ state 193
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 215 (src line 1211)
+ . reduce 228 (src line 1281)
negation goto 155
comparison_operator goto 156
@@ -2754,23 +2792,23 @@ state 193
state 194
select_clause: SELECT distinct fields. (47)
- . reduce 47 (src line 386)
+ . reduce 47 (src line 392)
state 195
- fields: field. (166)
+ fields: field. (179)
fields: field.',' fields
- ',' shift 288
- . reduce 166 (src line 957)
+ ',' shift 292
+ . reduce 179 (src line 1027)
state 196
- field: field_object. (147)
+ field: field_object. (162)
field: field_object.AS identifier
- AS shift 289
- . reduce 147 (src line 861)
+ AS shift 293
+ . reduce 162 (src line 941)
state 197
@@ -2791,15 +2829,15 @@ state 197
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- field_object: value. (145)
- negation: . (222)
+ field_object: value. (159)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -2809,58 +2847,161 @@ state 197
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 145 (src line 851)
+ . reduce 159 (src line 927)
negation goto 155
comparison_operator goto 156
state 198
- field_object: '*'. (146)
+ field_object: analytic_function. (160)
- . reduce 146 (src line 856)
+ . reduce 160 (src line 932)
state 199
- subquery: '(' select_query ')'. (90)
+ field_object: '*'. (161)
- . reduce 90 (src line 588)
+ . reduce 161 (src line 936)
+200: shift/reduce conflict (shift 294(0), red'n 71(0)) on '('
state 200
- select_query: select_entity order_by_clause limit_clause offset_clause. (40)
+ field_reference: identifier. (71)
+ field_reference: identifier.'.' identifier
+ function: identifier.'(' option ')'
+ analytic_function: identifier.'(' option ')' OVER '(' analytic_clause ')'
- . reduce 40 (src line 326)
+ '.' shift 168
+ '(' shift 294
+ . reduce 71 (src line 508)
state 201
- offset_clause: OFFSET.INTEGER
+ subquery: '(' select_query ')'. (100)
- INTEGER shift 290
- . error
+ . reduce 100 (src line 642)
state 202
- limit_clause: LIMIT INTEGER. (59)
+ select_query: select_entity order_by_clause limit_clause offset_clause. (40)
- . reduce 59 (src line 447)
+ . reduce 40 (src line 332)
state 203
- order_by_clause: ORDER BY order_items. (57)
+ offset_clause: OFFSET.value
- . reduce 57 (src line 437)
+ IDENTIFIER shift 59
+ STRING shift 100
+ INTEGER shift 101
+ FLOAT shift 103
+ TERNARY shift 104
+ DATETIME shift 105
+ VARIABLE shift 41
+ EXISTS shift 98
+ NOT shift 99
+ NULL shift 106
+ CASE shift 96
+ GROUP_CONCAT shift 107
+ '-' shift 102
+ '(' shift 87
+ . error
+ primary goto 77
+ field_reference goto 76
+ value goto 295
+ row_value goto 97
+ subquery goto 80
+ string_operation goto 79
+ comparison goto 83
+ arithmetic goto 78
+ logic goto 84
+ function goto 81
+ group_concat goto 95
+ case goto 82
+ identifier goto 88
+ text goto 89
+ integer goto 90
+ float goto 91
+ ternary goto 92
+ datetime goto 93
+ null goto 94
+ variable goto 85
+ variable_substitution goto 86
state 204
- order_items: order_item. (158)
- order_items: order_item.',' order_items
+ limit_clause: LIMIT value.limit_with
+ limit_clause: LIMIT value.PERCENT limit_with
+ string_operation: value.STRING_OP value
+ comparison: value.COMPARISON_OP value
+ comparison: value.'=' value
+ comparison: value.IS negation ternary
+ comparison: value.IS negation null
+ comparison: value.negation BETWEEN value AND value
+ comparison: value.negation IN row_value
+ comparison: value.negation LIKE value
+ comparison: value.comparison_operator ANY row_value
+ comparison: value.comparison_operator ALL row_value
+ arithmetic: value.'+' value
+ arithmetic: value.'-' value
+ arithmetic: value.'*' value
+ arithmetic: value.'/' value
+ arithmetic: value.'%' value
+ logic: value.OR value
+ logic: value.AND value
+ limit_with: . (61)
+ negation: . (235)
- ',' shift 291
- . reduce 158 (src line 917)
+ PERCENT shift 297
+ IN reduce 235 (src line 1317)
+ AND shift 163
+ OR shift 162
+ NOT shift 164
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
+ IS shift 154
+ WITH shift 298
+ COMPARISON_OP shift 152
+ STRING_OP shift 151
+ '=' shift 153
+ '+' shift 157
+ '-' shift 158
+ '*' shift 159
+ '/' shift 160
+ '%' shift 161
+ . reduce 61 (src line 462)
+ limit_with goto 296
+ negation goto 155
+ comparison_operator goto 156
state 205
- order_item: value.order_direction
+ order_by_clause: ORDER BY order_items. (57)
+
+ . reduce 57 (src line 443)
+
+
+state 206
+ order_items: order_item. (89)
+ order_items: order_item.',' order_items
+
+ ',' shift 299
+ . reduce 89 (src line 588)
+
+
+state 207
+ order_item: order_value.order_direction
+ order_item: order_value.order_direction NULLS order_null_position
+ order_direction: . (95)
+
+ ASC shift 301
+ DESC shift 302
+ . reduce 95 (src line 618)
+
+ order_direction goto 300
+
+state 208
+ order_value: value. (93)
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -2878,17 +3019,14 @@ state 205
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- order_direction: . (87)
- negation: . (222)
+ negation: . (235)
- ASC shift 293
- DESC shift 294
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -2898,23 +3036,28 @@ state 205
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 87 (src line 574)
+ . reduce 93 (src line 608)
negation goto 155
- order_direction goto 292
comparison_operator goto 156
-state 206
+state 209
+ order_value: analytic_function. (94)
+
+ . reduce 94 (src line 613)
+
+
+state 210
insert_query: INSERT INTO identifier VALUES.row_values
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 296
- row_values goto 295
- subquery goto 264
+ row_value goto 304
+ row_values goto 303
+ subquery goto 268
-state 207
+state 211
subquery: '('.select_query ')'
insert_query: INSERT INTO identifier '('.field_references ')' VALUES row_values
insert_query: INSERT INTO identifier '('.field_references ')' select_query
@@ -2928,108 +3071,108 @@ state 207
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
- field_reference goto 298
+ field_reference goto 306
subquery goto 40
- field_references goto 297
- identifier goto 212
+ field_references goto 305
+ identifier goto 216
-state 208
- insert_query: INSERT INTO identifier select_query. (172)
+state 212
+ insert_query: INSERT INTO identifier select_query. (185)
- . reduce 172 (src line 986)
+ . reduce 185 (src line 1056)
-state 209
+state 213
update_query: UPDATE identified_tables SET update_set_list.from_clause where_clause
from_clause: . (48)
FROM shift 115
- . reduce 48 (src line 392)
+ . reduce 48 (src line 398)
- from_clause goto 299
+ from_clause goto 307
-state 210
- update_set_list: update_set. (176)
+state 214
+ update_set_list: update_set. (189)
update_set_list: update_set.',' update_set_list
- ',' shift 300
- . reduce 176 (src line 1007)
+ ',' shift 308
+ . reduce 189 (src line 1077)
-state 211
+state 215
update_set: field_reference.'=' value
- '=' shift 301
+ '=' shift 309
. error
-state 212
- field_reference: identifier. (68)
+state 216
+ field_reference: identifier. (71)
field_reference: identifier.'.' identifier
'.' shift 168
- . reduce 68 (src line 488)
+ . reduce 71 (src line 508)
-state 213
- identified_tables: identified_table ',' identified_tables. (163)
+state 217
+ identified_tables: identified_table ',' identified_tables. (176)
- . reduce 163 (src line 942)
+ . reduce 176 (src line 1012)
-state 214
- identified_table: identifier AS identifier. (128)
+state 218
+ identified_table: identifier AS identifier. (142)
- . reduce 128 (src line 774)
+ . reduce 142 (src line 850)
-state 215
- delete_query: DELETE FROM tables where_clause. (178)
+state 219
+ delete_query: DELETE FROM tables where_clause. (191)
- . reduce 178 (src line 1017)
+ . reduce 191 (src line 1087)
-state 216
+state 220
join: table join_inner.JOIN table join_condition
- JOIN shift 302
+ JOIN shift 310
. error
- 217: reduce/reduce conflict (red'ns 224 and 228) on JOIN
-state 217
+ 221: reduce/reduce conflict (red'ns 237 and 241) on JOIN
+state 221
join: table NATURAL.join_inner JOIN table
join: table NATURAL.join_direction join_outer JOIN table
- join_inner: . (224)
- join_direction: . (228)
+ join_inner: . (237)
+ join_direction: . (241)
- INNER shift 221
- OUTER reduce 228 (src line 1277)
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- . reduce 224 (src line 1257)
+ INNER shift 225
+ OUTER reduce 241 (src line 1347)
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ . reduce 237 (src line 1327)
- join_inner goto 303
- join_direction goto 304
+ join_inner goto 311
+ join_direction goto 312
-state 218
+state 222
join: table join_direction.join_outer JOIN table join_condition
- join_outer: . (226)
+ join_outer: . (239)
- OUTER shift 306
- . reduce 226 (src line 1267)
+ OUTER shift 314
+ . reduce 239 (src line 1337)
- join_outer goto 305
+ join_outer goto 313
-state 219
+state 223
join: table CROSS.JOIN table
- JOIN shift 307
+ JOIN shift 315
. error
-state 220
+state 224
tables: table ','.tables
IDENTIFIER shift 59
@@ -3043,103 +3186,103 @@ state 220
virtual_table goto 134
table goto 132
join goto 135
- tables goto 308
+ tables goto 316
identifier goto 58
-state 221
- join_inner: INNER. (225)
+state 225
+ join_inner: INNER. (238)
- . reduce 225 (src line 1262)
+ . reduce 238 (src line 1332)
-state 222
- join_direction: LEFT. (229)
+state 226
+ join_direction: LEFT. (242)
- . reduce 229 (src line 1282)
+ . reduce 242 (src line 1352)
-state 223
- join_direction: RIGHT. (230)
+state 227
+ join_direction: RIGHT. (243)
- . reduce 230 (src line 1286)
+ . reduce 243 (src line 1356)
-state 224
- join_direction: FULL. (231)
+state 228
+ join_direction: FULL. (244)
- . reduce 231 (src line 1290)
+ . reduce 244 (src line 1360)
-state 225
- table: virtual_table identifier. (133)
+state 229
+ table: virtual_table identifier. (147)
- . reduce 133 (src line 798)
+ . reduce 147 (src line 874)
-state 226
+state 230
table: virtual_table AS.identifier
IDENTIFIER shift 59
. error
- identifier goto 309
+ identifier goto 317
-state 227
+state 231
delete_query: DELETE identified_tables FROM tables.where_clause
where_clause: . (50)
WHERE shift 187
- . reduce 50 (src line 402)
+ . reduce 50 (src line 408)
- where_clause goto 310
+ where_clause goto 318
-state 228
+state 232
create_table: CREATE TABLE identifier '('.using_fields ')'
IDENTIFIER shift 59
. error
- using_fields goto 311
- identifier goto 312
+ using_fields goto 319
+ identifier goto 320
-state 229
+state 233
add_columns: ALTER TABLE identifier ADD.column_default column_position
add_columns: ALTER TABLE identifier ADD.'(' column_defaults ')' column_position
IDENTIFIER shift 59
- '(' shift 314
+ '(' shift 322
. error
- column_default goto 313
- identifier goto 315
+ column_default goto 321
+ identifier goto 323
-state 230
+state 234
drop_columns: ALTER TABLE identifier DROP.field_reference
drop_columns: ALTER TABLE identifier DROP.'(' field_references ')'
IDENTIFIER shift 59
- '(' shift 317
+ '(' shift 325
. error
- field_reference goto 316
- identifier goto 212
+ field_reference goto 324
+ identifier goto 216
-state 231
+state 235
rename_column: ALTER TABLE identifier RENAME.field_reference TO identifier
IDENTIFIER shift 59
. error
- field_reference goto 318
- identifier goto 212
+ field_reference goto 326
+ identifier goto 216
-state 232
- variable_assignments: variable_assignment ',' variable_assignments. (219)
+state 236
+ variable_assignments: variable_assignment ',' variable_assignments. (232)
- . reduce 219 (src line 1232)
+ . reduce 232 (src line 1302)
-state 233
+state 237
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3157,15 +3300,15 @@ state 233
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- variable_assignment: VARIABLE SUBSTITUTION_OP value. (217)
- negation: . (222)
+ variable_assignment: VARIABLE SUBSTITUTION_OP value. (230)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -3175,59 +3318,59 @@ state 233
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 217 (src line 1222)
+ . reduce 230 (src line 1292)
negation goto 155
comparison_operator goto 156
-state 234
+state 238
cursor_statement: DECLARE identifier CURSOR FOR.select_query statement_terminal
SELECT shift 39
'(' shift 42
. error
- select_query goto 319
+ select_query goto 327
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
subquery goto 40
-state 235
+state 239
cursor_statement: FETCH identifier INTO variables.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 320
+ statement_terminal goto 328
-state 236
- variables: variable. (213)
+state 240
+ variables: variable. (226)
variables: variable.',' variables
',' shift 183
- . reduce 213 (src line 1201)
+ . reduce 226 (src line 1271)
-state 237
+state 241
flow_control_statement: IF value THEN program.else END IF statement_terminal
flow_control_statement: IF value THEN program.elseif else END IF statement_terminal
- else: . (197)
+ else: . (210)
- ELSEIF shift 324
- ELSE shift 323
- . reduce 197 (src line 1113)
+ ELSEIF shift 332
+ ELSE shift 331
+ . reduce 210 (src line 1183)
- elseif goto 322
- else goto 321
+ elseif goto 330
+ else goto 329
- 238: reduce/reduce conflict (red'ns 91 and 222) on IN
- 238: reduce/reduce conflict (red'ns 91 and 222) on BETWEEN
- 238: reduce/reduce conflict (red'ns 91 and 222) on LIKE
-state 238
+ 242: reduce/reduce conflict (red'ns 101 and 235) on IN
+ 242: reduce/reduce conflict (red'ns 101 and 235) on BETWEEN
+ 242: reduce/reduce conflict (red'ns 101 and 235) on LIKE
+state 242
string_operation: value.STRING_OP value
- string_operation: value STRING_OP value. (91)
+ string_operation: value STRING_OP value. (101)
comparison: value.COMPARISON_OP value
comparison: value.'=' value
comparison: value.IS negation ternary
@@ -3244,25 +3387,25 @@ state 238
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
'+' shift 157
'-' shift 158
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 91 (src line 594)
+ . reduce 101 (src line 648)
negation goto 155
comparison_operator goto 156
- 239: reduce/reduce conflict (red'ns 92 and 222) on IN
- 239: reduce/reduce conflict (red'ns 92 and 222) on BETWEEN
- 239: reduce/reduce conflict (red'ns 92 and 222) on LIKE
-state 239
+ 243: reduce/reduce conflict (red'ns 102 and 235) on IN
+ 243: reduce/reduce conflict (red'ns 102 and 235) on BETWEEN
+ 243: reduce/reduce conflict (red'ns 102 and 235) on LIKE
+state 243
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
- comparison: value COMPARISON_OP value. (92)
+ comparison: value COMPARISON_OP value. (102)
comparison: value.'=' value
comparison: value.IS negation ternary
comparison: value.IS negation null
@@ -3278,7 +3421,7 @@ state 239
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
IS error
COMPARISON_OP error
@@ -3289,19 +3432,19 @@ state 239
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 92 (src line 617)
+ . reduce 102 (src line 671)
negation goto 155
comparison_operator goto 156
- 240: reduce/reduce conflict (red'ns 94 and 222) on IN
- 240: reduce/reduce conflict (red'ns 94 and 222) on BETWEEN
- 240: reduce/reduce conflict (red'ns 94 and 222) on LIKE
-state 240
+ 244: reduce/reduce conflict (red'ns 104 and 235) on IN
+ 244: reduce/reduce conflict (red'ns 104 and 235) on BETWEEN
+ 244: reduce/reduce conflict (red'ns 104 and 235) on LIKE
+state 244
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
- comparison: value '=' value. (94)
+ comparison: value '=' value. (104)
comparison: value.IS negation ternary
comparison: value.IS negation null
comparison: value.negation BETWEEN value AND value
@@ -3316,7 +3459,7 @@ state 240
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
IS error
COMPARISON_OP error
@@ -3327,12 +3470,12 @@ state 240
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 94 (src line 626)
+ . reduce 104 (src line 680)
negation goto 155
comparison_operator goto 156
-state 241
+state 245
comparison: value IS negation.ternary
comparison: value IS negation.null
@@ -3340,10 +3483,10 @@ state 241
NULL shift 106
. error
- ternary goto 325
- null goto 326
+ ternary goto 333
+ null goto 334
-state 242
+state 246
comparison: value negation BETWEEN.value AND value
IDENTIFIER shift 59
@@ -3364,7 +3507,7 @@ state 242
primary goto 77
field_reference goto 76
- value goto 327
+ value goto 335
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -3384,16 +3527,16 @@ state 242
variable goto 85
variable_substitution goto 86
-state 243
+state 247
comparison: value negation IN.row_value
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 328
- subquery goto 264
+ row_value goto 336
+ subquery goto 268
-state 244
+state 248
comparison: value negation LIKE.value
IDENTIFIER shift 59
@@ -3414,7 +3557,7 @@ state 244
primary goto 77
field_reference goto 76
- value goto 329
+ value goto 337
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -3434,28 +3577,28 @@ state 244
variable goto 85
variable_substitution goto 86
-state 245
+state 249
comparison: value comparison_operator ANY.row_value
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 330
- subquery goto 264
+ row_value goto 338
+ subquery goto 268
-state 246
+state 250
comparison: value comparison_operator ALL.row_value
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 331
- subquery goto 264
+ row_value goto 339
+ subquery goto 268
- 247: reduce/reduce conflict (red'ns 111 and 222) on IN
- 247: reduce/reduce conflict (red'ns 111 and 222) on BETWEEN
- 247: reduce/reduce conflict (red'ns 111 and 222) on LIKE
-state 247
+ 251: reduce/reduce conflict (red'ns 121 and 235) on IN
+ 251: reduce/reduce conflict (red'ns 121 and 235) on BETWEEN
+ 251: reduce/reduce conflict (red'ns 121 and 235) on LIKE
+state 251
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3467,27 +3610,27 @@ state 247
comparison: value.comparison_operator ANY row_value
comparison: value.comparison_operator ALL row_value
arithmetic: value.'+' value
- arithmetic: value '+' value. (111)
+ arithmetic: value '+' value. (121)
arithmetic: value.'-' value
arithmetic: value.'*' value
arithmetic: value.'/' value
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 111 (src line 695)
+ . reduce 121 (src line 749)
negation goto 155
comparison_operator goto 156
- 248: reduce/reduce conflict (red'ns 112 and 222) on IN
- 248: reduce/reduce conflict (red'ns 112 and 222) on BETWEEN
- 248: reduce/reduce conflict (red'ns 112 and 222) on LIKE
-state 248
+ 252: reduce/reduce conflict (red'ns 122 and 235) on IN
+ 252: reduce/reduce conflict (red'ns 122 and 235) on BETWEEN
+ 252: reduce/reduce conflict (red'ns 122 and 235) on LIKE
+state 252
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3500,26 +3643,26 @@ state 248
comparison: value.comparison_operator ALL row_value
arithmetic: value.'+' value
arithmetic: value.'-' value
- arithmetic: value '-' value. (112)
+ arithmetic: value '-' value. (122)
arithmetic: value.'*' value
arithmetic: value.'/' value
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 112 (src line 700)
+ . reduce 122 (src line 754)
negation goto 155
comparison_operator goto 156
- 249: reduce/reduce conflict (red'ns 113 and 222) on IN
- 249: reduce/reduce conflict (red'ns 113 and 222) on BETWEEN
- 249: reduce/reduce conflict (red'ns 113 and 222) on LIKE
-state 249
+ 253: reduce/reduce conflict (red'ns 123 and 235) on IN
+ 253: reduce/reduce conflict (red'ns 123 and 235) on BETWEEN
+ 253: reduce/reduce conflict (red'ns 123 and 235) on LIKE
+state 253
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3533,22 +3676,22 @@ state 249
arithmetic: value.'+' value
arithmetic: value.'-' value
arithmetic: value.'*' value
- arithmetic: value '*' value. (113)
+ arithmetic: value '*' value. (123)
arithmetic: value.'/' value
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
- . reduce 113 (src line 704)
+ . reduce 123 (src line 758)
negation goto 155
comparison_operator goto 156
- 250: reduce/reduce conflict (red'ns 114 and 222) on IN
- 250: reduce/reduce conflict (red'ns 114 and 222) on BETWEEN
- 250: reduce/reduce conflict (red'ns 114 and 222) on LIKE
-state 250
+ 254: reduce/reduce conflict (red'ns 124 and 235) on IN
+ 254: reduce/reduce conflict (red'ns 124 and 235) on BETWEEN
+ 254: reduce/reduce conflict (red'ns 124 and 235) on LIKE
+state 254
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3563,21 +3706,21 @@ state 250
arithmetic: value.'-' value
arithmetic: value.'*' value
arithmetic: value.'/' value
- arithmetic: value '/' value. (114)
+ arithmetic: value '/' value. (124)
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
- . reduce 114 (src line 708)
+ . reduce 124 (src line 762)
negation goto 155
comparison_operator goto 156
- 251: reduce/reduce conflict (red'ns 115 and 222) on IN
- 251: reduce/reduce conflict (red'ns 115 and 222) on BETWEEN
- 251: reduce/reduce conflict (red'ns 115 and 222) on LIKE
-state 251
+ 255: reduce/reduce conflict (red'ns 125 and 235) on IN
+ 255: reduce/reduce conflict (red'ns 125 and 235) on BETWEEN
+ 255: reduce/reduce conflict (red'ns 125 and 235) on LIKE
+state 255
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3593,20 +3736,20 @@ state 251
arithmetic: value.'*' value
arithmetic: value.'/' value
arithmetic: value.'%' value
- arithmetic: value '%' value. (115)
+ arithmetic: value '%' value. (125)
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
- . reduce 115 (src line 712)
+ . reduce 125 (src line 766)
negation goto 155
comparison_operator goto 156
- 252: reduce/reduce conflict (red'ns 116 and 222) on IN
- 252: reduce/reduce conflict (red'ns 116 and 222) on BETWEEN
- 252: reduce/reduce conflict (red'ns 116 and 222) on LIKE
-state 252
+ 256: reduce/reduce conflict (red'ns 126 and 235) on IN
+ 256: reduce/reduce conflict (red'ns 126 and 235) on BETWEEN
+ 256: reduce/reduce conflict (red'ns 126 and 235) on LIKE
+state 256
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3623,9 +3766,9 @@ state 252
arithmetic: value.'/' value
arithmetic: value.'%' value
logic: value.OR value
- logic: value OR value. (116)
+ logic: value OR value. (126)
logic: value.AND value
- negation: . (222)
+ negation: . (235)
AND shift 163
NOT shift 164
@@ -3638,15 +3781,15 @@ state 252
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 116 (src line 717)
+ . reduce 126 (src line 771)
negation goto 155
comparison_operator goto 156
- 253: reduce/reduce conflict (red'ns 117 and 222) on IN
- 253: reduce/reduce conflict (red'ns 117 and 222) on BETWEEN
- 253: reduce/reduce conflict (red'ns 117 and 222) on LIKE
-state 253
+ 257: reduce/reduce conflict (red'ns 127 and 235) on IN
+ 257: reduce/reduce conflict (red'ns 127 and 235) on BETWEEN
+ 257: reduce/reduce conflict (red'ns 127 and 235) on LIKE
+state 257
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -3664,8 +3807,8 @@ state 253
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- logic: value AND value. (117)
- negation: . (222)
+ logic: value AND value. (127)
+ negation: . (235)
NOT shift 164
IS shift 154
@@ -3677,18 +3820,18 @@ state 253
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 117 (src line 722)
+ . reduce 127 (src line 776)
negation goto 155
comparison_operator goto 156
-state 254
- value: '(' value ')'. (81)
+state 258
+ value: '(' value ')'. (84)
- . reduce 81 (src line 543)
+ . reduce 84 (src line 563)
-state 255
+state 259
values: value ','.values
IDENTIFIER shift 59
@@ -3709,7 +3852,7 @@ state 255
primary goto 77
field_reference goto 76
- value goto 333
+ value goto 341
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -3719,7 +3862,7 @@ state 255
function goto 81
group_concat goto 95
case goto 82
- values goto 332
+ values goto 340
identifier goto 88
text goto 89
integer goto 90
@@ -3730,26 +3873,26 @@ state 255
variable goto 85
variable_substitution goto 86
-state 256
- row_value: '(' values ')'. (82)
+state 260
+ row_value: '(' values ')'. (85)
- . reduce 82 (src line 548)
+ . reduce 85 (src line 568)
-state 257
- field_reference: identifier '.' identifier. (69)
+state 261
+ field_reference: identifier '.' identifier. (72)
- . reduce 69 (src line 493)
+ . reduce 72 (src line 513)
-state 258
+state 262
function: identifier '(' option.')'
- ')' shift 334
+ ')' shift 342
. error
-state 259
+state 263
option: distinct.'*'
option: distinct.values
@@ -3766,13 +3909,13 @@ state 259
CASE shift 96
GROUP_CONCAT shift 107
'-' shift 102
- '*' shift 335
+ '*' shift 343
'(' shift 87
. error
primary goto 77
field_reference goto 76
- value goto 333
+ value goto 341
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -3782,7 +3925,7 @@ state 259
function goto 81
group_concat goto 95
case goto 82
- values goto 336
+ values goto 344
identifier goto 88
text goto 89
integer goto 90
@@ -3793,19 +3936,19 @@ state 259
variable goto 85
variable_substitution goto 86
-state 260
+state 264
case: CASE case_value case_when.case_else END
case_when: case_when.case_when
- case_else: . (152)
+ case_else: . (167)
- WHEN shift 261
- ELSE shift 339
- . reduce 152 (src line 887)
+ WHEN shift 265
+ ELSE shift 347
+ . reduce 167 (src line 967)
- case_else goto 337
- case_when goto 338
+ case_else goto 345
+ case_when goto 346
-state 261
+state 265
case_when: WHEN.value THEN value
IDENTIFIER shift 59
@@ -3826,7 +3969,7 @@ state 261
primary goto 77
field_reference goto 76
- value goto 340
+ value goto 348
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -3846,13 +3989,13 @@ state 261
variable goto 85
variable_substitution goto 86
-state 262
- comparison: row_value COMPARISON_OP row_value. (93)
+state 266
+ comparison: row_value COMPARISON_OP row_value. (103)
- . reduce 93 (src line 622)
+ . reduce 103 (src line 676)
-state 263
+state 267
row_value: '('.values ')'
subquery: '('.select_query ')'
@@ -3879,7 +4022,7 @@ state 263
select_clause goto 36
primary goto 77
field_reference goto 76
- value goto 333
+ value goto 341
row_value goto 97
subquery goto 167
string_operation goto 79
@@ -3900,72 +4043,72 @@ state 263
variable goto 85
variable_substitution goto 86
-state 264
- row_value: subquery. (83)
+state 268
+ row_value: subquery. (86)
- . reduce 83 (src line 553)
+ . reduce 86 (src line 573)
-state 265
- comparison: row_value '=' row_value. (95)
+state 269
+ comparison: row_value '=' row_value. (105)
- . reduce 95 (src line 630)
+ . reduce 105 (src line 684)
-state 266
+state 270
comparison: row_value negation BETWEEN.row_value AND row_value
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 341
- subquery goto 264
+ row_value goto 349
+ subquery goto 268
-state 267
+state 271
comparison: row_value negation IN.'(' row_values ')'
comparison: row_value negation IN.subquery
- '(' shift 342
+ '(' shift 350
. error
- subquery goto 343
+ subquery goto 351
-state 268
+state 272
comparison: row_value comparison_operator ANY.'(' row_values ')'
comparison: row_value comparison_operator ANY.subquery
- '(' shift 344
+ '(' shift 352
. error
- subquery goto 345
+ subquery goto 353
-state 269
+state 273
comparison: row_value comparison_operator ALL.'(' row_values ')'
comparison: row_value comparison_operator ALL.subquery
- '(' shift 346
+ '(' shift 354
. error
- subquery goto 347
+ subquery goto 355
-state 270
+state 274
group_concat: GROUP_CONCAT '(' option.order_by_clause ')'
group_concat: GROUP_CONCAT '(' option.order_by_clause SEPARATOR STRING ')'
order_by_clause: . (56)
ORDER shift 54
- . reduce 56 (src line 432)
+ . reduce 56 (src line 438)
- order_by_clause goto 348
+ order_by_clause goto 356
-state 271
+state 275
flow_control_statement: WHILE value DO in_loop_program.END WHILE statement_terminal
- END shift 349
+ END shift 357
. error
-state 272
+state 276
in_loop_program: in_loop_statement.in_loop_program
in_loop_program: . (3)
@@ -3977,7 +4120,7 @@ state 272
INSERT shift 17
CREATE shift 20
ALTER shift 21
- IF shift 275
+ IF shift 279
WHILE shift 32
DECLARE shift 26
FETCH shift 30
@@ -3986,22 +4129,22 @@ state 272
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE shift 276
- BREAK shift 277
+ CONTINUE shift 280
+ BREAK shift 281
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 3 (src line 158)
+ . reduce 3 (src line 164)
- in_loop_program goto 350
- statement goto 273
- in_loop_statement goto 272
+ in_loop_program goto 358
+ statement goto 277
+ in_loop_statement goto 276
variable_statement goto 11
transaction_statement goto 12
cursor_statement goto 13
flow_control_statement goto 14
- in_loop_flow_control_statement goto 274
+ in_loop_flow_control_statement goto 278
command_statement goto 15
select_query goto 3
select_entity goto 16
@@ -4018,19 +4161,19 @@ state 272
variable goto 38
variable_substitution goto 23
-state 273
+state 277
in_loop_statement: statement. (18)
- . reduce 18 (src line 224)
+ . reduce 18 (src line 230)
-state 274
+state 278
in_loop_statement: in_loop_flow_control_statement. (19)
- . reduce 19 (src line 229)
+ . reduce 19 (src line 235)
-state 275
+state 279
flow_control_statement: IF.value THEN program else END IF statement_terminal
flow_control_statement: IF.value THEN program elseif else END IF statement_terminal
in_loop_flow_control_statement: IF.value THEN in_loop_program in_loop_else END IF statement_terminal
@@ -4054,7 +4197,7 @@ state 275
primary goto 77
field_reference goto 76
- value goto 351
+ value goto 359
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -4074,63 +4217,63 @@ state 275
variable goto 85
variable_substitution goto 86
-state 276
+state 280
in_loop_flow_control_statement: CONTINUE.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 352
+ statement_terminal goto 360
-state 277
+state 281
in_loop_flow_control_statement: BREAK.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 353
+ statement_terminal goto 361
-state 278
+state 282
flow_control_statement: WHILE variables IN identifier.DO in_loop_program END WHILE statement_terminal
- DO shift 354
+ DO shift 362
. error
-state 279
- variables: variable ',' variables. (214)
+state 283
+ variables: variable ',' variables. (227)
- . reduce 214 (src line 1206)
+ . reduce 227 (src line 1276)
-state 280
+state 284
command_statement: SET FLAG '=' primary.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 355
+ statement_terminal goto 363
-state 281
+state 285
select_entity: select_clause from_clause where_clause group_by_clause.having_clause
having_clause: . (54)
- HAVING shift 357
- . reduce 54 (src line 422)
+ HAVING shift 365
+ . reduce 54 (src line 428)
- having_clause goto 356
+ having_clause goto 364
-state 282
+state 286
group_by_clause: GROUP.BY values
- BY shift 358
+ BY shift 366
. error
-state 283
+state 287
where_clause: WHERE value. (51)
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
@@ -4149,14 +4292,14 @@ state 283
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -4166,47 +4309,47 @@ state 283
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 51 (src line 407)
+ . reduce 51 (src line 413)
negation goto 155
comparison_operator goto 156
-state 284
+state 288
select_entity: select_set_entity.UNION all select_set_entity
select_entity: select_set_entity UNION all select_set_entity. (42)
select_entity: select_set_entity.INTERSECT all select_set_entity
select_entity: select_set_entity.EXCEPT all select_set_entity
INTERSECT shift 117
- . reduce 42 (src line 348)
+ . reduce 42 (src line 354)
-state 285
+state 289
select_set_entity: select_entity. (45)
- . reduce 45 (src line 376)
+ . reduce 45 (src line 382)
-state 286
+state 290
select_entity: select_set_entity.UNION all select_set_entity
select_entity: select_set_entity.INTERSECT all select_set_entity
select_entity: select_set_entity INTERSECT all select_set_entity. (43)
select_entity: select_set_entity.EXCEPT all select_set_entity
- . reduce 43 (src line 357)
+ . reduce 43 (src line 363)
-state 287
+state 291
select_entity: select_set_entity.UNION all select_set_entity
select_entity: select_set_entity.INTERSECT all select_set_entity
select_entity: select_set_entity.EXCEPT all select_set_entity
select_entity: select_set_entity EXCEPT all select_set_entity. (44)
INTERSECT shift 117
- . reduce 44 (src line 366)
+ . reduce 44 (src line 372)
-state 288
+state 292
fields: field ','.fields
IDENTIFIER shift 59
@@ -4222,7 +4365,7 @@ state 288
CASE shift 96
GROUP_CONCAT shift 107
'-' shift 102
- '*' shift 198
+ '*' shift 199
'(' shift 87
. error
@@ -4237,11 +4380,12 @@ state 288
logic goto 84
function goto 81
group_concat goto 95
+ analytic_function goto 198
field_object goto 196
field goto 195
case goto 82
- fields goto 359
- identifier goto 88
+ fields goto 367
+ identifier goto 200
text goto 89
integer goto 90
float goto 91
@@ -4251,21 +4395,91 @@ state 288
variable goto 85
variable_substitution goto 86
-state 289
+state 293
field: field_object AS.identifier
IDENTIFIER shift 59
. error
- identifier goto 360
+ identifier goto 368
-state 290
- offset_clause: OFFSET INTEGER. (61)
+state 294
+ function: identifier '('.option ')'
+ analytic_function: identifier '('.option ')' OVER '(' analytic_clause ')'
+ option: . (131)
+ distinct: . (233)
- . reduce 61 (src line 457)
+ DISTINCT shift 121
+ ')' reduce 131 (src line 795)
+ . reduce 233 (src line 1307)
+ option goto 369
+ distinct goto 263
-state 291
+state 295
+ offset_clause: OFFSET value. (64)
+ string_operation: value.STRING_OP value
+ comparison: value.COMPARISON_OP value
+ comparison: value.'=' value
+ comparison: value.IS negation ternary
+ comparison: value.IS negation null
+ comparison: value.negation BETWEEN value AND value
+ comparison: value.negation IN row_value
+ comparison: value.negation LIKE value
+ comparison: value.comparison_operator ANY row_value
+ comparison: value.comparison_operator ALL row_value
+ arithmetic: value.'+' value
+ arithmetic: value.'-' value
+ arithmetic: value.'*' value
+ arithmetic: value.'/' value
+ arithmetic: value.'%' value
+ logic: value.OR value
+ logic: value.AND value
+ negation: . (235)
+
+ IN reduce 235 (src line 1317)
+ AND shift 163
+ OR shift 162
+ NOT shift 164
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
+ IS shift 154
+ COMPARISON_OP shift 152
+ STRING_OP shift 151
+ '=' shift 153
+ '+' shift 157
+ '-' shift 158
+ '*' shift 159
+ '/' shift 160
+ '%' shift 161
+ . reduce 64 (src line 477)
+
+ negation goto 155
+ comparison_operator goto 156
+
+state 296
+ limit_clause: LIMIT value limit_with. (59)
+
+ . reduce 59 (src line 453)
+
+
+state 297
+ limit_clause: LIMIT value PERCENT.limit_with
+ limit_with: . (61)
+
+ WITH shift 298
+ . reduce 61 (src line 462)
+
+ limit_with goto 370
+
+state 298
+ limit_with: WITH.TIES
+
+ TIES shift 371
+ . error
+
+
+state 299
order_items: order_item ','.order_items
IDENTIFIER shift 59
@@ -4286,9 +4500,11 @@ state 291
primary goto 77
field_reference goto 76
- value goto 205
+ value goto 208
row_value goto 97
- order_item goto 204
+ order_items goto 372
+ order_item goto 206
+ order_value goto 207
subquery goto 80
string_operation goto 79
comparison goto 83
@@ -4296,9 +4512,9 @@ state 291
logic goto 84
function goto 81
group_concat goto 95
+ analytic_function goto 209
case goto 82
- order_items goto 361
- identifier goto 88
+ identifier goto 200
text goto 89
integer goto 90
float goto 91
@@ -4308,75 +4524,77 @@ state 291
variable goto 85
variable_substitution goto 86
-state 292
- order_item: value order_direction. (86)
+state 300
+ order_item: order_value order_direction. (91)
+ order_item: order_value order_direction.NULLS order_null_position
- . reduce 86 (src line 568)
+ NULLS shift 373
+ . reduce 91 (src line 598)
-state 293
- order_direction: ASC. (88)
+state 301
+ order_direction: ASC. (96)
- . reduce 88 (src line 579)
+ . reduce 96 (src line 623)
-state 294
- order_direction: DESC. (89)
+state 302
+ order_direction: DESC. (97)
- . reduce 89 (src line 583)
+ . reduce 97 (src line 627)
-state 295
- insert_query: INSERT INTO identifier VALUES row_values. (170)
+state 303
+ insert_query: INSERT INTO identifier VALUES row_values. (183)
- . reduce 170 (src line 977)
+ . reduce 183 (src line 1047)
-state 296
- row_values: row_value. (84)
+state 304
+ row_values: row_value. (87)
row_values: row_value.',' row_values
- ',' shift 362
- . reduce 84 (src line 558)
+ ',' shift 374
+ . reduce 87 (src line 578)
-state 297
+state 305
insert_query: INSERT INTO identifier '(' field_references.')' VALUES row_values
insert_query: INSERT INTO identifier '(' field_references.')' select_query
- ')' shift 363
+ ')' shift 375
. error
-state 298
- field_references: field_reference. (154)
+state 306
+ field_references: field_reference. (169)
field_references: field_reference.',' field_references
- ',' shift 364
- . reduce 154 (src line 897)
+ ',' shift 376
+ . reduce 169 (src line 977)
-state 299
+state 307
update_query: UPDATE identified_tables SET update_set_list from_clause.where_clause
where_clause: . (50)
WHERE shift 187
- . reduce 50 (src line 402)
+ . reduce 50 (src line 408)
- where_clause goto 365
+ where_clause goto 377
-state 300
+state 308
update_set_list: update_set ','.update_set_list
IDENTIFIER shift 59
. error
- field_reference goto 211
- update_set goto 210
- update_set_list goto 366
- identifier goto 212
+ field_reference goto 215
+ update_set goto 214
+ update_set_list goto 378
+ identifier goto 216
-state 301
+state 309
update_set: field_reference '='.value
IDENTIFIER shift 59
@@ -4397,7 +4615,7 @@ state 301
primary goto 77
field_reference goto 76
- value goto 367
+ value goto 379
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -4417,7 +4635,7 @@ state 301
variable goto 85
variable_substitution goto 86
-state 302
+state 310
join: table join_inner JOIN.table join_condition
IDENTIFIER shift 59
@@ -4429,40 +4647,40 @@ state 302
subquery goto 137
identified_table goto 133
virtual_table goto 134
- table goto 368
+ table goto 380
join goto 135
identifier goto 58
-state 303
+state 311
join: table NATURAL join_inner.JOIN table
- JOIN shift 369
+ JOIN shift 381
. error
-state 304
+state 312
join: table NATURAL join_direction.join_outer JOIN table
- join_outer: . (226)
+ join_outer: . (239)
- OUTER shift 306
- . reduce 226 (src line 1267)
+ OUTER shift 314
+ . reduce 239 (src line 1337)
- join_outer goto 370
+ join_outer goto 382
-state 305
+state 313
join: table join_direction join_outer.JOIN table join_condition
- JOIN shift 371
+ JOIN shift 383
. error
-state 306
- join_outer: OUTER. (227)
+state 314
+ join_outer: OUTER. (240)
- . reduce 227 (src line 1272)
+ . reduce 240 (src line 1342)
-state 307
+state 315
join: table CROSS JOIN.table
IDENTIFIER shift 59
@@ -4474,131 +4692,131 @@ state 307
subquery goto 137
identified_table goto 133
virtual_table goto 134
- table goto 372
+ table goto 384
join goto 135
identifier goto 58
-state 308
- tables: table ',' tables. (161)
+state 316
+ tables: table ',' tables. (174)
- . reduce 161 (src line 932)
+ . reduce 174 (src line 1002)
-state 309
- table: virtual_table AS identifier. (134)
+state 317
+ table: virtual_table AS identifier. (148)
- . reduce 134 (src line 802)
+ . reduce 148 (src line 878)
-state 310
- delete_query: DELETE identified_tables FROM tables where_clause. (179)
+state 318
+ delete_query: DELETE identified_tables FROM tables where_clause. (192)
- . reduce 179 (src line 1023)
+ . reduce 192 (src line 1093)
-state 311
+state 319
create_table: CREATE TABLE identifier '(' using_fields.')'
- ')' shift 373
+ ')' shift 385
. error
-state 312
- using_fields: identifier. (164)
+state 320
+ using_fields: identifier. (177)
using_fields: identifier.',' using_fields
- ',' shift 374
- . reduce 164 (src line 947)
+ ',' shift 386
+ . reduce 177 (src line 1017)
-state 313
+state 321
add_columns: ALTER TABLE identifier ADD column_default.column_position
- column_position: . (187)
+ column_position: . (200)
- FIRST shift 376
- LAST shift 377
- AFTER shift 378
- BEFORE shift 379
- . reduce 187 (src line 1065)
+ FIRST shift 388
+ LAST shift 389
+ AFTER shift 390
+ BEFORE shift 391
+ . reduce 200 (src line 1135)
- column_position goto 375
+ column_position goto 387
-state 314
+state 322
add_columns: ALTER TABLE identifier ADD '('.column_defaults ')' column_position
IDENTIFIER shift 59
. error
- column_default goto 381
- column_defaults goto 380
- identifier goto 315
+ column_default goto 393
+ column_defaults goto 392
+ identifier goto 323
-state 315
- column_default: identifier. (183)
+state 323
+ column_default: identifier. (196)
column_default: identifier.DEFAULT value
- DEFAULT shift 382
- . reduce 183 (src line 1045)
+ DEFAULT shift 394
+ . reduce 196 (src line 1115)
-state 316
- drop_columns: ALTER TABLE identifier DROP field_reference. (192)
+state 324
+ drop_columns: ALTER TABLE identifier DROP field_reference. (205)
- . reduce 192 (src line 1087)
+ . reduce 205 (src line 1157)
-state 317
+state 325
drop_columns: ALTER TABLE identifier DROP '('.field_references ')'
IDENTIFIER shift 59
. error
- field_reference goto 298
- field_references goto 383
- identifier goto 212
+ field_reference goto 306
+ field_references goto 395
+ identifier goto 216
-state 318
+state 326
rename_column: ALTER TABLE identifier RENAME field_reference.TO identifier
- TO shift 384
+ TO shift 396
. error
-state 319
+state 327
cursor_statement: DECLARE identifier CURSOR FOR select_query.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 385
+ statement_terminal goto 397
-state 320
+state 328
cursor_statement: FETCH identifier INTO variables statement_terminal. (28)
- . reduce 28 (src line 271)
+ . reduce 28 (src line 277)
-state 321
+state 329
flow_control_statement: IF value THEN program else.END IF statement_terminal
- END shift 386
+ END shift 398
. error
-state 322
+state 330
flow_control_statement: IF value THEN program elseif.else END IF statement_terminal
elseif: elseif.elseif
- else: . (197)
+ else: . (210)
- ELSEIF shift 324
- ELSE shift 323
- . reduce 197 (src line 1113)
+ ELSEIF shift 332
+ ELSE shift 331
+ . reduce 210 (src line 1183)
- elseif goto 388
- else goto 387
+ elseif goto 400
+ else goto 399
-state 323
+state 331
else: ELSE.program
program: . (1)
@@ -4623,9 +4841,9 @@ state 323
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
- program goto 389
+ program goto 401
statement goto 2
variable_statement goto 11
transaction_statement goto 12
@@ -4647,7 +4865,7 @@ state 323
variable goto 38
variable_substitution goto 23
-state 324
+state 332
elseif: ELSEIF.value THEN program
IDENTIFIER shift 59
@@ -4668,7 +4886,7 @@ state 324
primary goto 77
field_reference goto 76
- value goto 390
+ value goto 402
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -4688,19 +4906,19 @@ state 324
variable goto 85
variable_substitution goto 86
-state 325
- comparison: value IS negation ternary. (96)
+state 333
+ comparison: value IS negation ternary. (106)
- . reduce 96 (src line 634)
+ . reduce 106 (src line 688)
-state 326
- comparison: value IS negation null. (97)
+state 334
+ comparison: value IS negation null. (107)
- . reduce 97 (src line 638)
+ . reduce 107 (src line 692)
-state 327
+state 335
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -4719,9 +4937,9 @@ state 327
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
- AND shift 391
+ AND shift 403
OR shift 162
NOT shift 164
IS shift 154
@@ -4733,21 +4951,21 @@ state 327
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 328
- comparison: value negation IN row_value. (100)
+state 336
+ comparison: value negation IN row_value. (110)
- . reduce 100 (src line 650)
+ . reduce 110 (src line 704)
- 329: reduce/reduce conflict (red'ns 103 and 222) on IN
- 329: reduce/reduce conflict (red'ns 103 and 222) on BETWEEN
- 329: reduce/reduce conflict (red'ns 103 and 222) on LIKE
-state 329
+ 337: reduce/reduce conflict (red'ns 113 and 235) on IN
+ 337: reduce/reduce conflict (red'ns 113 and 235) on BETWEEN
+ 337: reduce/reduce conflict (red'ns 113 and 235) on LIKE
+state 337
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -4756,7 +4974,7 @@ state 329
comparison: value.negation BETWEEN value AND value
comparison: value.negation IN row_value
comparison: value.negation LIKE value
- comparison: value negation LIKE value. (103)
+ comparison: value negation LIKE value. (113)
comparison: value.comparison_operator ANY row_value
comparison: value.comparison_operator ALL row_value
arithmetic: value.'+' value
@@ -4766,7 +4984,7 @@ state 329
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
IS error
COMPARISON_OP error
@@ -4777,30 +4995,30 @@ state 329
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 103 (src line 662)
+ . reduce 113 (src line 716)
negation goto 155
comparison_operator goto 156
-state 330
- comparison: value comparison_operator ANY row_value. (104)
+state 338
+ comparison: value comparison_operator ANY row_value. (114)
- . reduce 104 (src line 666)
+ . reduce 114 (src line 720)
-state 331
- comparison: value comparison_operator ALL row_value. (107)
+state 339
+ comparison: value comparison_operator ALL row_value. (117)
- . reduce 107 (src line 678)
+ . reduce 117 (src line 732)
-state 332
- values: value ',' values. (157)
+state 340
+ values: value ',' values. (172)
- . reduce 157 (src line 912)
+ . reduce 172 (src line 992)
-state 333
+state 341
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -4818,16 +5036,16 @@ state 333
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- values: value. (156)
+ values: value. (171)
values: value.',' values
- negation: . (222)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -4837,48 +5055,48 @@ state 333
'*' shift 159
'/' shift 160
'%' shift 161
- ',' shift 255
- . reduce 156 (src line 907)
+ ',' shift 259
+ . reduce 171 (src line 987)
negation goto 155
comparison_operator goto 156
-state 334
- function: identifier '(' option ')'. (119)
+state 342
+ function: identifier '(' option ')'. (129)
- . reduce 119 (src line 731)
+ . reduce 129 (src line 785)
-state 335
- option: distinct '*'. (122)
+state 343
+ option: distinct '*'. (132)
- . reduce 122 (src line 746)
+ . reduce 132 (src line 800)
-state 336
- option: distinct values. (123)
+state 344
+ option: distinct values. (133)
- . reduce 123 (src line 750)
+ . reduce 133 (src line 804)
-state 337
+state 345
case: CASE case_value case_when case_else.END
- END shift 392
+ END shift 404
. error
-338: shift/reduce conflict (shift 261(0), red'n 169(0)) on WHEN
-state 338
+346: shift/reduce conflict (shift 265(0), red'n 182(0)) on WHEN
+state 346
case_when: case_when.case_when
- case_when: case_when case_when. (169)
+ case_when: case_when case_when. (182)
- WHEN shift 261
- . reduce 169 (src line 972)
+ WHEN shift 265
+ . reduce 182 (src line 1042)
- case_when goto 338
+ case_when goto 346
-state 339
+state 347
case_else: ELSE.value
IDENTIFIER shift 59
@@ -4899,7 +5117,7 @@ state 339
primary goto 77
field_reference goto 76
- value goto 393
+ value goto 405
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -4919,7 +5137,7 @@ state 339
variable goto 85
variable_substitution goto 86
-state 340
+state 348
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -4938,13 +5156,13 @@ state 340
logic: value.OR value
logic: value.AND value
case_when: WHEN value.THEN value
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- THEN shift 394
+ THEN shift 406
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -4953,107 +5171,107 @@ state 340
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 341
+state 349
comparison: row_value negation BETWEEN row_value.AND row_value
- AND shift 395
+ AND shift 407
. error
-state 342
+state 350
subquery: '('.select_query ')'
comparison: row_value negation IN '('.row_values ')'
SELECT shift 39
- '(' shift 263
+ '(' shift 267
. error
select_query goto 122
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
- row_value goto 296
- row_values goto 396
- subquery goto 397
+ row_value goto 304
+ row_values goto 408
+ subquery goto 409
-state 343
- comparison: row_value negation IN subquery. (102)
+state 351
+ comparison: row_value negation IN subquery. (112)
- . reduce 102 (src line 658)
+ . reduce 112 (src line 712)
-state 344
+state 352
subquery: '('.select_query ')'
comparison: row_value comparison_operator ANY '('.row_values ')'
SELECT shift 39
- '(' shift 263
+ '(' shift 267
. error
select_query goto 122
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
- row_value goto 296
- row_values goto 398
- subquery goto 397
+ row_value goto 304
+ row_values goto 410
+ subquery goto 409
-state 345
- comparison: row_value comparison_operator ANY subquery. (106)
+state 353
+ comparison: row_value comparison_operator ANY subquery. (116)
- . reduce 106 (src line 674)
+ . reduce 116 (src line 728)
-state 346
+state 354
subquery: '('.select_query ')'
comparison: row_value comparison_operator ALL '('.row_values ')'
SELECT shift 39
- '(' shift 263
+ '(' shift 267
. error
select_query goto 122
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
- row_value goto 296
- row_values goto 399
- subquery goto 397
+ row_value goto 304
+ row_values goto 411
+ subquery goto 409
-state 347
- comparison: row_value comparison_operator ALL subquery. (109)
+state 355
+ comparison: row_value comparison_operator ALL subquery. (119)
- . reduce 109 (src line 686)
+ . reduce 119 (src line 740)
-state 348
+state 356
group_concat: GROUP_CONCAT '(' option order_by_clause.')'
group_concat: GROUP_CONCAT '(' option order_by_clause.SEPARATOR STRING ')'
- SEPARATOR shift 401
- ')' shift 400
+ SEPARATOR shift 413
+ ')' shift 412
. error
-state 349
+state 357
flow_control_statement: WHILE value DO in_loop_program END.WHILE statement_terminal
- WHILE shift 402
+ WHILE shift 414
. error
-state 350
+state 358
in_loop_program: in_loop_statement in_loop_program. (4)
- . reduce 4 (src line 164)
+ . reduce 4 (src line 170)
-state 351
+state 359
flow_control_statement: IF value.THEN program else END IF statement_terminal
flow_control_statement: IF value.THEN program elseif else END IF statement_terminal
in_loop_flow_control_statement: IF value.THEN in_loop_program in_loop_else END IF statement_terminal
@@ -5075,13 +5293,13 @@ state 351
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- THEN shift 403
+ THEN shift 415
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -5090,24 +5308,24 @@ state 351
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 352
+state 360
in_loop_flow_control_statement: CONTINUE statement_terminal. (36)
- . reduce 36 (src line 307)
+ . reduce 36 (src line 313)
-state 353
+state 361
in_loop_flow_control_statement: BREAK statement_terminal. (37)
- . reduce 37 (src line 311)
+ . reduce 37 (src line 317)
-state 354
+state 362
flow_control_statement: WHILE variables IN identifier DO.in_loop_program END WHILE statement_terminal
in_loop_program: . (3)
@@ -5119,7 +5337,7 @@ state 354
INSERT shift 17
CREATE shift 20
ALTER shift 21
- IF shift 275
+ IF shift 279
WHILE shift 32
DECLARE shift 26
FETCH shift 30
@@ -5128,22 +5346,22 @@ state 354
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE shift 276
- BREAK shift 277
+ CONTINUE shift 280
+ BREAK shift 281
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 3 (src line 158)
+ . reduce 3 (src line 164)
- in_loop_program goto 404
- statement goto 273
- in_loop_statement goto 272
+ in_loop_program goto 416
+ statement goto 277
+ in_loop_statement goto 276
variable_statement goto 11
transaction_statement goto 12
cursor_statement goto 13
flow_control_statement goto 14
- in_loop_flow_control_statement goto 274
+ in_loop_flow_control_statement goto 278
command_statement goto 15
select_query goto 3
select_entity goto 16
@@ -5160,19 +5378,19 @@ state 354
variable goto 38
variable_substitution goto 23
-state 355
+state 363
command_statement: SET FLAG '=' primary statement_terminal. (38)
- . reduce 38 (src line 316)
+ . reduce 38 (src line 322)
-state 356
+state 364
select_entity: select_clause from_clause where_clause group_by_clause having_clause. (41)
- . reduce 41 (src line 337)
+ . reduce 41 (src line 343)
-state 357
+state 365
having_clause: HAVING.value
IDENTIFIER shift 59
@@ -5193,7 +5411,7 @@ state 357
primary goto 77
field_reference goto 76
- value goto 405
+ value goto 417
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -5213,7 +5431,7 @@ state 357
variable goto 85
variable_substitution goto 86
-state 358
+state 366
group_by_clause: GROUP BY.values
IDENTIFIER shift 59
@@ -5234,7 +5452,7 @@ state 358
primary goto 77
field_reference goto 76
- value goto 333
+ value goto 341
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -5244,7 +5462,7 @@ state 358
function goto 81
group_concat goto 95
case goto 82
- values goto 406
+ values goto 418
identifier goto 88
text goto 89
integer goto 90
@@ -5255,72 +5473,101 @@ state 358
variable goto 85
variable_substitution goto 86
-state 359
- fields: field ',' fields. (167)
+state 367
+ fields: field ',' fields. (180)
- . reduce 167 (src line 962)
+ . reduce 180 (src line 1032)
-state 360
- field: field_object AS identifier. (148)
+state 368
+ field: field_object AS identifier. (163)
- . reduce 148 (src line 866)
+ . reduce 163 (src line 946)
-state 361
- order_items: order_item ',' order_items. (159)
+state 369
+ function: identifier '(' option.')'
+ analytic_function: identifier '(' option.')' OVER '(' analytic_clause ')'
- . reduce 159 (src line 922)
+ ')' shift 419
+ . error
-state 362
+state 370
+ limit_clause: LIMIT value PERCENT limit_with. (60)
+
+ . reduce 60 (src line 457)
+
+
+state 371
+ limit_with: WITH TIES. (62)
+
+ . reduce 62 (src line 467)
+
+
+state 372
+ order_items: order_item ',' order_items. (90)
+
+ . reduce 90 (src line 593)
+
+
+state 373
+ order_item: order_value order_direction NULLS.order_null_position
+
+ FIRST shift 421
+ LAST shift 422
+ . error
+
+ order_null_position goto 420
+
+state 374
row_values: row_value ','.row_values
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 296
- row_values goto 407
- subquery goto 264
+ row_value goto 304
+ row_values goto 423
+ subquery goto 268
-state 363
+state 375
insert_query: INSERT INTO identifier '(' field_references ')'.VALUES row_values
insert_query: INSERT INTO identifier '(' field_references ')'.select_query
SELECT shift 39
- VALUES shift 408
+ VALUES shift 424
'(' shift 42
. error
- select_query goto 409
+ select_query goto 425
select_entity goto 16
select_set_entity goto 37
select_clause goto 36
subquery goto 40
-state 364
+state 376
field_references: field_reference ','.field_references
IDENTIFIER shift 59
. error
- field_reference goto 298
- field_references goto 410
- identifier goto 212
+ field_reference goto 306
+ field_references goto 426
+ identifier goto 216
-state 365
- update_query: UPDATE identified_tables SET update_set_list from_clause where_clause. (174)
+state 377
+ update_query: UPDATE identified_tables SET update_set_list from_clause where_clause. (187)
- . reduce 174 (src line 995)
+ . reduce 187 (src line 1065)
-state 366
- update_set_list: update_set ',' update_set_list. (177)
+state 378
+ update_set_list: update_set ',' update_set_list. (190)
- . reduce 177 (src line 1012)
+ . reduce 190 (src line 1082)
-state 367
+state 379
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -5338,15 +5585,15 @@ state 367
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- update_set: field_reference '=' value. (175)
- negation: . (222)
+ update_set: field_reference '=' value. (188)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -5356,48 +5603,48 @@ state 367
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 175 (src line 1001)
+ . reduce 188 (src line 1071)
negation goto 155
comparison_operator goto 156
- 368: reduce/reduce conflict (red'ns 224 and 142) on JOIN
-368: shift/reduce conflict (shift 221(0), red'n 142(0)) on INNER
-368: shift/reduce conflict (shift 222(0), red'n 142(0)) on LEFT
-368: shift/reduce conflict (shift 223(0), red'n 142(0)) on RIGHT
-368: shift/reduce conflict (shift 224(0), red'n 142(0)) on FULL
-368: shift/reduce conflict (shift 219(0), red'n 142(0)) on CROSS
-368: shift/reduce conflict (shift 412(0), red'n 142(0)) on ON
-368: shift/reduce conflict (shift 413(0), red'n 142(0)) on USING
-368: shift/reduce conflict (shift 217(0), red'n 142(0)) on NATURAL
- 368: reduce/reduce conflict (red'ns 142 and 228) on JOIN
- 368: reduce/reduce conflict (red'ns 142 and 228) on OUTER
-state 368
+ 380: reduce/reduce conflict (red'ns 237 and 156) on JOIN
+380: shift/reduce conflict (shift 225(0), red'n 156(0)) on INNER
+380: shift/reduce conflict (shift 226(0), red'n 156(0)) on LEFT
+380: shift/reduce conflict (shift 227(0), red'n 156(0)) on RIGHT
+380: shift/reduce conflict (shift 228(0), red'n 156(0)) on FULL
+380: shift/reduce conflict (shift 223(0), red'n 156(0)) on CROSS
+380: shift/reduce conflict (shift 428(0), red'n 156(0)) on ON
+380: shift/reduce conflict (shift 429(0), red'n 156(0)) on USING
+380: shift/reduce conflict (shift 221(0), red'n 156(0)) on NATURAL
+ 380: reduce/reduce conflict (red'ns 156 and 241) on JOIN
+ 380: reduce/reduce conflict (red'ns 156 and 241) on OUTER
+state 380
join: table.join_inner JOIN table join_condition
join: table join_inner JOIN table.join_condition
join: table.NATURAL join_inner JOIN table
join: table.join_direction join_outer JOIN table join_condition
join: table.NATURAL join_direction join_outer JOIN table
join: table.CROSS JOIN table
- join_inner: . (224)
- join_condition: . (142)
- join_direction: . (228)
-
- INNER shift 221
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- CROSS shift 219
- ON shift 412
- USING shift 413
- NATURAL shift 217
- . reduce 142 (src line 837)
-
- join_condition goto 411
- join_inner goto 216
- join_direction goto 218
+ join_inner: . (237)
+ join_condition: . (156)
+ join_direction: . (241)
+
+ INNER shift 225
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ CROSS shift 223
+ ON shift 428
+ USING shift 429
+ NATURAL shift 221
+ . reduce 156 (src line 913)
+
+ join_condition goto 427
+ join_inner goto 220
+ join_direction goto 222
-state 369
+state 381
join: table NATURAL join_inner JOIN.table
IDENTIFIER shift 59
@@ -5409,18 +5656,18 @@ state 369
subquery goto 137
identified_table goto 133
virtual_table goto 134
- table goto 414
+ table goto 430
join goto 135
identifier goto 58
-state 370
+state 382
join: table NATURAL join_direction join_outer.JOIN table
- JOIN shift 415
+ JOIN shift 431
. error
-state 371
+state 383
join: table join_direction join_outer JOIN.table join_condition
IDENTIFIER shift 59
@@ -5432,107 +5679,107 @@ state 371
subquery goto 137
identified_table goto 133
virtual_table goto 134
- table goto 416
+ table goto 432
join goto 135
identifier goto 58
-372: shift/reduce conflict (shift 221(0), red'n 141(0)) on INNER
-372: shift/reduce conflict (shift 222(0), red'n 141(0)) on LEFT
-372: shift/reduce conflict (shift 223(0), red'n 141(0)) on RIGHT
-372: shift/reduce conflict (shift 224(0), red'n 141(0)) on FULL
-372: shift/reduce conflict (shift 219(0), red'n 141(0)) on CROSS
-372: shift/reduce conflict (shift 217(0), red'n 141(0)) on NATURAL
- 372: reduce/reduce conflict (red'ns 141 and 224) on JOIN
- 372: reduce/reduce conflict (red'ns 141 and 228) on JOIN
- 372: reduce/reduce conflict (red'ns 141 and 228) on OUTER
-state 372
+384: shift/reduce conflict (shift 225(0), red'n 155(0)) on INNER
+384: shift/reduce conflict (shift 226(0), red'n 155(0)) on LEFT
+384: shift/reduce conflict (shift 227(0), red'n 155(0)) on RIGHT
+384: shift/reduce conflict (shift 228(0), red'n 155(0)) on FULL
+384: shift/reduce conflict (shift 223(0), red'n 155(0)) on CROSS
+384: shift/reduce conflict (shift 221(0), red'n 155(0)) on NATURAL
+ 384: reduce/reduce conflict (red'ns 155 and 237) on JOIN
+ 384: reduce/reduce conflict (red'ns 155 and 241) on JOIN
+ 384: reduce/reduce conflict (red'ns 155 and 241) on OUTER
+state 384
join: table.join_inner JOIN table join_condition
join: table.NATURAL join_inner JOIN table
join: table.join_direction join_outer JOIN table join_condition
join: table.NATURAL join_direction join_outer JOIN table
join: table.CROSS JOIN table
- join: table CROSS JOIN table. (141)
- join_inner: . (224)
- join_direction: . (228)
+ join: table CROSS JOIN table. (155)
+ join_inner: . (237)
+ join_direction: . (241)
- INNER shift 221
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- CROSS shift 219
- NATURAL shift 217
- . reduce 141 (src line 832)
+ INNER shift 225
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ CROSS shift 223
+ NATURAL shift 221
+ . reduce 155 (src line 908)
- join_inner goto 216
- join_direction goto 218
+ join_inner goto 220
+ join_direction goto 222
-state 373
- create_table: CREATE TABLE identifier '(' using_fields ')'. (180)
+state 385
+ create_table: CREATE TABLE identifier '(' using_fields ')'. (193)
- . reduce 180 (src line 1029)
+ . reduce 193 (src line 1099)
-state 374
+state 386
using_fields: identifier ','.using_fields
IDENTIFIER shift 59
. error
- using_fields goto 417
- identifier goto 312
+ using_fields goto 433
+ identifier goto 320
-state 375
- add_columns: ALTER TABLE identifier ADD column_default column_position. (181)
+state 387
+ add_columns: ALTER TABLE identifier ADD column_default column_position. (194)
- . reduce 181 (src line 1035)
+ . reduce 194 (src line 1105)
-state 376
- column_position: FIRST. (188)
+state 388
+ column_position: FIRST. (201)
- . reduce 188 (src line 1070)
+ . reduce 201 (src line 1140)
-state 377
- column_position: LAST. (189)
+state 389
+ column_position: LAST. (202)
- . reduce 189 (src line 1074)
+ . reduce 202 (src line 1144)
-state 378
+state 390
column_position: AFTER.field_reference
IDENTIFIER shift 59
. error
- field_reference goto 418
- identifier goto 212
+ field_reference goto 434
+ identifier goto 216
-state 379
+state 391
column_position: BEFORE.field_reference
IDENTIFIER shift 59
. error
- field_reference goto 419
- identifier goto 212
+ field_reference goto 435
+ identifier goto 216
-state 380
+state 392
add_columns: ALTER TABLE identifier ADD '(' column_defaults.')' column_position
- ')' shift 420
+ ')' shift 436
. error
-state 381
- column_defaults: column_default. (185)
+state 393
+ column_defaults: column_default. (198)
column_defaults: column_default.',' column_defaults
- ',' shift 421
- . reduce 185 (src line 1055)
+ ',' shift 437
+ . reduce 198 (src line 1125)
-state 382
+state 394
column_default: identifier DEFAULT.value
IDENTIFIER shift 59
@@ -5553,7 +5800,7 @@ state 382
primary goto 77
field_reference goto 76
- value goto 422
+ value goto 438
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -5573,58 +5820,58 @@ state 382
variable goto 85
variable_substitution goto 86
-state 383
+state 395
drop_columns: ALTER TABLE identifier DROP '(' field_references.')'
- ')' shift 423
+ ')' shift 439
. error
-state 384
+state 396
rename_column: ALTER TABLE identifier RENAME field_reference TO.identifier
IDENTIFIER shift 59
. error
- identifier goto 424
+ identifier goto 440
-state 385
+state 397
cursor_statement: DECLARE identifier CURSOR FOR select_query statement_terminal. (24)
- . reduce 24 (src line 254)
+ . reduce 24 (src line 260)
-state 386
+state 398
flow_control_statement: IF value THEN program else END.IF statement_terminal
- IF shift 425
+ IF shift 441
. error
-state 387
+state 399
flow_control_statement: IF value THEN program elseif else.END IF statement_terminal
- END shift 426
+ END shift 442
. error
-388: shift/reduce conflict (shift 324(0), red'n 196(0)) on ELSEIF
-state 388
+400: shift/reduce conflict (shift 332(0), red'n 209(0)) on ELSEIF
+state 400
elseif: elseif.elseif
- elseif: elseif elseif. (196)
+ elseif: elseif elseif. (209)
- ELSEIF shift 324
- . reduce 196 (src line 1108)
+ ELSEIF shift 332
+ . reduce 209 (src line 1178)
- elseif goto 388
+ elseif goto 400
-state 389
- else: ELSE program. (198)
+state 401
+ else: ELSE program. (211)
- . reduce 198 (src line 1118)
+ . reduce 211 (src line 1188)
-state 390
+state 402
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -5643,13 +5890,13 @@ state 390
logic: value.OR value
logic: value.AND value
elseif: ELSEIF value.THEN program
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- THEN shift 427
+ THEN shift 443
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -5658,12 +5905,12 @@ state 390
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 391
+state 403
comparison: value negation BETWEEN value AND.value
logic: value AND.value
@@ -5685,7 +5932,7 @@ state 391
primary goto 77
field_reference goto 76
- value goto 428
+ value goto 444
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -5705,13 +5952,13 @@ state 391
variable goto 85
variable_substitution goto 86
-state 392
- case: CASE case_value case_when case_else END. (149)
+state 404
+ case: CASE case_value case_when case_else END. (164)
- . reduce 149 (src line 871)
+ . reduce 164 (src line 951)
-state 393
+state 405
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -5729,14 +5976,14 @@ state 393
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- case_else: ELSE value. (153)
- negation: . (222)
+ case_else: ELSE value. (168)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- END reduce 153 (src line 892)
+ END reduce 168 (src line 972)
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -5745,12 +5992,12 @@ state 393
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 394
+state 406
case_when: WHEN value THEN.value
IDENTIFIER shift 59
@@ -5771,7 +6018,7 @@ state 394
primary goto 77
field_reference goto 76
- value goto 429
+ value goto 445
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -5791,71 +6038,71 @@ state 394
variable goto 85
variable_substitution goto 86
-state 395
+state 407
comparison: row_value negation BETWEEN row_value AND.row_value
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 430
- subquery goto 264
+ row_value goto 446
+ subquery goto 268
-state 396
+state 408
comparison: row_value negation IN '(' row_values.')'
- ')' shift 431
+ ')' shift 447
. error
-state 397
+state 409
select_set_entity: subquery. (46)
- row_value: subquery. (83)
+ row_value: subquery. (86)
- ')' reduce 83 (src line 553)
- ',' reduce 83 (src line 553)
- . reduce 46 (src line 381)
+ ')' reduce 86 (src line 573)
+ ',' reduce 86 (src line 573)
+ . reduce 46 (src line 387)
-state 398
+state 410
comparison: row_value comparison_operator ANY '(' row_values.')'
- ')' shift 432
+ ')' shift 448
. error
-state 399
+state 411
comparison: row_value comparison_operator ALL '(' row_values.')'
- ')' shift 433
+ ')' shift 449
. error
-state 400
- group_concat: GROUP_CONCAT '(' option order_by_clause ')'. (124)
+state 412
+ group_concat: GROUP_CONCAT '(' option order_by_clause ')'. (134)
- . reduce 124 (src line 755)
+ . reduce 134 (src line 809)
-state 401
+state 413
group_concat: GROUP_CONCAT '(' option order_by_clause SEPARATOR.STRING ')'
- STRING shift 434
+ STRING shift 450
. error
-state 402
+state 414
flow_control_statement: WHILE value DO in_loop_program END WHILE.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 435
+ statement_terminal goto 451
- 403: reduce/reduce conflict (red'ns 1 and 3) on ELSEIF
- 403: reduce/reduce conflict (red'ns 1 and 3) on ELSE
- 403: reduce/reduce conflict (red'ns 1 and 3) on END
-state 403
+ 415: reduce/reduce conflict (red'ns 1 and 3) on ELSEIF
+ 415: reduce/reduce conflict (red'ns 1 and 3) on ELSE
+ 415: reduce/reduce conflict (red'ns 1 and 3) on END
+state 415
flow_control_statement: IF value THEN.program else END IF statement_terminal
flow_control_statement: IF value THEN.program elseif else END IF statement_terminal
in_loop_flow_control_statement: IF value THEN.in_loop_program in_loop_else END IF statement_terminal
@@ -5871,7 +6118,7 @@ state 403
INSERT shift 17
CREATE shift 20
ALTER shift 21
- IF shift 275
+ IF shift 279
WHILE shift 32
DECLARE shift 26
FETCH shift 30
@@ -5880,23 +6127,23 @@ state 403
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE shift 276
- BREAK shift 277
+ CONTINUE shift 280
+ BREAK shift 281
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
- program goto 237
- in_loop_program goto 436
- statement goto 437
- in_loop_statement goto 272
+ program goto 241
+ in_loop_program goto 452
+ statement goto 453
+ in_loop_statement goto 276
variable_statement goto 11
transaction_statement goto 12
cursor_statement goto 13
flow_control_statement goto 14
- in_loop_flow_control_statement goto 274
+ in_loop_flow_control_statement goto 278
command_statement goto 15
select_query goto 3
select_entity goto 16
@@ -5913,14 +6160,14 @@ state 403
variable goto 38
variable_substitution goto 23
-state 404
+state 416
flow_control_statement: WHILE variables IN identifier DO in_loop_program.END WHILE statement_terminal
- END shift 438
+ END shift 454
. error
-state 405
+state 417
having_clause: HAVING value. (55)
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
@@ -5939,14 +6186,14 @@ state 405
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- negation: . (222)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -5956,52 +6203,78 @@ state 405
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 55 (src line 427)
+ . reduce 55 (src line 433)
negation goto 155
comparison_operator goto 156
-state 406
+state 418
group_by_clause: GROUP BY values. (53)
- . reduce 53 (src line 417)
+ . reduce 53 (src line 423)
-state 407
- row_values: row_value ',' row_values. (85)
+state 419
+ function: identifier '(' option ')'. (129)
+ analytic_function: identifier '(' option ')'.OVER '(' analytic_clause ')'
- . reduce 85 (src line 563)
+ OVER shift 455
+ . reduce 129 (src line 785)
-state 408
+state 420
+ order_item: order_value order_direction NULLS order_null_position. (92)
+
+ . reduce 92 (src line 603)
+
+
+state 421
+ order_null_position: FIRST. (98)
+
+ . reduce 98 (src line 632)
+
+
+state 422
+ order_null_position: LAST. (99)
+
+ . reduce 99 (src line 637)
+
+
+state 423
+ row_values: row_value ',' row_values. (88)
+
+ . reduce 88 (src line 583)
+
+
+state 424
insert_query: INSERT INTO identifier '(' field_references ')' VALUES.row_values
- '(' shift 263
+ '(' shift 267
. error
- row_value goto 296
- row_values goto 439
- subquery goto 264
+ row_value goto 304
+ row_values goto 456
+ subquery goto 268
-state 409
- insert_query: INSERT INTO identifier '(' field_references ')' select_query. (173)
+state 425
+ insert_query: INSERT INTO identifier '(' field_references ')' select_query. (186)
- . reduce 173 (src line 990)
+ . reduce 186 (src line 1060)
-state 410
- field_references: field_reference ',' field_references. (155)
+state 426
+ field_references: field_reference ',' field_references. (170)
- . reduce 155 (src line 902)
+ . reduce 170 (src line 982)
-state 411
- join: table join_inner JOIN table join_condition. (137)
+state 427
+ join: table join_inner JOIN table join_condition. (151)
- . reduce 137 (src line 815)
+ . reduce 151 (src line 891)
-state 412
+state 428
join_condition: ON.value
IDENTIFIER shift 59
@@ -6022,7 +6295,7 @@ state 412
primary goto 77
field_reference goto 76
- value goto 440
+ value goto 457
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -6042,44 +6315,44 @@ state 412
variable goto 85
variable_substitution goto 86
-state 413
+state 429
join_condition: USING.'(' using_fields ')'
- '(' shift 441
+ '(' shift 458
. error
-414: shift/reduce conflict (shift 221(0), red'n 138(0)) on INNER
-414: shift/reduce conflict (shift 222(0), red'n 138(0)) on LEFT
-414: shift/reduce conflict (shift 223(0), red'n 138(0)) on RIGHT
-414: shift/reduce conflict (shift 224(0), red'n 138(0)) on FULL
-414: shift/reduce conflict (shift 219(0), red'n 138(0)) on CROSS
-414: shift/reduce conflict (shift 217(0), red'n 138(0)) on NATURAL
- 414: reduce/reduce conflict (red'ns 138 and 224) on JOIN
- 414: reduce/reduce conflict (red'ns 138 and 228) on JOIN
- 414: reduce/reduce conflict (red'ns 138 and 228) on OUTER
-state 414
+430: shift/reduce conflict (shift 225(0), red'n 152(0)) on INNER
+430: shift/reduce conflict (shift 226(0), red'n 152(0)) on LEFT
+430: shift/reduce conflict (shift 227(0), red'n 152(0)) on RIGHT
+430: shift/reduce conflict (shift 228(0), red'n 152(0)) on FULL
+430: shift/reduce conflict (shift 223(0), red'n 152(0)) on CROSS
+430: shift/reduce conflict (shift 221(0), red'n 152(0)) on NATURAL
+ 430: reduce/reduce conflict (red'ns 152 and 237) on JOIN
+ 430: reduce/reduce conflict (red'ns 152 and 241) on JOIN
+ 430: reduce/reduce conflict (red'ns 152 and 241) on OUTER
+state 430
join: table.join_inner JOIN table join_condition
join: table.NATURAL join_inner JOIN table
- join: table NATURAL join_inner JOIN table. (138)
+ join: table NATURAL join_inner JOIN table. (152)
join: table.join_direction join_outer JOIN table join_condition
join: table.NATURAL join_direction join_outer JOIN table
join: table.CROSS JOIN table
- join_inner: . (224)
- join_direction: . (228)
+ join_inner: . (237)
+ join_direction: . (241)
- INNER shift 221
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- CROSS shift 219
- NATURAL shift 217
- . reduce 138 (src line 820)
+ INNER shift 225
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ CROSS shift 223
+ NATURAL shift 221
+ . reduce 152 (src line 896)
- join_inner goto 216
- join_direction goto 218
+ join_inner goto 220
+ join_direction goto 222
-state 415
+state 431
join: table NATURAL join_direction join_outer JOIN.table
IDENTIFIER shift 59
@@ -6091,87 +6364,87 @@ state 415
subquery goto 137
identified_table goto 133
virtual_table goto 134
- table goto 442
+ table goto 459
join goto 135
identifier goto 58
- 416: reduce/reduce conflict (red'ns 224 and 228) on JOIN
- 416: reduce/reduce conflict (red'ns 224 and 142) on JOIN
-416: shift/reduce conflict (shift 221(0), red'n 142(0)) on INNER
- 416: reduce/reduce conflict (red'ns 228 and 142) on OUTER
-416: shift/reduce conflict (shift 222(0), red'n 142(0)) on LEFT
-416: shift/reduce conflict (shift 223(0), red'n 142(0)) on RIGHT
-416: shift/reduce conflict (shift 224(0), red'n 142(0)) on FULL
-416: shift/reduce conflict (shift 219(0), red'n 142(0)) on CROSS
-416: shift/reduce conflict (shift 412(0), red'n 142(0)) on ON
-416: shift/reduce conflict (shift 413(0), red'n 142(0)) on USING
-416: shift/reduce conflict (shift 217(0), red'n 142(0)) on NATURAL
-state 416
+ 432: reduce/reduce conflict (red'ns 237 and 241) on JOIN
+ 432: reduce/reduce conflict (red'ns 237 and 156) on JOIN
+432: shift/reduce conflict (shift 225(0), red'n 156(0)) on INNER
+ 432: reduce/reduce conflict (red'ns 241 and 156) on OUTER
+432: shift/reduce conflict (shift 226(0), red'n 156(0)) on LEFT
+432: shift/reduce conflict (shift 227(0), red'n 156(0)) on RIGHT
+432: shift/reduce conflict (shift 228(0), red'n 156(0)) on FULL
+432: shift/reduce conflict (shift 223(0), red'n 156(0)) on CROSS
+432: shift/reduce conflict (shift 428(0), red'n 156(0)) on ON
+432: shift/reduce conflict (shift 429(0), red'n 156(0)) on USING
+432: shift/reduce conflict (shift 221(0), red'n 156(0)) on NATURAL
+state 432
join: table.join_inner JOIN table join_condition
join: table.NATURAL join_inner JOIN table
join: table.join_direction join_outer JOIN table join_condition
join: table join_direction join_outer JOIN table.join_condition
join: table.NATURAL join_direction join_outer JOIN table
join: table.CROSS JOIN table
- join_inner: . (224)
- join_direction: . (228)
- join_condition: . (142)
-
- INNER shift 221
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- CROSS shift 219
- ON shift 412
- USING shift 413
- NATURAL shift 217
- . reduce 142 (src line 837)
-
- join_condition goto 443
- join_inner goto 216
- join_direction goto 218
+ join_inner: . (237)
+ join_direction: . (241)
+ join_condition: . (156)
+
+ INNER shift 225
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ CROSS shift 223
+ ON shift 428
+ USING shift 429
+ NATURAL shift 221
+ . reduce 156 (src line 913)
+
+ join_condition goto 460
+ join_inner goto 220
+ join_direction goto 222
-state 417
- using_fields: identifier ',' using_fields. (165)
+state 433
+ using_fields: identifier ',' using_fields. (178)
- . reduce 165 (src line 952)
+ . reduce 178 (src line 1022)
-state 418
- column_position: AFTER field_reference. (190)
+state 434
+ column_position: AFTER field_reference. (203)
- . reduce 190 (src line 1078)
+ . reduce 203 (src line 1148)
-state 419
- column_position: BEFORE field_reference. (191)
+state 435
+ column_position: BEFORE field_reference. (204)
- . reduce 191 (src line 1082)
+ . reduce 204 (src line 1152)
-state 420
+state 436
add_columns: ALTER TABLE identifier ADD '(' column_defaults ')'.column_position
- column_position: . (187)
+ column_position: . (200)
- FIRST shift 376
- LAST shift 377
- AFTER shift 378
- BEFORE shift 379
- . reduce 187 (src line 1065)
+ FIRST shift 388
+ LAST shift 389
+ AFTER shift 390
+ BEFORE shift 391
+ . reduce 200 (src line 1135)
- column_position goto 444
+ column_position goto 461
-state 421
+state 437
column_defaults: column_default ','.column_defaults
IDENTIFIER shift 59
. error
- column_default goto 381
- column_defaults goto 445
- identifier goto 315
+ column_default goto 393
+ column_defaults goto 462
+ identifier goto 323
-state 422
+state 438
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -6189,15 +6462,15 @@ state 422
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- column_default: identifier DEFAULT value. (184)
- negation: . (222)
+ column_default: identifier DEFAULT value. (197)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -6207,40 +6480,40 @@ state 422
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 184 (src line 1050)
+ . reduce 197 (src line 1120)
negation goto 155
comparison_operator goto 156
-state 423
- drop_columns: ALTER TABLE identifier DROP '(' field_references ')'. (193)
+state 439
+ drop_columns: ALTER TABLE identifier DROP '(' field_references ')'. (206)
- . reduce 193 (src line 1092)
+ . reduce 206 (src line 1162)
-state 424
- rename_column: ALTER TABLE identifier RENAME field_reference TO identifier. (194)
+state 440
+ rename_column: ALTER TABLE identifier RENAME field_reference TO identifier. (207)
- . reduce 194 (src line 1097)
+ . reduce 207 (src line 1167)
-state 425
+state 441
flow_control_statement: IF value THEN program else END IF.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 446
+ statement_terminal goto 463
-state 426
+state 442
flow_control_statement: IF value THEN program elseif else END.IF statement_terminal
- IF shift 447
+ IF shift 464
. error
-state 427
+state 443
elseif: ELSEIF value THEN.program
program: . (1)
@@ -6265,9 +6538,9 @@ state 427
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
- program goto 448
+ program goto 465
statement goto 2
variable_statement goto 11
transaction_statement goto 12
@@ -6289,22 +6562,22 @@ state 427
variable goto 38
variable_substitution goto 23
- 428: reduce/reduce conflict (red'ns 98 and 117) on IN
- 428: reduce/reduce conflict (red'ns 98 and 117) on AND
- 428: reduce/reduce conflict (red'ns 98 and 117) on OR
- 428: reduce/reduce conflict (red'ns 98 and 117) on BETWEEN
- 428: reduce/reduce conflict (red'ns 98 and 117) on LIKE
- 428: reduce/reduce conflict (red'ns 98 and 222) on IN
- 428: reduce/reduce conflict (red'ns 98 and 222) on BETWEEN
- 428: reduce/reduce conflict (red'ns 98 and 222) on LIKE
-state 428
+ 444: reduce/reduce conflict (red'ns 108 and 127) on IN
+ 444: reduce/reduce conflict (red'ns 108 and 127) on AND
+ 444: reduce/reduce conflict (red'ns 108 and 127) on OR
+ 444: reduce/reduce conflict (red'ns 108 and 127) on BETWEEN
+ 444: reduce/reduce conflict (red'ns 108 and 127) on LIKE
+ 444: reduce/reduce conflict (red'ns 108 and 235) on IN
+ 444: reduce/reduce conflict (red'ns 108 and 235) on BETWEEN
+ 444: reduce/reduce conflict (red'ns 108 and 235) on LIKE
+state 444
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
comparison: value.IS negation ternary
comparison: value.IS negation null
comparison: value.negation BETWEEN value AND value
- comparison: value negation BETWEEN value AND value. (98)
+ comparison: value negation BETWEEN value AND value. (108)
comparison: value.negation IN row_value
comparison: value.negation LIKE value
comparison: value.comparison_operator ANY row_value
@@ -6316,8 +6589,8 @@ state 428
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- logic: value AND value. (117)
- negation: . (222)
+ logic: value AND value. (127)
+ negation: . (235)
NOT shift 164
IS shift 154
@@ -6329,12 +6602,12 @@ state 428
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 98 (src line 642)
+ . reduce 108 (src line 696)
negation goto 155
comparison_operator goto 156
-state 429
+state 445
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -6352,16 +6625,16 @@ state 429
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- case_when: WHEN value THEN value. (168)
- negation: . (222)
+ case_when: WHEN value THEN value. (181)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- WHEN reduce 168 (src line 967)
- ELSE reduce 168 (src line 967)
- END reduce 168 (src line 967)
+ WHEN reduce 181 (src line 1037)
+ ELSE reduce 181 (src line 1037)
+ END reduce 181 (src line 1037)
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -6370,85 +6643,85 @@ state 429
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 430
- comparison: row_value negation BETWEEN row_value AND row_value. (99)
+state 446
+ comparison: row_value negation BETWEEN row_value AND row_value. (109)
- . reduce 99 (src line 646)
+ . reduce 109 (src line 700)
-state 431
- comparison: row_value negation IN '(' row_values ')'. (101)
+state 447
+ comparison: row_value negation IN '(' row_values ')'. (111)
- . reduce 101 (src line 654)
+ . reduce 111 (src line 708)
-state 432
- comparison: row_value comparison_operator ANY '(' row_values ')'. (105)
+state 448
+ comparison: row_value comparison_operator ANY '(' row_values ')'. (115)
- . reduce 105 (src line 670)
+ . reduce 115 (src line 724)
-state 433
- comparison: row_value comparison_operator ALL '(' row_values ')'. (108)
+state 449
+ comparison: row_value comparison_operator ALL '(' row_values ')'. (118)
- . reduce 108 (src line 682)
+ . reduce 118 (src line 736)
-state 434
+state 450
group_concat: GROUP_CONCAT '(' option order_by_clause SEPARATOR STRING.')'
- ')' shift 449
+ ')' shift 466
. error
-state 435
+state 451
flow_control_statement: WHILE value DO in_loop_program END WHILE statement_terminal. (31)
- . reduce 31 (src line 285)
+ . reduce 31 (src line 291)
-state 436
+state 452
in_loop_flow_control_statement: IF value THEN in_loop_program.in_loop_else END IF statement_terminal
in_loop_flow_control_statement: IF value THEN in_loop_program.in_loop_elseif in_loop_else END IF statement_terminal
- in_loop_else: . (201)
-
- ELSEIF shift 453
- ELSE shift 452
- . reduce 201 (src line 1133)
-
- in_loop_elseif goto 451
- in_loop_else goto 450
-
-437: shift/reduce conflict (shift 41(0), red'n 18(0)) on VARIABLE
-437: shift/reduce conflict (shift 39(0), red'n 18(0)) on SELECT
-437: shift/reduce conflict (shift 18(0), red'n 18(0)) on UPDATE
-437: shift/reduce conflict (shift 34(0), red'n 18(0)) on SET
-437: shift/reduce conflict (shift 19(0), red'n 18(0)) on DELETE
-437: shift/reduce conflict (shift 17(0), red'n 18(0)) on INSERT
-437: shift/reduce conflict (shift 20(0), red'n 18(0)) on CREATE
-437: shift/reduce conflict (shift 21(0), red'n 18(0)) on ALTER
-437: shift/reduce conflict (shift 31(0), red'n 18(0)) on IF
-437: shift/reduce conflict (shift 32(0), red'n 18(0)) on WHILE
-437: shift/reduce conflict (shift 26(0), red'n 18(0)) on DECLARE
-437: shift/reduce conflict (shift 30(0), red'n 18(0)) on FETCH
-437: shift/reduce conflict (shift 27(0), red'n 18(0)) on OPEN
-437: shift/reduce conflict (shift 28(0), red'n 18(0)) on CLOSE
-437: shift/reduce conflict (shift 29(0), red'n 18(0)) on DISPOSE
-437: shift/reduce conflict (shift 24(0), red'n 18(0)) on COMMIT
-437: shift/reduce conflict (shift 25(0), red'n 18(0)) on ROLLBACK
-437: shift/reduce conflict (shift 33(0), red'n 18(0)) on EXIT
-437: shift/reduce conflict (shift 35(0), red'n 18(0)) on PRINT
-437: shift/reduce conflict (shift 22(0), red'n 18(0)) on VAR
-437: shift/reduce conflict (shift 42(0), red'n 18(0)) on '('
- 437: reduce/reduce conflict (red'ns 18 and 1) on ELSEIF
- 437: reduce/reduce conflict (red'ns 18 and 1) on ELSE
- 437: reduce/reduce conflict (red'ns 18 and 1) on END
-state 437
+ in_loop_else: . (214)
+
+ ELSEIF shift 470
+ ELSE shift 469
+ . reduce 214 (src line 1203)
+
+ in_loop_elseif goto 468
+ in_loop_else goto 467
+
+453: shift/reduce conflict (shift 41(0), red'n 18(0)) on VARIABLE
+453: shift/reduce conflict (shift 39(0), red'n 18(0)) on SELECT
+453: shift/reduce conflict (shift 18(0), red'n 18(0)) on UPDATE
+453: shift/reduce conflict (shift 34(0), red'n 18(0)) on SET
+453: shift/reduce conflict (shift 19(0), red'n 18(0)) on DELETE
+453: shift/reduce conflict (shift 17(0), red'n 18(0)) on INSERT
+453: shift/reduce conflict (shift 20(0), red'n 18(0)) on CREATE
+453: shift/reduce conflict (shift 21(0), red'n 18(0)) on ALTER
+453: shift/reduce conflict (shift 31(0), red'n 18(0)) on IF
+453: shift/reduce conflict (shift 32(0), red'n 18(0)) on WHILE
+453: shift/reduce conflict (shift 26(0), red'n 18(0)) on DECLARE
+453: shift/reduce conflict (shift 30(0), red'n 18(0)) on FETCH
+453: shift/reduce conflict (shift 27(0), red'n 18(0)) on OPEN
+453: shift/reduce conflict (shift 28(0), red'n 18(0)) on CLOSE
+453: shift/reduce conflict (shift 29(0), red'n 18(0)) on DISPOSE
+453: shift/reduce conflict (shift 24(0), red'n 18(0)) on COMMIT
+453: shift/reduce conflict (shift 25(0), red'n 18(0)) on ROLLBACK
+453: shift/reduce conflict (shift 33(0), red'n 18(0)) on EXIT
+453: shift/reduce conflict (shift 35(0), red'n 18(0)) on PRINT
+453: shift/reduce conflict (shift 22(0), red'n 18(0)) on VAR
+453: shift/reduce conflict (shift 42(0), red'n 18(0)) on '('
+ 453: reduce/reduce conflict (red'ns 18 and 1) on ELSEIF
+ 453: reduce/reduce conflict (red'ns 18 and 1) on ELSE
+ 453: reduce/reduce conflict (red'ns 18 and 1) on END
+state 453
program: statement.program
in_loop_statement: statement. (18)
program: . (1)
@@ -6470,13 +6743,13 @@ state 437
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE reduce 18 (src line 224)
- BREAK reduce 18 (src line 224)
+ CONTINUE reduce 18 (src line 230)
+ BREAK reduce 18 (src line 230)
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 1 (src line 146)
+ . reduce 1 (src line 152)
program goto 43
statement goto 2
@@ -6500,20 +6773,27 @@ state 437
variable goto 38
variable_substitution goto 23
-state 438
+state 454
flow_control_statement: WHILE variables IN identifier DO in_loop_program END.WHILE statement_terminal
- WHILE shift 454
+ WHILE shift 471
. error
-state 439
- insert_query: INSERT INTO identifier '(' field_references ')' VALUES row_values. (171)
+state 455
+ analytic_function: identifier '(' option ')' OVER.'(' analytic_clause ')'
+
+ '(' shift 472
+ . error
- . reduce 171 (src line 982)
+state 456
+ insert_query: INSERT INTO identifier '(' field_references ')' VALUES row_values. (184)
-state 440
+ . reduce 184 (src line 1052)
+
+
+state 457
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -6531,15 +6811,15 @@ state 440
arithmetic: value.'%' value
logic: value.OR value
logic: value.AND value
- join_condition: ON value. (143)
- negation: . (222)
+ join_condition: ON value. (157)
+ negation: . (235)
- IN reduce 222 (src line 1247)
+ IN reduce 235 (src line 1317)
AND shift 163
OR shift 162
NOT shift 164
- BETWEEN reduce 222 (src line 1247)
- LIKE reduce 222 (src line 1247)
+ BETWEEN reduce 235 (src line 1317)
+ LIKE reduce 235 (src line 1317)
IS shift 154
COMPARISON_OP shift 152
STRING_OP shift 151
@@ -6549,115 +6829,115 @@ state 440
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 143 (src line 842)
+ . reduce 157 (src line 918)
negation goto 155
comparison_operator goto 156
-state 441
+state 458
join_condition: USING '('.using_fields ')'
IDENTIFIER shift 59
. error
- using_fields goto 455
- identifier goto 312
+ using_fields goto 473
+ identifier goto 320
-442: shift/reduce conflict (shift 221(0), red'n 140(0)) on INNER
-442: shift/reduce conflict (shift 222(0), red'n 140(0)) on LEFT
-442: shift/reduce conflict (shift 223(0), red'n 140(0)) on RIGHT
-442: shift/reduce conflict (shift 224(0), red'n 140(0)) on FULL
-442: shift/reduce conflict (shift 219(0), red'n 140(0)) on CROSS
-442: shift/reduce conflict (shift 217(0), red'n 140(0)) on NATURAL
- 442: reduce/reduce conflict (red'ns 140 and 224) on JOIN
- 442: reduce/reduce conflict (red'ns 140 and 228) on JOIN
- 442: reduce/reduce conflict (red'ns 140 and 228) on OUTER
-state 442
+459: shift/reduce conflict (shift 225(0), red'n 154(0)) on INNER
+459: shift/reduce conflict (shift 226(0), red'n 154(0)) on LEFT
+459: shift/reduce conflict (shift 227(0), red'n 154(0)) on RIGHT
+459: shift/reduce conflict (shift 228(0), red'n 154(0)) on FULL
+459: shift/reduce conflict (shift 223(0), red'n 154(0)) on CROSS
+459: shift/reduce conflict (shift 221(0), red'n 154(0)) on NATURAL
+ 459: reduce/reduce conflict (red'ns 154 and 237) on JOIN
+ 459: reduce/reduce conflict (red'ns 154 and 241) on JOIN
+ 459: reduce/reduce conflict (red'ns 154 and 241) on OUTER
+state 459
join: table.join_inner JOIN table join_condition
join: table.NATURAL join_inner JOIN table
join: table.join_direction join_outer JOIN table join_condition
join: table.NATURAL join_direction join_outer JOIN table
- join: table NATURAL join_direction join_outer JOIN table. (140)
+ join: table NATURAL join_direction join_outer JOIN table. (154)
join: table.CROSS JOIN table
- join_inner: . (224)
- join_direction: . (228)
+ join_inner: . (237)
+ join_direction: . (241)
- INNER shift 221
- LEFT shift 222
- RIGHT shift 223
- FULL shift 224
- CROSS shift 219
- NATURAL shift 217
- . reduce 140 (src line 828)
+ INNER shift 225
+ LEFT shift 226
+ RIGHT shift 227
+ FULL shift 228
+ CROSS shift 223
+ NATURAL shift 221
+ . reduce 154 (src line 904)
- join_inner goto 216
- join_direction goto 218
+ join_inner goto 220
+ join_direction goto 222
-state 443
- join: table join_direction join_outer JOIN table join_condition. (139)
+state 460
+ join: table join_direction join_outer JOIN table join_condition. (153)
- . reduce 139 (src line 824)
+ . reduce 153 (src line 900)
-state 444
- add_columns: ALTER TABLE identifier ADD '(' column_defaults ')' column_position. (182)
+state 461
+ add_columns: ALTER TABLE identifier ADD '(' column_defaults ')' column_position. (195)
- . reduce 182 (src line 1040)
+ . reduce 195 (src line 1110)
-state 445
- column_defaults: column_default ',' column_defaults. (186)
+state 462
+ column_defaults: column_default ',' column_defaults. (199)
- . reduce 186 (src line 1060)
+ . reduce 199 (src line 1130)
-state 446
+state 463
flow_control_statement: IF value THEN program else END IF statement_terminal. (29)
- . reduce 29 (src line 276)
+ . reduce 29 (src line 282)
-state 447
+state 464
flow_control_statement: IF value THEN program elseif else END IF.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 456
+ statement_terminal goto 474
-state 448
- elseif: ELSEIF value THEN program. (195)
+state 465
+ elseif: ELSEIF value THEN program. (208)
- . reduce 195 (src line 1103)
+ . reduce 208 (src line 1173)
-state 449
- group_concat: GROUP_CONCAT '(' option order_by_clause SEPARATOR STRING ')'. (125)
+state 466
+ group_concat: GROUP_CONCAT '(' option order_by_clause SEPARATOR STRING ')'. (135)
- . reduce 125 (src line 760)
+ . reduce 135 (src line 814)
-state 450
+state 467
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_else.END IF statement_terminal
- END shift 457
+ END shift 475
. error
-state 451
+state 468
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_elseif.in_loop_else END IF statement_terminal
in_loop_elseif: in_loop_elseif.in_loop_elseif
- in_loop_else: . (201)
+ in_loop_else: . (214)
- ELSEIF shift 453
- ELSE shift 452
- . reduce 201 (src line 1133)
+ ELSEIF shift 470
+ ELSE shift 469
+ . reduce 214 (src line 1203)
- in_loop_elseif goto 459
- in_loop_else goto 458
+ in_loop_elseif goto 477
+ in_loop_else goto 476
-state 452
+state 469
in_loop_else: ELSE.in_loop_program
in_loop_program: . (3)
@@ -6669,7 +6949,7 @@ state 452
INSERT shift 17
CREATE shift 20
ALTER shift 21
- IF shift 275
+ IF shift 279
WHILE shift 32
DECLARE shift 26
FETCH shift 30
@@ -6678,22 +6958,22 @@ state 452
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE shift 276
- BREAK shift 277
+ CONTINUE shift 280
+ BREAK shift 281
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 3 (src line 158)
+ . reduce 3 (src line 164)
- in_loop_program goto 460
- statement goto 273
- in_loop_statement goto 272
+ in_loop_program goto 478
+ statement goto 277
+ in_loop_statement goto 276
variable_statement goto 11
transaction_statement goto 12
cursor_statement goto 13
flow_control_statement goto 14
- in_loop_flow_control_statement goto 274
+ in_loop_flow_control_statement goto 278
command_statement goto 15
select_query goto 3
select_entity goto 16
@@ -6710,7 +6990,7 @@ state 452
variable goto 38
variable_substitution goto 23
-state 453
+state 470
in_loop_elseif: ELSEIF.value THEN in_loop_program
IDENTIFIER shift 59
@@ -6731,7 +7011,7 @@ state 453
primary goto 77
field_reference goto 76
- value goto 461
+ value goto 479
row_value goto 97
subquery goto 80
string_operation goto 79
@@ -6751,59 +7031,69 @@ state 453
variable goto 85
variable_substitution goto 86
-state 454
+state 471
flow_control_statement: WHILE variables IN identifier DO in_loop_program END WHILE.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 462
+ statement_terminal goto 480
-state 455
+state 472
+ analytic_function: identifier '(' option ')' OVER '('.analytic_clause ')'
+ partition: . (138)
+
+ PARTITION shift 483
+ . reduce 138 (src line 831)
+
+ analytic_clause goto 481
+ partition goto 482
+
+state 473
join_condition: USING '(' using_fields.')'
- ')' shift 463
+ ')' shift 484
. error
-state 456
+state 474
flow_control_statement: IF value THEN program elseif else END IF statement_terminal. (30)
- . reduce 30 (src line 281)
+ . reduce 30 (src line 287)
-state 457
+state 475
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_else END.IF statement_terminal
- IF shift 464
+ IF shift 485
. error
-state 458
+state 476
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_elseif in_loop_else.END IF statement_terminal
- END shift 465
+ END shift 486
. error
-459: shift/reduce conflict (shift 453(0), red'n 200(0)) on ELSEIF
-state 459
+477: shift/reduce conflict (shift 470(0), red'n 213(0)) on ELSEIF
+state 477
in_loop_elseif: in_loop_elseif.in_loop_elseif
- in_loop_elseif: in_loop_elseif in_loop_elseif. (200)
+ in_loop_elseif: in_loop_elseif in_loop_elseif. (213)
- ELSEIF shift 453
- . reduce 200 (src line 1128)
+ ELSEIF shift 470
+ . reduce 213 (src line 1198)
- in_loop_elseif goto 459
+ in_loop_elseif goto 477
-state 460
- in_loop_else: ELSE in_loop_program. (202)
+state 478
+ in_loop_else: ELSE in_loop_program. (215)
- . reduce 202 (src line 1138)
+ . reduce 215 (src line 1208)
-state 461
+state 479
string_operation: value.STRING_OP value
comparison: value.COMPARISON_OP value
comparison: value.'=' value
@@ -6822,13 +7112,13 @@ state 461
logic: value.OR value
logic: value.AND value
in_loop_elseif: ELSEIF value.THEN in_loop_program
- negation: . (222)
+ negation: . (235)
AND shift 163
OR shift 162
NOT shift 164
IS shift 154
- THEN shift 466
+ THEN shift 487
COMPARISON_OP shift 152
STRING_OP shift 151
'=' shift 153
@@ -6837,40 +7127,63 @@ state 461
'*' shift 159
'/' shift 160
'%' shift 161
- . reduce 222 (src line 1247)
+ . reduce 235 (src line 1317)
negation goto 155
comparison_operator goto 156
-state 462
+state 480
flow_control_statement: WHILE variables IN identifier DO in_loop_program END WHILE statement_terminal. (32)
- . reduce 32 (src line 289)
+ . reduce 32 (src line 295)
-state 463
- join_condition: USING '(' using_fields ')'. (144)
+state 481
+ analytic_function: identifier '(' option ')' OVER '(' analytic_clause.')'
- . reduce 144 (src line 846)
+ ')' shift 488
+ . error
-state 464
+state 482
+ analytic_clause: partition.order_by_clause
+ order_by_clause: . (56)
+
+ ORDER shift 54
+ . reduce 56 (src line 438)
+
+ order_by_clause goto 489
+
+state 483
+ partition: PARTITION.BY values
+
+ BY shift 490
+ . error
+
+
+state 484
+ join_condition: USING '(' using_fields ')'. (158)
+
+ . reduce 158 (src line 922)
+
+
+state 485
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_else END IF.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 467
+ statement_terminal goto 491
-state 465
+state 486
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_elseif in_loop_else END.IF statement_terminal
- IF shift 468
+ IF shift 492
. error
-state 466
+state 487
in_loop_elseif: ELSEIF value THEN.in_loop_program
in_loop_program: . (3)
@@ -6882,7 +7195,7 @@ state 466
INSERT shift 17
CREATE shift 20
ALTER shift 21
- IF shift 275
+ IF shift 279
WHILE shift 32
DECLARE shift 26
FETCH shift 30
@@ -6891,22 +7204,22 @@ state 466
DISPOSE shift 29
COMMIT shift 24
ROLLBACK shift 25
- CONTINUE shift 276
- BREAK shift 277
+ CONTINUE shift 280
+ BREAK shift 281
EXIT shift 33
PRINT shift 35
VAR shift 22
'(' shift 42
- . reduce 3 (src line 158)
+ . reduce 3 (src line 164)
- in_loop_program goto 469
- statement goto 273
- in_loop_statement goto 272
+ in_loop_program goto 493
+ statement goto 277
+ in_loop_statement goto 276
variable_statement goto 11
transaction_statement goto 12
cursor_statement goto 13
flow_control_statement goto 14
- in_loop_flow_control_statement goto 274
+ in_loop_flow_control_statement goto 278
command_statement goto 15
select_query goto 3
select_entity goto 16
@@ -6923,42 +7236,102 @@ state 466
variable goto 38
variable_substitution goto 23
-state 467
+state 488
+ analytic_function: identifier '(' option ')' OVER '(' analytic_clause ')'. (136)
+
+ . reduce 136 (src line 819)
+
+
+state 489
+ analytic_clause: partition order_by_clause. (137)
+
+ . reduce 137 (src line 825)
+
+
+state 490
+ partition: PARTITION BY.values
+
+ IDENTIFIER shift 59
+ STRING shift 100
+ INTEGER shift 101
+ FLOAT shift 103
+ TERNARY shift 104
+ DATETIME shift 105
+ VARIABLE shift 41
+ EXISTS shift 98
+ NOT shift 99
+ NULL shift 106
+ CASE shift 96
+ GROUP_CONCAT shift 107
+ '-' shift 102
+ '(' shift 87
+ . error
+
+ primary goto 77
+ field_reference goto 76
+ value goto 341
+ row_value goto 97
+ subquery goto 80
+ string_operation goto 79
+ comparison goto 83
+ arithmetic goto 78
+ logic goto 84
+ function goto 81
+ group_concat goto 95
+ case goto 82
+ values goto 494
+ identifier goto 88
+ text goto 89
+ integer goto 90
+ float goto 91
+ ternary goto 92
+ datetime goto 93
+ null goto 94
+ variable goto 85
+ variable_substitution goto 86
+
+state 491
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_else END IF statement_terminal. (34)
- . reduce 34 (src line 298)
+ . reduce 34 (src line 304)
-state 468
+state 492
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_elseif in_loop_else END IF.statement_terminal
- statement_terminal: . (236)
+ statement_terminal: . (249)
';' shift 45
- . reduce 236 (src line 1315)
+ . reduce 249 (src line 1385)
- statement_terminal goto 470
+ statement_terminal goto 495
-state 469
- in_loop_elseif: ELSEIF value THEN in_loop_program. (199)
+state 493
+ in_loop_elseif: ELSEIF value THEN in_loop_program. (212)
- . reduce 199 (src line 1123)
+ . reduce 212 (src line 1193)
-state 470
+state 494
+ partition: PARTITION BY values. (139)
+
+ . reduce 139 (src line 836)
+
+
+state 495
in_loop_flow_control_statement: IF value THEN in_loop_program in_loop_elseif in_loop_else END IF statement_terminal. (35)
- . reduce 35 (src line 303)
-
-
-109 terminals, 91 nonterminals
-238 grammar rules, 471/8000 states
-72 shift/reduce, 81 reduce/reduce conflicts reported
-140 working sets used
-memory: parser 2161/120000
-560 extra closures
-1514 shift entries, 62 exceptions
-385 goto entries
-1127 entries saved by goto default
-Optimizer space used: output 1132/120000
-1132 table entries, 263 zero
-maximum spread: 109, maximum offset: 468
+ . reduce 35 (src line 309)
+
+
+114 terminals, 97 nonterminals
+251 grammar rules, 496/8000 states
+73 shift/reduce, 81 reduce/reduce conflicts reported
+146 working sets used
+memory: parser 2303/120000
+580 extra closures
+1595 shift entries, 69 exceptions
+403 goto entries
+1191 entries saved by goto default
+Optimizer space used: output 1142/120000
+1142 table entries, 242 zero
+maximum spread: 114, maximum offset: 492
diff --git a/lib/parser/parser.y b/lib/parser/parser.y
index f780ae70..0b825a09 100644
--- a/lib/parser/parser.y
+++ b/lib/parser/parser.y
@@ -42,13 +42,18 @@ package parser
%type having_clause
%type order_by_clause
%type limit_clause
+%type limit_with
%type offset_clause
%type primary
%type field_reference
%type value
%type row_value
%type row_values
+%type order_items
%type order_item
+%type order_value
+%type order_direction
+%type order_null_position
%type subquery
%type string_operation
%type comparison
@@ -57,6 +62,9 @@ package parser
%type function
%type option
%type group_concat
+%type analytic_function
+%type analytic_clause
+%type partition
%type identified_table
%type virtual_table
%type table
@@ -69,7 +77,6 @@ package parser
%type case_else
%type field_references
%type values
-%type order_items
%type tables
%type identified_tables
%type using_fields
@@ -105,7 +112,6 @@ package parser
%type variable_assignments
%type distinct
%type negation
-%type order_direction
%type join_inner
%type join_outer
%type join_direction
@@ -116,15 +122,15 @@ package parser
%token IDENTIFIER STRING INTEGER FLOAT BOOLEAN TERNARY DATETIME VARIABLE FLAG
%token SELECT FROM UPDATE SET DELETE WHERE INSERT INTO VALUES AS DUAL STDIN
%token CREATE ADD DROP ALTER TABLE FIRST LAST AFTER BEFORE DEFAULT RENAME TO
-%token ORDER GROUP HAVING BY ASC DESC LIMIT OFFSET
+%token ORDER GROUP HAVING BY ASC DESC LIMIT OFFSET TIES PERCENT
%token JOIN INNER OUTER LEFT RIGHT FULL CROSS ON USING NATURAL
%token UNION INTERSECT EXCEPT
%token ALL ANY EXISTS IN
-%token AND OR NOT BETWEEN LIKE IS NULL
+%token AND OR NOT BETWEEN LIKE IS NULL NULLS
%token DISTINCT WITH
%token CASE IF ELSEIF WHILE WHEN THEN ELSE DO END
%token DECLARE CURSOR FOR FETCH OPEN CLOSE DISPOSE
-%token GROUP_CONCAT SEPARATOR
+%token GROUP_CONCAT SEPARATOR PARTITION OVER
%token COMMIT ROLLBACK
%token CONTINUE BREAK EXIT
%token PRINT
@@ -444,9 +450,23 @@ limit_clause
{
$$ = nil
}
- | LIMIT INTEGER
+ | LIMIT value limit_with
{
- $$ = LimitClause{Limit: $1.Literal, Number: StrToInt64($2.Literal)}
+ $$ = LimitClause{Limit: $1.Literal, Value: $2, With: $3}
+ }
+ | LIMIT value PERCENT limit_with
+ {
+ $$ = LimitClause{Limit: $1.Literal, Value: $2, Percent: $3.Literal, With: $4}
+ }
+
+limit_with
+ :
+ {
+ $$ = nil
+ }
+ | WITH TIES
+ {
+ $$ = LimitWith{With: $1.Literal, Type: $2}
}
offset_clause
@@ -454,9 +474,9 @@ offset_clause
{
$$ = nil
}
- | OFFSET INTEGER
+ | OFFSET value
{
- $$ = OffsetClause{Offset: $1.Literal, Number: StrToInt64($2.Literal)}
+ $$ = OffsetClause{Offset: $1.Literal, Value: $2}
}
primary
@@ -565,10 +585,34 @@ row_values
$$ = append([]Expression{$1}, $3...)
}
+order_items
+ : order_item
+ {
+ $$ = []Expression{$1}
+ }
+ | order_item ',' order_items
+ {
+ $$ = append([]Expression{$1}, $3...)
+ }
+
order_item
- : value order_direction
+ : order_value order_direction
+ {
+ $$ = OrderItem{Value: $1, Direction: $2}
+ }
+ | order_value order_direction NULLS order_null_position
{
- $$ = OrderItem{Item: $1, Direction: $2}
+ $$ = OrderItem{Value: $1, Direction: $2, Nulls: $3.Literal, Position: $4}
+ }
+
+order_value
+ : value
+ {
+ $$ = $1
+ }
+ | analytic_function
+ {
+ $$ = $1
}
order_direction
@@ -585,6 +629,16 @@ order_direction
$$ = $1
}
+order_null_position
+ : FIRST
+ {
+ $$ = $1
+ }
+ | LAST
+ {
+ $$ = $1
+ }
+
subquery
: '(' select_query ')'
{
@@ -762,6 +816,28 @@ group_concat
$$ = GroupConcat{GroupConcat: $1.Literal, Option: $3.(Option), OrderBy: $4, SeparatorLit: $5.Literal, Separator: $6.Literal}
}
+analytic_function
+ : identifier '(' option ')' OVER '(' analytic_clause ')'
+ {
+ $$ = AnalyticFunction{Name: $1.Literal, Option: $3.(Option), Over: $5.Literal, AnalyticClause: $7.(AnalyticClause)}
+ }
+
+analytic_clause
+ : partition order_by_clause
+ {
+ $$ = AnalyticClause{Partition: $1, OrderByClause: $2}
+ }
+
+partition
+ :
+ {
+ $$ = nil
+ }
+ | PARTITION BY values
+ {
+ $$ = Partition{PartitionBy: $1.Literal + " " + $2.Literal, Values: $3}
+ }
+
identified_table
: identifier
{
@@ -853,6 +929,10 @@ field_object
{
$$ = $1
}
+ | analytic_function
+ {
+ $$ = $1
+ }
| '*'
{
$$ = AllColumns{}
@@ -914,16 +994,6 @@ values
$$ = append([]Expression{$1}, $3...)
}
-order_items
- : order_item
- {
- $$ = []Expression{$1}
- }
- | order_item ',' order_items
- {
- $$ = append([]Expression{$1}, $3...)
- }
-
tables
: table
{
diff --git a/lib/parser/parser_test.go b/lib/parser/parser_test.go
index 0c99f2a9..e6a0e26f 100644
--- a/lib/parser/parser_test.go
+++ b/lib/parser/parser_test.go
@@ -209,7 +209,7 @@ var parseTests = []struct {
" where 1 = 1" +
" group by column1, column2 " +
" having 1 > 1 " +
- " order by column4, column5 desc, column6 asc " +
+ " order by column4, column5 desc, column6 asc, column7 nulls first, column8 desc nulls last, avg() over () " +
" limit 10 " +
" offset 10 ",
Output: []Statement{
@@ -244,18 +244,65 @@ var parseTests = []struct {
OrderByClause: OrderByClause{
OrderBy: "order by",
Items: []Expression{
- OrderItem{Item: FieldReference{Column: Identifier{Literal: "column4"}}},
- OrderItem{Item: FieldReference{Column: Identifier{Literal: "column5"}}, Direction: Token{Token: DESC, Literal: "desc"}},
- OrderItem{Item: FieldReference{Column: Identifier{Literal: "column6"}}, Direction: Token{Token: ASC, Literal: "asc"}},
+ OrderItem{Value: FieldReference{Column: Identifier{Literal: "column4"}}},
+ OrderItem{Value: FieldReference{Column: Identifier{Literal: "column5"}}, Direction: Token{Token: DESC, Literal: "desc"}},
+ OrderItem{Value: FieldReference{Column: Identifier{Literal: "column6"}}, Direction: Token{Token: ASC, Literal: "asc"}},
+ OrderItem{Value: FieldReference{Column: Identifier{Literal: "column7"}}, Nulls: "nulls", Position: Token{Token: FIRST, Literal: "first"}},
+ OrderItem{Value: FieldReference{Column: Identifier{Literal: "column8"}}, Direction: Token{Token: DESC, Literal: "desc"}, Nulls: "nulls", Position: Token{Token: LAST, Literal: "last"}},
+ OrderItem{Value: AnalyticFunction{
+ Name: "avg",
+ Option: Option{},
+ Over: "over",
+ AnalyticClause: AnalyticClause{
+ Partition: nil,
+ OrderByClause: nil,
+ },
+ }},
},
},
LimitClause: LimitClause{
- Limit: "limit",
- Number: 10,
+ Limit: "limit",
+ Value: NewInteger(10),
},
OffsetClause: OffsetClause{
Offset: "offset",
- Number: 10,
+ Value: NewInteger(10),
+ },
+ },
+ },
+ },
+ {
+ Input: "select 1 " +
+ " from dual " +
+ " limit 10 percent",
+ Output: []Statement{
+ SelectQuery{
+ SelectEntity: SelectEntity{
+ SelectClause: SelectClause{Select: "select", Fields: []Expression{Field{Object: NewIntegerFromString("1")}}},
+ FromClause: FromClause{From: "from", Tables: []Expression{Table{Object: Dual{Dual: "dual"}}}},
+ },
+ LimitClause: LimitClause{
+ Limit: "limit",
+ Value: NewInteger(10),
+ Percent: "percent",
+ },
+ },
+ },
+ },
+ {
+ Input: "select 1 " +
+ " from dual " +
+ " limit 10 with ties",
+ Output: []Statement{
+ SelectQuery{
+ SelectEntity: SelectEntity{
+ SelectClause: SelectClause{Select: "select", Fields: []Expression{Field{Object: NewIntegerFromString("1")}}},
+ FromClause: FromClause{From: "from", Tables: []Expression{Table{Object: Dual{Dual: "dual"}}}},
+ },
+ LimitClause: LimitClause{
+ Limit: "limit",
+ Value: NewInteger(10),
+ With: LimitWith{With: "with", Type: Token{Token: TIES, Literal: "ties"}},
},
},
},
@@ -1283,7 +1330,7 @@ var parseTests = []struct {
OrderBy: OrderByClause{
OrderBy: "order by",
Items: []Expression{
- OrderItem{Item: FieldReference{Column: Identifier{Literal: "column1"}}},
+ OrderItem{Value: FieldReference{Column: Identifier{Literal: "column1"}}},
},
},
}},
@@ -1313,6 +1360,64 @@ var parseTests = []struct {
},
},
},
+ {
+ Input: "select rank() over (partition by column1 order by column2)",
+ Output: []Statement{
+ SelectQuery{
+ SelectEntity: SelectEntity{
+ SelectClause: SelectClause{
+ Select: "select",
+ Fields: []Expression{
+ Field{Object: AnalyticFunction{
+ Name: "rank",
+ Option: Option{},
+ Over: "over",
+ AnalyticClause: AnalyticClause{
+ Partition: Partition{
+ PartitionBy: "partition by",
+ Values: []Expression{
+ FieldReference{Column: Identifier{Literal: "column1"}},
+ },
+ },
+ OrderByClause: OrderByClause{
+ OrderBy: "order by",
+ Items: []Expression{
+ OrderItem{
+ Value: FieldReference{Column: Identifier{Literal: "column2"}},
+ },
+ },
+ },
+ },
+ }},
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ Input: "select avg() over ()",
+ Output: []Statement{
+ SelectQuery{
+ SelectEntity: SelectEntity{
+ SelectClause: SelectClause{
+ Select: "select",
+ Fields: []Expression{
+ Field{Object: AnalyticFunction{
+ Name: "avg",
+ Option: Option{},
+ Over: "over",
+ AnalyticClause: AnalyticClause{
+ Partition: nil,
+ OrderByClause: nil,
+ },
+ }},
+ },
+ },
+ },
+ },
+ },
+ },
{
Input: "select 1 from table1 cross join table2",
Output: []Statement{
diff --git a/lib/query/aggregate.go b/lib/query/aggregate_function.go
similarity index 100%
rename from lib/query/aggregate.go
rename to lib/query/aggregate_function.go
diff --git a/lib/query/aggregate_test.go b/lib/query/aggregate_function_test.go
similarity index 100%
rename from lib/query/aggregate_test.go
rename to lib/query/aggregate_function_test.go
diff --git a/lib/query/analytic_function.go b/lib/query/analytic_function.go
new file mode 100644
index 00000000..7d8a528b
--- /dev/null
+++ b/lib/query/analytic_function.go
@@ -0,0 +1,133 @@
+package query
+
+import (
+ "errors"
+
+ "github.com/mithrandie/csvq/lib/parser"
+ "github.com/mithrandie/csvq/lib/ternary"
+)
+
+var AnalyticFunctions = map[string]func(*View, []parser.Expression, []partitionValue) error{
+ "ROW_NUMBER": RowNumber,
+ "RANK": Rank,
+ "DENSE_RANK": DenseRank,
+}
+
+type partitionValue struct {
+ values []parser.Primary
+ orderValues []parser.Primary
+ number float64
+ rank float64
+}
+
+func (pv partitionValue) match(values []parser.Primary) bool {
+ for i, v := range pv.values {
+ if EquivalentTo(v, values[i]) != ternary.TRUE {
+ return false
+ }
+ }
+ return true
+}
+
+func (pv partitionValue) isSameRank(orderValues []parser.Primary) bool {
+ for i, v := range pv.orderValues {
+ if EquivalentTo(v, orderValues[i]) != ternary.TRUE {
+ return false
+ }
+ }
+ return true
+}
+
+type partitionValues []partitionValue
+
+func (pv partitionValues) searchIndex(values []parser.Primary) int {
+ for idx, v := range pv {
+ if v.match(values) {
+ return idx
+ }
+ }
+ return -1
+}
+
+func RowNumber(view *View, args []parser.Expression, partitinList []partitionValue) error {
+ if args != nil {
+ return errors.New("function ROW_NUMBER takes no argument")
+ }
+
+ partitions := partitionValues{}
+
+ for i := range view.Records {
+ var idx int
+ if idx = partitions.searchIndex(partitinList[i].values); -1 < idx {
+ partitions[idx].number++
+ } else {
+ partitions = append(partitions, partitionValue{
+ values: partitinList[i].values,
+ number: 1,
+ })
+ idx = len(partitions) - 1
+ }
+
+ view.Records[i] = append(view.Records[i], NewCell(parser.NewInteger(int64(partitions[idx].number))))
+ }
+
+ return nil
+}
+
+func Rank(view *View, args []parser.Expression, partitinList []partitionValue) error {
+ if args != nil {
+ return errors.New("function RANK takes no argument")
+ }
+
+ partitions := partitionValues{}
+
+ for i := range view.Records {
+ var idx int
+ if idx = partitions.searchIndex(partitinList[i].values); -1 < idx {
+ partitions[idx].number++
+ if !partitions[idx].isSameRank(partitinList[i].orderValues) {
+ partitions[idx].rank = partitions[idx].number
+ }
+ } else {
+ partitions = append(partitions, partitionValue{
+ values: partitinList[i].values,
+ orderValues: partitinList[i].orderValues,
+ number: 1,
+ rank: 1,
+ })
+ idx = len(partitions) - 1
+ }
+
+ view.Records[i] = append(view.Records[i], NewCell(parser.NewInteger(int64(partitions[idx].rank))))
+ }
+
+ return nil
+}
+
+func DenseRank(view *View, args []parser.Expression, partitinList []partitionValue) error {
+ if args != nil {
+ return errors.New("function DENSE_RANK takes no argument")
+ }
+
+ partitions := partitionValues{}
+
+ for i := range view.Records {
+ var idx int
+ if idx = partitions.searchIndex(partitinList[i].values); -1 < idx {
+ if !partitions[idx].isSameRank(partitinList[i].orderValues) {
+ partitions[idx].rank++
+ }
+ } else {
+ partitions = append(partitions, partitionValue{
+ values: partitinList[i].values,
+ orderValues: partitinList[i].orderValues,
+ rank: 1,
+ })
+ idx = len(partitions) - 1
+ }
+
+ view.Records[i] = append(view.Records[i], NewCell(parser.NewInteger(int64(partitions[idx].rank))))
+ }
+
+ return nil
+}
diff --git a/lib/query/analytic_function_test.go b/lib/query/analytic_function_test.go
new file mode 100644
index 00000000..58d5237b
--- /dev/null
+++ b/lib/query/analytic_function_test.go
@@ -0,0 +1,454 @@
+package query
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/mithrandie/csvq/lib/parser"
+)
+
+type analyticFunctionTest struct {
+ Name string
+ View *View
+ Args []parser.Expression
+ PartitionList []partitionValue
+ Result *View
+ Error string
+}
+
+func testAnalyticFunction(t *testing.T, f func(*View, []parser.Expression, []partitionValue) error, tests []analyticFunctionTest) {
+ for _, v := range tests {
+ ViewCache.Clear()
+ err := f(v.View, v.Args, v.PartitionList)
+ if err != nil {
+ if len(v.Error) < 1 {
+ t.Errorf("%s: unexpected error %q", v.Name, err)
+ } else if err.Error() != v.Error {
+ t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
+ }
+ continue
+ }
+ if 0 < len(v.Error) {
+ t.Errorf("%s: no error, want error %q", v.Name, v.Error)
+ continue
+ }
+ if !reflect.DeepEqual(v.View, v.Result) {
+ t.Errorf("%s: result = %q, want %q", v.Name, v.View, v.Result)
+ }
+ }
+}
+
+var rowNumberTests = []analyticFunctionTest{
+ {
+ Name: "RowNumber",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ },
+ },
+ PartitionList: []partitionValue{
+ {
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ orderValues: []parser.Primary{parser.NewInteger(2)},
+ },
+ {
+ orderValues: []parser.Primary{parser.NewInteger(3)},
+ },
+ {
+ orderValues: []parser.Primary{parser.NewInteger(4)},
+ },
+ {
+ orderValues: []parser.Primary{parser.NewInteger(5)},
+ },
+ },
+ Result: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ parser.NewInteger(4),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ parser.NewInteger(5),
+ }),
+ },
+ },
+ },
+ {
+ Name: "RowNumber with Partition",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ },
+ },
+ PartitionList: []partitionValue{
+ {
+ values: []parser.Primary{parser.NewString("a")},
+ },
+ {
+ values: []parser.Primary{parser.NewString("a")},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ },
+ },
+ Result: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ parser.NewInteger(3),
+ }),
+ },
+ },
+ },
+ {
+ Name: "RowNumber Arguments Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ Args: []parser.Expression{
+ parser.NewInteger(1),
+ },
+ Error: "function ROW_NUMBER takes no argument",
+ },
+}
+
+func TestRowNumber(t *testing.T) {
+ testAnalyticFunction(t, RowNumber, rowNumberTests)
+}
+
+var rankTests = []analyticFunctionTest{
+ {
+ Name: "Rank",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ PartitionList: []partitionValue{
+ {
+ values: []parser.Primary{parser.NewString("a")},
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ orderValues: []parser.Primary{parser.NewInteger(2)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("a")},
+ orderValues: []parser.Primary{parser.NewInteger(2)},
+ },
+ },
+ Result: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(2),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ },
+ {
+ Name: "Rank Arguments Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ Args: []parser.Expression{
+ parser.NewInteger(1),
+ },
+ Error: "function RANK takes no argument",
+ },
+}
+
+func TestRank(t *testing.T) {
+ testAnalyticFunction(t, Rank, rankTests)
+}
+
+var denseRankTests = []analyticFunctionTest{
+ {
+ Name: "DenseRank",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ PartitionList: []partitionValue{
+ {
+ values: []parser.Primary{parser.NewString("a")},
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ orderValues: []parser.Primary{parser.NewInteger(1)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("b")},
+ orderValues: []parser.Primary{parser.NewInteger(2)},
+ },
+ {
+ values: []parser.Primary{parser.NewString("a")},
+ orderValues: []parser.Primary{parser.NewInteger(2)},
+ },
+ },
+ Result: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(2),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ },
+ {
+ Name: "DenseRank Arguments Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ },
+ },
+ Args: []parser.Expression{
+ parser.NewInteger(1),
+ },
+ Error: "function DENSE_RANK takes no argument",
+ },
+}
+
+func TestDenseRank(t *testing.T) {
+ testAnalyticFunction(t, DenseRank, denseRankTests)
+}
diff --git a/lib/query/cursor_test.go b/lib/query/cursor_test.go
index 8f4b3c29..02f0f1f3 100644
--- a/lib/query/cursor_test.go
+++ b/lib/query/cursor_test.go
@@ -179,7 +179,7 @@ var cursorMapOpenTests = []struct {
{
Name: "CursorMap Open Query Error",
Key: "cur2",
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
diff --git a/lib/query/error.go b/lib/query/error.go
index 0afa81ec..74ad9b9a 100644
--- a/lib/query/error.go
+++ b/lib/query/error.go
@@ -12,7 +12,7 @@ type IdentificationError struct {
}
func (e IdentificationError) Error() string {
- return fmt.Sprintf("identifier = %s: %s", e.Field.String(), e.Err)
+ return fmt.Sprintf(e.Err.Error(), e.Field.String())
}
type NotGroupedError struct {
@@ -25,7 +25,7 @@ func (e NotGroupedError) Error() string {
}
var (
- ErrFieldAmbiguous = errors.New("field is ambiguous")
- ErrFieldNotExist = errors.New("field does not exist")
+ ErrFieldAmbiguous = errors.New("field %s is ambiguous")
+ ErrFieldNotExist = errors.New("field %s does not exist")
ErrNotGrouped = errors.New("records are not grouped")
)
diff --git a/lib/query/filter.go b/lib/query/filter.go
index 794e2bcf..7c39b8c4 100644
--- a/lib/query/filter.go
+++ b/lib/query/filter.go
@@ -95,7 +95,7 @@ func (f Filter) evalFieldReference(expr parser.FieldReference) (parser.Primary,
}
}
if v.View.isGrouped && !v.View.Header[idx].IsGroupKey {
- return nil, errors.New(fmt.Sprintf("identifier = %s: field is not a group key", expr))
+ return nil, errors.New(fmt.Sprintf("field %s is not a group key", expr))
}
p = v.View.Records[v.RecordIndex][idx].Primary()
}
@@ -370,7 +370,7 @@ func (f Filter) evalFunction(expr parser.Function) (parser.Primary, error) {
fn, ok := Functions[name]
if !ok {
- return nil, errors.New(fmt.Sprintf("function %s is not exist", expr.Name))
+ return nil, errors.New(fmt.Sprintf("function %s does not exist", expr.Name))
}
if expr.Option.IsDistinct() {
@@ -433,15 +433,6 @@ func (f Filter) evalAggregateFunction(expr parser.Function) (parser.Primary, err
}
func (f Filter) evalGroupConcat(expr parser.GroupConcat) (parser.Primary, error) {
- var in = func(list []string, item string) bool {
- for _, v := range list {
- if v == item {
- return true
- }
- }
- return false
- }
-
if !f[0].View.isGrouped {
return nil, &NotGroupedError{
Function: expr.GroupConcat,
@@ -481,7 +472,7 @@ func (f Filter) evalGroupConcat(expr parser.GroupConcat) (parser.Primary, error)
if parser.IsNull(s) {
continue
}
- if expr.Option.IsDistinct() && in(list, s.(parser.String).Value()) {
+ if expr.Option.IsDistinct() && InStrSlice(s.(parser.String).Value(), list) {
continue
}
list = append(list, s.(parser.String).Value())
@@ -578,16 +569,20 @@ func (f Filter) evalRowValue(expr parser.RowValue) (values []parser.Primary, err
return
}
-func (f Filter) evalValueList(expr parser.ValueList) ([]parser.Primary, error) {
- list := make([]parser.Primary, len(expr.Values))
- for i, v := range expr.Values {
- s, err := f.Evaluate(v)
+func (f Filter) evalValues(exprs []parser.Expression) ([]parser.Primary, error) {
+ values := make([]parser.Primary, len(exprs))
+ for i, v := range exprs {
+ value, err := f.Evaluate(v)
if err != nil {
return nil, err
}
- list[i] = s
+ values[i] = value
}
- return list, nil
+ return values, nil
+}
+
+func (f Filter) evalValueList(expr parser.ValueList) ([]parser.Primary, error) {
+ return f.evalValues(expr.Values)
}
func (f Filter) evalRowValueList(expr parser.RowValueList) ([][]parser.Primary, error) {
diff --git a/lib/query/filter_test.go b/lib/query/filter_test.go
index c4a0506c..cb3c641e 100644
--- a/lib/query/filter_test.go
+++ b/lib/query/filter_test.go
@@ -77,7 +77,7 @@ var filterEvaluateTests = []struct {
},
},
Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column3"}},
- Error: "identifier = column3: field does not exist",
+ Error: "field column3 does not exist",
},
{
Name: "FieldReference FieldAmbigous Error",
@@ -100,7 +100,7 @@ var filterEvaluateTests = []struct {
},
},
Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
- Error: "identifier = column1: field is ambiguous",
+ Error: "field column1 is ambiguous",
},
{
Name: "FieldReference Not Group Key Error",
@@ -137,7 +137,7 @@ var filterEvaluateTests = []struct {
},
},
Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
- Error: "identifier = column1: field is not a group key",
+ Error: "field column1 is not a group key",
},
{
Name: "FieldReference Fields Ambiguous Error with Multiple Tables",
@@ -176,7 +176,7 @@ var filterEvaluateTests = []struct {
},
},
Expr: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
- Error: "identifier = column1: field is ambiguous",
+ Error: "field column1 is ambiguous",
},
{
Name: "Arithmetic",
@@ -194,7 +194,7 @@ var filterEvaluateTests = []struct {
RHS: parser.NewInteger(2),
Operator: '+',
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Arithmetic RHS Error",
@@ -203,7 +203,7 @@ var filterEvaluateTests = []struct {
RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
Operator: '+',
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Concat",
@@ -225,7 +225,7 @@ var filterEvaluateTests = []struct {
parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Concat Including Null",
@@ -254,7 +254,7 @@ var filterEvaluateTests = []struct {
RHS: parser.NewInteger(2),
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Comparison RHS Error",
@@ -263,7 +263,7 @@ var filterEvaluateTests = []struct {
RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Comparison with Row Values",
@@ -351,7 +351,7 @@ var filterEvaluateTests = []struct {
},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Comparison with Row Value and Subquery Returns No Record",
@@ -424,7 +424,7 @@ var filterEvaluateTests = []struct {
},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Comparison with Row Values RHS Error",
@@ -498,7 +498,7 @@ var filterEvaluateTests = []struct {
RHS: parser.NewNull(),
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Is RHS Error",
@@ -507,7 +507,7 @@ var filterEvaluateTests = []struct {
RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between",
@@ -527,7 +527,7 @@ var filterEvaluateTests = []struct {
High: parser.NewInteger(3),
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between Low Error",
@@ -537,7 +537,7 @@ var filterEvaluateTests = []struct {
High: parser.NewInteger(3),
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between High Error",
@@ -547,7 +547,7 @@ var filterEvaluateTests = []struct {
High: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between with Row Values",
@@ -607,7 +607,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between with Row Values Low Error",
@@ -637,7 +637,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between with Row Values High Error",
@@ -667,7 +667,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Between with Row Values Low Comparison Error",
@@ -759,7 +759,7 @@ var filterEvaluateTests = []struct {
},
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "In List Error",
@@ -776,7 +776,7 @@ var filterEvaluateTests = []struct {
},
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "In Subquery",
@@ -858,7 +858,7 @@ var filterEvaluateTests = []struct {
},
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "In Subquery Returns No Record",
@@ -987,7 +987,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "In with Row Values Values Error",
@@ -1021,7 +1021,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "In with Row Values Length Not Match Error ",
@@ -1108,7 +1108,7 @@ var filterEvaluateTests = []struct {
},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Any Query Execution Error",
@@ -1142,7 +1142,7 @@ var filterEvaluateTests = []struct {
},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "<>"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Any Row Value Length Not Match Error",
@@ -1224,7 +1224,7 @@ var filterEvaluateTests = []struct {
},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "All Query Execution Error",
@@ -1258,7 +1258,7 @@ var filterEvaluateTests = []struct {
},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "All Row Value Length Not Match Error",
@@ -1304,7 +1304,7 @@ var filterEvaluateTests = []struct {
Pattern: parser.NewString("_bc%"),
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Like Pattern Error",
@@ -1313,7 +1313,7 @@ var filterEvaluateTests = []struct {
Pattern: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
Negation: parser.Token{Token: parser.NOT, Literal: "not"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Exists",
@@ -1413,7 +1413,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Subquery",
@@ -1454,7 +1454,7 @@ var filterEvaluateTests = []struct {
},
},
LimitClause: parser.LimitClause{
- Number: 1,
+ Value: parser.NewInteger(1),
},
},
},
@@ -1481,7 +1481,7 @@ var filterEvaluateTests = []struct {
},
},
LimitClause: parser.LimitClause{
- Number: 1,
+ Value: parser.NewInteger(1),
},
},
},
@@ -1506,7 +1506,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Subquery Too Many Records Error",
@@ -1548,7 +1548,7 @@ var filterEvaluateTests = []struct {
},
},
LimitClause: parser.LimitClause{
- Number: 1,
+ Value: parser.NewInteger(1),
},
},
},
@@ -1568,7 +1568,7 @@ var filterEvaluateTests = []struct {
Result: parser.NewString("str"),
},
{
- Name: "Function Is Not Exist",
+ Name: "Function Not Exist Error",
Expr: parser.Function{
Name: "notexist",
Option: parser.Option{
@@ -1578,7 +1578,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "function notexist is not exist",
+ Error: "function notexist does not exist",
},
{
Name: "Function Option Error",
@@ -1896,7 +1896,7 @@ var filterEvaluateTests = []struct {
},
OrderBy: parser.OrderByClause{
Items: []parser.Expression{
- parser.OrderItem{Item: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
+ parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
},
},
Separator: ",",
@@ -2075,12 +2075,12 @@ var filterEvaluateTests = []struct {
},
OrderBy: parser.OrderByClause{
Items: []parser.Expression{
- parser.OrderItem{Item: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}},
+ parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}}},
},
},
Separator: ",",
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "GroupConcat Function Duplicate Error",
@@ -2217,7 +2217,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Case When Condition Error",
@@ -2234,7 +2234,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Case When Result Error",
@@ -2251,7 +2251,7 @@ var filterEvaluateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Case Else Result Error",
@@ -2271,7 +2271,7 @@ var filterEvaluateTests = []struct {
Result: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Logic AND",
@@ -2306,7 +2306,7 @@ var filterEvaluateTests = []struct {
RHS: parser.NewTernary(ternary.FALSE),
Operator: parser.Token{Token: parser.AND, Literal: "and"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Logic RHS Error",
@@ -2315,7 +2315,7 @@ var filterEvaluateTests = []struct {
RHS: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
Operator: parser.Token{Token: parser.AND, Literal: "and"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Variable",
diff --git a/lib/query/header.go b/lib/query/header.go
index d0345522..ef178996 100644
--- a/lib/query/header.go
+++ b/lib/query/header.go
@@ -1,6 +1,10 @@
package query
-import "github.com/mithrandie/csvq/lib/parser"
+import (
+ "strings"
+
+ "github.com/mithrandie/csvq/lib/parser"
+)
const INTERNAL_ID_COLUMN = "@__internal_id"
@@ -61,9 +65,10 @@ func MergeHeader(h1 Header, h2 Header) Header {
return append(h1, h2...)
}
-func AddHeaderField(h Header, alias string) (header Header, index int) {
+func AddHeaderField(h Header, column string, alias string) (header Header, index int) {
header = append(h, HeaderField{
- Alias: alias,
+ Column: column,
+ Alias: alias,
})
index = header.Len() - 1
return
@@ -103,9 +108,9 @@ func (h Header) TableColumnNames() []string {
return names
}
-func (h Header) ContainsAlias(alias string) (int, error) {
+func (h Header) ContainsObject(obj parser.Expression) (int, error) {
fieldRef := parser.FieldReference{
- Column: parser.Identifier{Literal: alias},
+ Column: parser.Identifier{Literal: obj.String()},
}
return h.Contains(fieldRef)
}
@@ -121,11 +126,11 @@ func (h Header) Contains(fieldRef parser.FieldReference) (int, error) {
for i, f := range h {
if 0 < len(ref) {
- if f.Reference != ref || f.Column != column {
+ if !strings.EqualFold(f.Reference, ref) || !strings.EqualFold(f.Column, column) {
continue
}
} else {
- if f.Column != column && f.Alias != column {
+ if !strings.EqualFold(f.Column, column) && !strings.EqualFold(f.Alias, column) {
continue
}
}
diff --git a/lib/query/header_test.go b/lib/query/header_test.go
index 7caa4e18..ebb67316 100644
--- a/lib/query/header_test.go
+++ b/lib/query/header_test.go
@@ -86,13 +86,13 @@ var headerContainsTests = []struct {
Ref: parser.FieldReference{
Column: parser.Identifier{Literal: "c1"},
},
- Error: "identifier = c1: field is ambiguous",
+ Error: "field c1 is ambiguous",
},
{
Ref: parser.FieldReference{
Column: parser.Identifier{Literal: "d1"},
},
- Error: "identifier = d1: field does not exist",
+ Error: "field d1 does not exist",
},
}
diff --git a/lib/query/join_test.go b/lib/query/join_test.go
index e6d29f15..6161fa23 100644
--- a/lib/query/join_test.go
+++ b/lib/query/join_test.go
@@ -295,7 +295,7 @@ var innerJoinTests = []struct {
RHS: parser.FieldReference{View: parser.Identifier{Literal: "table2"}, Column: parser.Identifier{Literal: "notexist"}},
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
- Error: "identifier = table2.notexist: field does not exist",
+ Error: "field table2.notexist does not exist",
},
}
@@ -617,7 +617,7 @@ var outerJoinTests = []struct {
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
Direction: parser.LEFT,
- Error: "identifier = table1.notexist: field does not exist",
+ Error: "field table1.notexist does not exist",
},
{
Name: "Outer Join Direction Undefined",
diff --git a/lib/query/main_test.go b/lib/query/main_test.go
index 509b7f47..dfd11b94 100644
--- a/lib/query/main_test.go
+++ b/lib/query/main_test.go
@@ -24,10 +24,14 @@ func GetTestLocation() *time.Location {
}
func TestMain(m *testing.M) {
+ os.Exit(run(m))
+}
+
+func run(m *testing.M) int {
+ defer teardown()
+
setup()
- r := m.Run()
- teardown()
- os.Exit(r)
+ return m.Run()
}
func setup() {
diff --git a/lib/query/query.go b/lib/query/query.go
index f8ce5ac7..4b46bb12 100644
--- a/lib/query/query.go
+++ b/lib/query/query.go
@@ -479,11 +479,15 @@ func Select(query parser.SelectQuery, parentFilter Filter) (*View, error) {
}
if query.OffsetClause != nil {
- view.Offset(query.OffsetClause.(parser.OffsetClause))
+ if err := view.Offset(query.OffsetClause.(parser.OffsetClause)); err != nil {
+ return nil, err
+ }
}
if query.LimitClause != nil {
- view.Limit(query.LimitClause.(parser.LimitClause))
+ if err := view.Limit(query.LimitClause.(parser.LimitClause)); err != nil {
+ return nil, err
+ }
}
view.Fix()
diff --git a/lib/query/query_test.go b/lib/query/query_test.go
index 6ef5f8a9..1165cd4a 100644
--- a/lib/query/query_test.go
+++ b/lib/query/query_test.go
@@ -210,6 +210,7 @@ var executeStatementTests = []struct {
View: &View{
Header: []HeaderField{
{
+ Column: "@var1",
Alias: "var1",
FromTable: true,
},
@@ -588,7 +589,7 @@ var ifStmtTests = []struct {
parser.TransactionControl{Token: parser.COMMIT},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -796,7 +797,7 @@ var whileTests = []struct {
parser.TransactionControl{Token: parser.COMMIT},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "While Statement Execution Error",
@@ -819,7 +820,7 @@ var whileTests = []struct {
parser.TransactionControl{Token: parser.COMMIT},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -997,7 +998,7 @@ var whileInCursorTests = []struct {
parser.TransactionControl{Token: parser.COMMIT},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -1217,14 +1218,14 @@ var selectTests = []struct {
},
OrderByClause: parser.OrderByClause{
Items: []parser.Expression{
- parser.OrderItem{Item: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
+ parser.OrderItem{Value: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
},
},
LimitClause: parser.LimitClause{
- Number: 5,
+ Value: parser.NewInteger(5),
},
OffsetClause: parser.OffsetClause{
- Number: 0,
+ Value: parser.NewInteger(0),
},
},
Result: &View{
@@ -1242,6 +1243,7 @@ var selectTests = []struct {
FromTable: true,
},
{
+ Column: "count(*)",
Alias: "count(*)",
FromTable: true,
},
@@ -1573,7 +1575,7 @@ var selectTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Union RHS Error",
@@ -1608,7 +1610,7 @@ var selectTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -1820,7 +1822,7 @@ var insertTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Insert Select Query",
@@ -2106,7 +2108,7 @@ var updateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Update Query File Is Not Loaded Error",
@@ -2168,7 +2170,7 @@ var updateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Update Query Update Value Error",
@@ -2192,7 +2194,7 @@ var updateTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Update Query Record Is Ambiguous Error",
@@ -2419,7 +2421,7 @@ var deleteTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Delete Query File Is Not Loaded Error",
@@ -2777,7 +2779,7 @@ var addColumnsTests = []struct {
Column: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Add Columns Field Duplicate Error",
@@ -2809,7 +2811,7 @@ var addColumnsTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -2893,7 +2895,7 @@ var dropColumnsTests = []struct {
parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -2986,7 +2988,7 @@ var renameColumnTests = []struct {
Old: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
New: parser.Identifier{Literal: "newcolumn"},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
diff --git a/lib/query/record.go b/lib/query/record.go
index 1b955c49..74946f81 100644
--- a/lib/query/record.go
+++ b/lib/query/record.go
@@ -63,6 +63,16 @@ func (r Record) IsEqualTo(record Record) bool {
return true
}
+func (r Record) Match(record Record, indices []int) bool {
+ for _, i := range indices {
+ if EquivalentTo(r[i].Primary(), record[i].Primary()) != ternary.TRUE {
+ return false
+ }
+ }
+
+ return true
+}
+
func (r Record) GroupLen() int {
return r[0].Len()
}
diff --git a/lib/query/variables_test.go b/lib/query/variables_test.go
index c205dd0f..53b58470 100644
--- a/lib/query/variables_test.go
+++ b/lib/query/variables_test.go
@@ -66,7 +66,7 @@ var variablesDeclareTests = []variableTests{
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -118,7 +118,7 @@ var variablesSubstituteTests = []variableTests{
Variable: parser.Variable{Name: "var1"},
Value: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
diff --git a/lib/query/view.go b/lib/query/view.go
index 0f716293..42b59b53 100644
--- a/lib/query/view.go
+++ b/lib/query/view.go
@@ -3,6 +3,7 @@ package query
import (
"errors"
"fmt"
+ "math"
"os"
"path"
"path/filepath"
@@ -184,8 +185,11 @@ type View struct {
filteredIndices []int
- sortIndices []int
- sortDirections []int
+ sortIndices []int
+ sortDirections []int
+ sortNullPositions []int
+
+ offset int
OperatedRecords int
OperatedFields int
@@ -585,33 +589,25 @@ func (view *View) Select(clause parser.SelectClause) error {
return append(append(fields[:insertIdx], insert...), fields[insertIdx+1:]...)
}
- var evalFields = func(view *View, fields []parser.Expression) ([]Record, error) {
- records := make([]Record, view.RecordLen())
- for i := range view.Records {
- var record Record
- var filter Filter = append([]FilterRecord{{View: view, RecordIndex: i}}, view.parentFilter...)
-
- for _, f := range fields {
- field := f.(parser.Field)
- primary, err := filter.Evaluate(field.Object)
- if err != nil {
- return nil, err
- }
- if _, ok := field.Object.(parser.FieldReference); !ok {
- record = append(record, NewCell(primary))
- }
+ var evalFields = func(view *View, fields []parser.Expression) error {
+ view.selectFields = make([]int, len(fields))
+ for i, f := range fields {
+ field := f.(parser.Field)
+ idx, err := view.evalColumn(field.Object, field.Object.String(), field.Name())
+ if err != nil {
+ return err
}
- records[i] = record
+ view.selectFields[i] = idx
}
- return records, nil
+ return nil
}
fields := parseAllColumns(view, clause.Fields)
- records, err := evalFields(view, fields)
+ err := evalFields(view, fields)
if err != nil {
if _, ok := err.(*NotGroupedError); ok {
view.group(nil)
- records, err = evalFields(view, fields)
+ err = evalFields(view, fields)
if err != nil {
return err
}
@@ -620,26 +616,6 @@ func (view *View) Select(clause parser.SelectClause) error {
}
}
- view.selectFields = make([]int, len(fields))
- for i, f := range fields {
- field := f.(parser.Field)
- if fieldRef, ok := field.Object.(parser.FieldReference); ok {
- idx, err := view.Header.Contains(fieldRef)
- if err != nil {
- return err
- }
- view.selectFields[i] = idx
- } else {
- view.Header, view.selectFields[i] = AddHeaderField(view.Header, field.Name())
- }
- }
-
- for i := range view.Records {
- if 0 < len(records[i]) {
- view.Records[i] = append(view.Records[i], records[i]...)
- }
- }
-
if clause.IsDistinct() {
records := make(Records, view.RecordLen())
for i, v := range view.Records {
@@ -687,67 +663,192 @@ func (view *View) SelectAllColumns() error {
}
func (view *View) OrderBy(clause parser.OrderByClause) error {
- view.sortIndices = []int{}
+ view.sortIndices = make([]int, len(clause.Items))
+ view.sortDirections = make([]int, len(clause.Items))
+ view.sortNullPositions = make([]int, len(clause.Items))
- for _, v := range clause.Items {
+ for i, v := range clause.Items {
oi := v.(parser.OrderItem)
- switch oi.Item.(type) {
- case parser.FieldReference:
- idx, err := view.FieldIndex(oi.Item.(parser.FieldReference))
- if err != nil {
- return err
+ idx, err := view.evalColumn(oi.Value, oi.Value.String(), "")
+ if err != nil {
+ return err
+ }
+ view.sortIndices[i] = idx
+
+ if oi.Direction.IsEmpty() {
+ view.sortDirections[i] = parser.ASC
+ } else {
+ view.sortDirections[i] = oi.Direction.Token
+ }
+
+ if oi.Position.IsEmpty() {
+ switch view.sortDirections[i] {
+ case parser.ASC:
+ view.sortNullPositions[i] = parser.FIRST
+ default: //parser.DESC
+ view.sortNullPositions[i] = parser.LAST
}
- view.sortIndices = append(view.sortIndices, idx)
- default:
- idx, err := view.Header.ContainsAlias(oi.Item.String())
- if err != nil {
+ } else {
+ view.sortNullPositions[i] = oi.Position.Token
+ }
+ }
+
+ sort.Sort(view)
+ return nil
+}
+
+func (view *View) evalColumn(obj parser.Expression, column string, alias string) (idx int, err error) {
+ switch obj.(type) {
+ case parser.FieldReference:
+ idx, err = view.FieldIndex(obj.(parser.FieldReference))
+ default:
+ idx, err = view.Header.ContainsObject(obj)
+ if err != nil {
+ err = nil
+
+ if analyticFunction, ok := obj.(parser.AnalyticFunction); ok {
+ err = view.evalAnalyticFunction(analyticFunction)
+ if err != nil {
+ return
+ }
+ } else {
+ var filter Filter = append([]FilterRecord{{View: view, RecordIndex: 0}}, view.parentFilter...)
for i := range view.Records {
- var filter Filter = append([]FilterRecord{{View: view, RecordIndex: i}}, view.parentFilter...)
+ var primary parser.Primary
+ filter[0].RecordIndex = i
- primary, err := filter.Evaluate(oi.Item)
+ primary, err = filter.Evaluate(obj)
if err != nil {
- return err
+ return
}
view.Records[i] = append(view.Records[i], NewCell(primary))
}
- view.Header, idx = AddHeaderField(view.Header, oi.Item.String())
}
- view.sortIndices = append(view.sortIndices, idx)
+ view.Header, idx = AddHeaderField(view.Header, column, alias)
}
- view.sortDirections = append(view.sortDirections, oi.Direction.Token)
}
+ return
+}
- direction := parser.ASC
- for i := len(view.sortDirections) - 1; i >= 0; i-- {
- if view.sortDirections[i] == parser.ASC || view.sortDirections[i] == parser.DESC {
- direction = view.sortDirections[i]
- } else {
- view.sortDirections[i] = direction
+func (view *View) evalAnalyticFunction(expr parser.AnalyticFunction) error {
+ name := strings.ToUpper(expr.Name)
+ fn, ok := AnalyticFunctions[name]
+ if !ok {
+ return errors.New(fmt.Sprintf("function %s does not exist", expr.Name))
+ }
+
+ if expr.Option.IsDistinct() {
+ return errors.New(fmt.Sprintf("syntax error: unexpected %s", expr.Option.Distinct.Literal))
+ }
+
+ if expr.AnalyticClause.OrderByClause != nil {
+ err := view.OrderBy(expr.AnalyticClause.OrderByClause.(parser.OrderByClause))
+ if err != nil {
+ return err
}
}
- sort.Sort(view)
- return nil
+ partitionList := make([]partitionValue, view.RecordLen())
+
+ var filter Filter = append([]FilterRecord{{View: view, RecordIndex: 0}}, view.parentFilter...)
+ for i := range view.Records {
+ filter[0].RecordIndex = i
+ values, err := filter.evalValues(expr.AnalyticClause.PartitionValues())
+ if err != nil {
+ return err
+ }
+
+ orderValues, err := filter.evalValues(expr.AnalyticClause.OrderValues())
+ if err != nil {
+ return err
+ }
+
+ partitionList[i] = partitionValue{
+ values: values,
+ orderValues: orderValues,
+ }
+ }
+
+ return fn(view, expr.Option.Args, partitionList)
}
-func (view *View) Offset(clause parser.OffsetClause) {
- if int64(len(view.Records)) <= clause.Number {
+func (view *View) Offset(clause parser.OffsetClause) error {
+ var filter Filter
+ value, err := filter.Evaluate(clause.Value)
+ if err != nil {
+ return err
+ }
+ number := parser.PrimaryToInteger(value)
+ if parser.IsNull(number) {
+ return errors.New("offset number is not an integer")
+ }
+ view.offset = int(number.(parser.Integer).Value())
+ if view.offset < 0 {
+ view.offset = 0
+ }
+
+ if view.RecordLen() <= view.offset {
view.Records = Records{}
} else {
- view.Records = view.Records[clause.Number:]
+ view.Records = view.Records[view.offset:]
records := make(Records, len(view.Records))
copy(records, view.Records)
view.Records = records
}
+ return nil
}
-func (view *View) Limit(clause parser.LimitClause) {
- if clause.Number < int64(len(view.Records)) {
- view.Records = view.Records[:clause.Number]
- records := make(Records, len(view.Records))
- copy(records, view.Records)
- view.Records = records
+func (view *View) Limit(clause parser.LimitClause) error {
+ var filter Filter
+ value, err := filter.Evaluate(clause.Value)
+ if err != nil {
+ return err
+ }
+
+ var limit int
+ if clause.IsPercentage() {
+ number := parser.PrimaryToFloat(value)
+ if parser.IsNull(number) {
+ return errors.New("limit percentage is not a float value")
+ }
+ percentage := number.(parser.Float).Value()
+ if 100 < percentage {
+ limit = 100
+ } else if percentage < 0 {
+ limit = 0
+ } else {
+ limit = int(math.Ceil(float64(view.RecordLen()+view.offset) * percentage / 100))
+ }
+ } else {
+ number := parser.PrimaryToInteger(value)
+ if parser.IsNull(number) {
+ return errors.New("limit number of records is not an integer value")
+ }
+ limit = int(number.(parser.Integer).Value())
+ if limit < 0 {
+ limit = 0
+ }
}
+
+ if view.RecordLen() <= limit {
+ return nil
+ }
+
+ if clause.IsWithTies() && 0 < len(view.sortIndices) {
+ bottomRecord := view.Records[limit-1]
+ for limit < view.RecordLen() {
+ if !bottomRecord.Match(view.Records[limit], view.sortIndices) {
+ break
+ }
+ limit++
+ }
+ }
+
+ view.Records = view.Records[:limit]
+ records := make(Records, view.RecordLen())
+ copy(records, view.Records)
+ view.Records = records
+ return nil
}
func (view *View) InsertValues(fields []parser.Expression, list []parser.Expression) error {
@@ -855,6 +956,8 @@ func (view *View) Fix() {
view.parentFilter = Filter(nil)
view.sortIndices = []int(nil)
view.sortDirections = []int(nil)
+ view.sortNullPositions = []int(nil)
+ view.offset = 0
}
func (view *View) Union(calcView *View, all bool) {
@@ -967,9 +1070,17 @@ func (view *View) Less(i, j int) bool {
continue
case ternary.UNKNOWN:
if parser.IsNull(pi) {
- t = ternary.TRUE
+ if view.sortNullPositions[k] == parser.FIRST {
+ return true
+ } else {
+ return false
+ }
} else if parser.IsNull(pj) {
- t = ternary.FALSE
+ if view.sortNullPositions[k] == parser.FIRST {
+ return false
+ } else {
+ return true
+ }
} else {
continue
}
diff --git a/lib/query/view_test.go b/lib/query/view_test.go
index 90230d09..e1a7112c 100644
--- a/lib/query/view_test.go
+++ b/lib/query/view_test.go
@@ -734,7 +734,7 @@ var viewWhereTests = []struct {
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: "="},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -979,7 +979,7 @@ var viewHavingTests = []struct {
Operator: parser.Token{Token: parser.COMPARISON_OP, Literal: ">"},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "Having Not Grouped",
@@ -1116,7 +1116,7 @@ var viewSelectTests = []struct {
{Reference: "table2", Column: INTERNAL_ID_COLUMN},
{Reference: "table2", Column: "column3", FromTable: true},
{Reference: "table2", Column: "column4", FromTable: true},
- {Alias: "a"},
+ {Column: "1", Alias: "a"},
},
Records: []Record{
NewRecordWithoutId([]parser.Primary{
@@ -1215,7 +1215,7 @@ var viewSelectTests = []struct {
Result: &View{
Header: []HeaderField{
{Reference: "table1", Column: "column1", FromTable: true},
- {Alias: "a"},
+ {Column: "1", Alias: "a"},
},
Records: []Record{
NewRecordWithoutId([]parser.Primary{
@@ -1266,7 +1266,7 @@ var viewSelectTests = []struct {
{Reference: "table1", Column: INTERNAL_ID_COLUMN},
{Reference: "table1", Column: "column1", FromTable: true},
{Reference: "table1", Column: "column2", FromTable: true},
- {Alias: "sum(column1)"},
+ {Column: "sum(column1)", Alias: "sum(column1)"},
},
Records: []Record{
{
@@ -1279,6 +1279,333 @@ var viewSelectTests = []struct {
selectFields: []int{3},
},
},
+ {
+ Name: "Select Analytic Function",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ },
+ },
+ Select: parser.SelectClause{
+ Fields: []parser.Expression{
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
+ parser.Field{
+ Object: parser.AnalyticFunction{
+ Name: "row_number",
+ Over: "over",
+ AnalyticClause: parser.AnalyticClause{
+ Partition: parser.Partition{
+ PartitionBy: "partition by",
+ Values: []parser.Expression{
+ parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
+ },
+ },
+ OrderByClause: parser.OrderByClause{
+ OrderBy: "order by",
+ Items: []parser.Expression{
+ parser.OrderItem{
+ Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}},
+ },
+ },
+ },
+ },
+ },
+ Alias: parser.Identifier{Literal: "rownum"},
+ },
+ },
+ },
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ {Column: "row_number() over (partition by column1 order by column2)", Alias: "rownum"},
+ },
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ parser.NewInteger(3),
+ }),
+ },
+ selectFields: []int{0, 1, 2},
+ },
+ },
+ {
+ Name: "Select Analytic Function Not Exist Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ },
+ },
+ Select: parser.SelectClause{
+ Fields: []parser.Expression{
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
+ parser.Field{
+ Object: parser.AnalyticFunction{
+ Name: "notexist",
+ Over: "over",
+ AnalyticClause: parser.AnalyticClause{
+ Partition: parser.Partition{
+ PartitionBy: "partition by",
+ Values: []parser.Expression{
+ parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
+ },
+ },
+ OrderByClause: parser.OrderByClause{
+ OrderBy: "order by",
+ Items: []parser.Expression{
+ parser.OrderItem{
+ Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}},
+ },
+ },
+ },
+ },
+ },
+ Alias: parser.Identifier{Literal: "rownum"},
+ },
+ },
+ },
+ Error: "function notexist does not exist",
+ },
+ {
+ Name: "Select Analytic Function Option Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ },
+ },
+ Select: parser.SelectClause{
+ Fields: []parser.Expression{
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
+ parser.Field{
+ Object: parser.AnalyticFunction{
+ Name: "row_number",
+ Option: parser.Option{
+ Distinct: parser.Token{Token: parser.DISTINCT, Literal: "distinct"},
+ },
+ Over: "over",
+ AnalyticClause: parser.AnalyticClause{
+ Partition: parser.Partition{
+ PartitionBy: "partition by",
+ Values: []parser.Expression{
+ parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
+ },
+ },
+ OrderByClause: parser.OrderByClause{
+ OrderBy: "order by",
+ Items: []parser.Expression{
+ parser.OrderItem{
+ Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}},
+ },
+ },
+ },
+ },
+ },
+ Alias: parser.Identifier{Literal: "rownum"},
+ },
+ },
+ },
+ Error: "syntax error: unexpected distinct",
+ },
+ {
+ Name: "Select Analytic Function Order Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ },
+ },
+ Select: parser.SelectClause{
+ Fields: []parser.Expression{
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
+ parser.Field{
+ Object: parser.AnalyticFunction{
+ Name: "row_number",
+ Over: "over",
+ AnalyticClause: parser.AnalyticClause{
+ Partition: parser.Partition{
+ PartitionBy: "partition by",
+ Values: []parser.Expression{
+ parser.FieldReference{Column: parser.Identifier{Literal: "column1"}},
+ },
+ },
+ OrderByClause: parser.OrderByClause{
+ OrderBy: "order by",
+ Items: []parser.Expression{
+ parser.OrderItem{
+ Value: parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
+ },
+ },
+ },
+ },
+ },
+ Alias: parser.Identifier{Literal: "rownum"},
+ },
+ },
+ },
+ Error: "field notexist does not exist",
+ },
+ {
+ Name: "Select Analytic Function Partition Value Error",
+ View: &View{
+ Header: NewHeaderWithoutId("table1", []string{"column1", "column2"}),
+ Records: []Record{
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(2),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(3),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(5),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("a"),
+ parser.NewInteger(1),
+ }),
+ NewRecordWithoutId([]parser.Primary{
+ parser.NewString("b"),
+ parser.NewInteger(4),
+ }),
+ },
+ },
+ Select: parser.SelectClause{
+ Fields: []parser.Expression{
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}},
+ parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}}},
+ parser.Field{
+ Object: parser.AnalyticFunction{
+ Name: "row_number",
+ Over: "over",
+ AnalyticClause: parser.AnalyticClause{
+ Partition: parser.Partition{
+ PartitionBy: "partition by",
+ Values: []parser.Expression{
+ parser.FieldReference{Column: parser.Identifier{Literal: "notexist"}},
+ },
+ },
+ OrderByClause: parser.OrderByClause{
+ OrderBy: "order by",
+ Items: []parser.Expression{
+ parser.OrderItem{
+ Value: parser.FieldReference{Column: parser.Identifier{Literal: "column2"}},
+ },
+ },
+ },
+ },
+ },
+ Alias: parser.Identifier{Literal: "rownum"},
+ },
+ },
+ },
+ Error: "field notexist does not exist",
+ },
}
func TestView_Select(t *testing.T) {
@@ -1355,17 +1682,17 @@ var viewOrderByTests = []struct {
OrderBy: parser.OrderByClause{
Items: []parser.Expression{
parser.OrderItem{
- Item: parser.Identifier{Literal: "column1"},
+ Value: parser.Identifier{Literal: "column1"},
},
parser.OrderItem{
- Item: parser.Identifier{Literal: "column2"},
+ Value: parser.Identifier{Literal: "column2"},
Direction: parser.Token{Token: parser.DESC, Literal: "desc"},
},
parser.OrderItem{
- Item: parser.Identifier{Literal: "column3"},
+ Value: parser.Identifier{Literal: "column3"},
},
parser.OrderItem{
- Item: parser.NewInteger(1),
+ Value: parser.NewInteger(1),
},
},
},
@@ -1375,9 +1702,15 @@ var viewOrderByTests = []struct {
{Reference: "table1", Column: "column1", FromTable: true},
{Reference: "table1", Column: "column2", FromTable: true},
{Reference: "table1", Column: "column3", FromTable: true},
- {Alias: "1"},
+ {Column: "1"},
},
Records: []Record{
+ NewRecord(5, []parser.Primary{
+ parser.NewNull(),
+ parser.NewString("2"),
+ parser.NewString("4"),
+ parser.NewInteger(1),
+ }),
NewRecord(2, []parser.Primary{
parser.NewString("1"),
parser.NewString("4"),
@@ -1402,24 +1735,91 @@ var viewOrderByTests = []struct {
parser.NewString("2"),
parser.NewInteger(1),
}),
- NewRecord(5, []parser.Primary{
+ },
+ },
+ },
+ {
+ Name: "Order By With Null Positions",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("2"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("2"),
+ }),
+ NewRecord(3, []parser.Primary{
parser.NewNull(),
parser.NewString("2"),
- parser.NewString("4"),
- parser.NewInteger(1),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewNull(),
+ }),
+ NewRecord(5, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("2"),
}),
},
},
- },
-}
-
-func TestView_OrderBy(t *testing.T) {
- for _, v := range viewOrderByTests {
- err := v.View.OrderBy(v.OrderBy)
- if err != nil {
- if len(v.Error) < 1 {
- t.Errorf("%s: unexpected error %q", v.Name, err)
- } else if err.Error() != v.Error {
+ OrderBy: parser.OrderByClause{
+ Items: []parser.Expression{
+ parser.OrderItem{
+ Value: parser.Identifier{Literal: "column1"},
+ Position: parser.Token{Token: parser.LAST, Literal: "last"},
+ },
+ parser.OrderItem{
+ Value: parser.Identifier{Literal: "column2"},
+ Position: parser.Token{Token: parser.FIRST, Literal: "first"},
+ },
+ },
+ },
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(4, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewNull(),
+ }),
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("2"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("2"),
+ }),
+ NewRecord(5, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("2"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewNull(),
+ parser.NewString("2"),
+ }),
+ },
+ },
+ },
+}
+
+func TestView_OrderBy(t *testing.T) {
+ for _, v := range viewOrderByTests {
+ err := v.View.OrderBy(v.OrderBy)
+ if err != nil {
+ if len(v.Error) < 1 {
+ t.Errorf("%s: unexpected error %q", v.Name, err)
+ } else if err.Error() != v.Error {
t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
}
continue
@@ -1437,143 +1837,637 @@ func TestView_OrderBy(t *testing.T) {
}
}
-func TestView_Limit(t *testing.T) {
- view := &View{
- Header: []HeaderField{
- {Reference: "table1", Column: INTERNAL_ID_COLUMN},
- {Reference: "table1", Column: "column1", FromTable: true},
- {Reference: "table1", Column: "column2", FromTable: true},
+var viewLimitTests = []struct {
+ Name string
+ View *View
+ Limit parser.LimitClause
+ Result *View
+ Error string
+}{
+ {
+ Name: "Limit",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("3"),
+ parser.NewString("str3"),
+ }),
+ },
},
- Records: []Record{
- NewRecord(1, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(2, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(3, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(4, []parser.Primary{
- parser.NewString("2"),
- parser.NewString("str2"),
- }),
+ Limit: parser.LimitClause{Value: parser.NewInteger(2)},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
},
- }
- limit := parser.LimitClause{Number: 2}
- expect := &View{
- Header: []HeaderField{
- {Reference: "table1", Column: INTERNAL_ID_COLUMN},
- {Reference: "table1", Column: "column1", FromTable: true},
- {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ {
+ Name: "Limit With Ties",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("3"),
+ parser.NewString("str3"),
+ }),
+ },
+ sortIndices: []int{1, 2},
},
- Records: []Record{
- NewRecord(1, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(2, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
+ Limit: parser.LimitClause{Value: parser.NewInteger(2), With: parser.LimitWith{Type: parser.Token{Token: parser.TIES}}},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ sortIndices: []int{1, 2},
},
- }
-
- view.Limit(limit)
- if !reflect.DeepEqual(view, expect) {
- t.Errorf("limit: view = %s, want %s", view, expect)
- }
-}
-
-func TestView_Offset(t *testing.T) {
- view := &View{
- Header: []HeaderField{
- {Reference: "table1", Column: INTERNAL_ID_COLUMN},
- {Reference: "table1", Column: "column1", FromTable: true},
- {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ {
+ Name: "Limit By Percentage",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("3"),
+ parser.NewString("str3"),
+ }),
+ },
+ offset: 1,
},
- Records: []Record{
- NewRecord(1, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(2, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(3, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(4, []parser.Primary{
- parser.NewString("2"),
- parser.NewString("str2"),
- }),
+ Limit: parser.LimitClause{Value: parser.NewFloat(50.5), Percent: "percent"},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ },
+ offset: 1,
},
- }
-
- offset := parser.OffsetClause{Number: 3}
- expect := &View{
- Header: []HeaderField{
- {Reference: "table1", Column: INTERNAL_ID_COLUMN},
- {Reference: "table1", Column: "column1", FromTable: true},
- {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ {
+ Name: "Limit By Over 100 Percentage",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("3"),
+ parser.NewString("str3"),
+ }),
+ },
},
- Records: []Record{
- NewRecord(4, []parser.Primary{
- parser.NewString("2"),
- parser.NewString("str2"),
- }),
+ Limit: parser.LimitClause{Value: parser.NewFloat(150), Percent: "percent"},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("3"),
+ parser.NewString("str3"),
+ }),
+ },
},
- }
+ },
+ {
+ Name: "Limit By Negative Percentage",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("3"),
+ parser.NewString("str3"),
+ }),
+ },
+ },
+ Limit: parser.LimitClause{Value: parser.NewFloat(-10), Percent: "percent"},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{},
+ },
+ },
+ {
+ Name: "Limit Greater Than Records",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ Limit: parser.LimitClause{Value: parser.NewInteger(5)},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ },
+ {
+ Name: "Limit Evaluate Error",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ Limit: parser.LimitClause{Value: parser.Variable{Name: "notexist"}},
+ Error: "variable notexist is undefined",
+ },
+ {
+ Name: "Limit Value Error",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ Limit: parser.LimitClause{Value: parser.NewString("str")},
+ Error: "limit number of records is not an integer value",
+ },
+ {
+ Name: "Limit Negative Value",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ Limit: parser.LimitClause{Value: parser.NewInteger(-1)},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{},
+ },
+ },
+ {
+ Name: "Limit By Percentage Value Error",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ Limit: parser.LimitClause{Value: parser.NewString("str"), Percent: "percent"},
+ Error: "limit percentage is not a float value",
+ },
+}
- view.Offset(offset)
- if !reflect.DeepEqual(view, expect) {
- t.Errorf("offset: view = %s, want %s", view, expect)
+func TestView_Limit(t *testing.T) {
+ for _, v := range viewLimitTests {
+ err := v.View.Limit(v.Limit)
+ if err != nil {
+ if len(v.Error) < 1 {
+ t.Errorf("%s: unexpected error %q", v.Name, err)
+ } else if err.Error() != v.Error {
+ t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
+ }
+ continue
+ }
+ if 0 < len(v.Error) {
+ t.Errorf("%s: no error, want error %q", v.Name, v.Error)
+ continue
+ }
+ if !reflect.DeepEqual(v.View, v.Result) {
+ t.Errorf("%s: view = %s, want %s", v.Name, v.View, v.Result)
+ }
}
+}
- view = &View{
- Header: []HeaderField{
- {Reference: "table1", Column: INTERNAL_ID_COLUMN},
- {Reference: "table1", Column: "column1", FromTable: true},
- {Reference: "table1", Column: "column2", FromTable: true},
+var viewOffsetTests = []struct {
+ Name string
+ View *View
+ Offset parser.OffsetClause
+ Result *View
+ Error string
+}{
+ {
+ Name: "Offset",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ },
},
- Records: []Record{
- NewRecord(1, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(2, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(3, []parser.Primary{
- parser.NewString("1"),
- parser.NewString("str1"),
- }),
- NewRecord(4, []parser.Primary{
- parser.NewString("2"),
- parser.NewString("str2"),
- }),
+ Offset: parser.OffsetClause{Value: parser.NewInteger(3)},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ },
+ offset: 3,
},
- }
-
- offset = parser.OffsetClause{Number: 4}
- expect = &View{
- Header: []HeaderField{
- {Reference: "table1", Column: INTERNAL_ID_COLUMN},
- {Reference: "table1", Column: "column1", FromTable: true},
- {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ {
+ Name: "Offset Equal To Record Length",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ },
},
- Records: []Record{},
- }
+ Offset: parser.OffsetClause{Value: parser.NewInteger(4)},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{},
+ offset: 4,
+ },
+ },
+ {
+ Name: "Offset Evaluate Error",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ },
+ },
+ Offset: parser.OffsetClause{Value: parser.Variable{Name: "notexist"}},
+ Error: "variable notexist is undefined",
+ },
+ {
+ Name: "Offset Value Error",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(3, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(4, []parser.Primary{
+ parser.NewString("2"),
+ parser.NewString("str2"),
+ }),
+ },
+ },
+ Offset: parser.OffsetClause{Value: parser.NewString("str")},
+ Error: "offset number is not an integer",
+ },
+ {
+ Name: "Offset Negative Number",
+ View: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ },
+ Offset: parser.OffsetClause{Value: parser.NewInteger(-3)},
+ Result: &View{
+ Header: []HeaderField{
+ {Reference: "table1", Column: INTERNAL_ID_COLUMN},
+ {Reference: "table1", Column: "column1", FromTable: true},
+ {Reference: "table1", Column: "column2", FromTable: true},
+ },
+ Records: []Record{
+ NewRecord(1, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ NewRecord(2, []parser.Primary{
+ parser.NewString("1"),
+ parser.NewString("str1"),
+ }),
+ },
+ offset: 0,
+ },
+ },
+}
- view.Offset(offset)
- if !reflect.DeepEqual(view, expect) {
- t.Errorf("offset: view = %s, want %s", view, expect)
+func TestView_Offset(t *testing.T) {
+ for _, v := range viewOffsetTests {
+ err := v.View.Offset(v.Offset)
+ if err != nil {
+ if len(v.Error) < 1 {
+ t.Errorf("%s: unexpected error %q", v.Name, err)
+ } else if err.Error() != v.Error {
+ t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error)
+ }
+ continue
+ }
+ if 0 < len(v.Error) {
+ t.Errorf("%s: no error, want error %q", v.Name, v.Error)
+ continue
+ }
+ if !reflect.DeepEqual(v.View, v.Result) {
+ t.Errorf("%s: view = %s, want %s", v.Name, v.View, v.Result)
+ }
}
}
@@ -1663,7 +2557,7 @@ var viewInsertValuesTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
{
Name: "InsertValues Field Does Not Exist Error",
@@ -1679,7 +2573,7 @@ var viewInsertValuesTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
@@ -1792,7 +2686,7 @@ var viewInsertFromQueryTests = []struct {
},
},
},
- Error: "identifier = notexist: field does not exist",
+ Error: "field notexist does not exist",
},
}
diff --git a/main.go b/main.go
index 6df30149..1ff4ecfb 100644
--- a/main.go
+++ b/main.go
@@ -11,7 +11,7 @@ import (
"github.com/urfave/cli"
)
-var version = "v0.2.2"
+var version = "v0.2.3"
func main() {
cli.AppHelpTemplate = appHHelpTemplate