diff --git a/ADOPTERS.md b/ADOPTERS.md index f36b4b44c21..11ee7b0efdf 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -5,6 +5,7 @@ This is an alphabetical list of known adopters of Vitess. Some have already gone * [BetterCloud](http://bettercloud.com) * [FlipKart](http://flipkart.com) * [HubSpot](http://product.hubspot.com/) +* [JD](http://jd.com/) * [Nozzle](http://nozzle.io) * [Pixel Federation](http://pixelfederation.com) * [Quiz of Kings](http://quizofkings.com) diff --git a/data/test/vtgate/dml_cases.txt b/data/test/vtgate/dml_cases.txt index 7a7a7e80354..41930d54083 100644 --- a/data/test/vtgate/dml_cases.txt +++ b/data/test/vtgate/dml_cases.txt @@ -921,6 +921,33 @@ } } +# insert with multiple rows - multi-shard autocommit +"insert /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ into user(id) values (1), (2)" +{ + "Original": "insert /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ into user(id) values (1), (2)", + "Instructions": { + "Opcode": "InsertSharded", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "insert /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ into user(id, Name, Costly) values (:_Id0, :_Name0, :_Costly0), (:_Id1, :_Name1, :_Costly1)", + "Values": [[[":__seq0",":__seq1"]],[[null,null]],[[null,null]]], + "Table": "user", + "Generate": { + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "Query": "select next :n values from seq", + "Values": [1,2] + }, + "Prefix": "insert /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ into user(id, Name, Costly) values ", + "Mid": ["(:_Id0, :_Name0, :_Costly0)","(:_Id1, :_Name1, :_Costly1)"], + "MultiShardAutocommit": true + } +} + # simple replace unsharded "replace into unsharded values(1, 2)" { @@ -1253,6 +1280,22 @@ } } +# delete from with no index match - multi shard autocommit +"delete /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ from user_extra where name = 'jose'" +{ + "Original": "delete /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ from user_extra where name = 'jose'", + "Instructions": { + "Opcode": "DeleteScatter", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "Query": "delete /*vt+ MULTI_SHARD_AUTOCOMMIT=1 */ from user_extra where name = 'jose'", + "Table": "user_extra", + "MultiShardAutocommit": true + } +} + # delete from with primary id in through IN clause "delete from user_extra where user_id in (1, 2)" { diff --git a/doc/ServerConfiguration.md b/doc/ServerConfiguration.md index 7cd2449bf2d..03ba9670b59 100644 --- a/doc/ServerConfiguration.md +++ b/doc/ServerConfiguration.md @@ -61,7 +61,7 @@ RBR will eventually be supported by Vitess. ### Data types -Vitess supports data types at the MySQL 5.5 level. The newer data types like spatial or JSON are not supported yet. Additionally, the TIMESTAMP data type should not be used in a primary key or sharding column. Otherwise, Vitess cannot predict those values correctly and this may result in data corruption. +Vitess supports all data types including newer data types like spatial and JSON. Additionally, the TIMESTAMP data type should not be used in a primary key or sharding column. Otherwise, Vitess cannot predict those values correctly and this may result in data corruption. ### No side effects @@ -676,4 +676,3 @@ Orchestrator, it also means new instances will be discovered immediately, and the topology will automatically repopulate even if Orchestrator's backing store is wiped out. Note that Orchestrator will forget stale instances after a configurable timeout. - diff --git a/doc/VitessReplication.md b/doc/VitessReplication.md index b69bd5fa9e9..fe06568b0cb 100644 --- a/doc/VitessReplication.md +++ b/doc/VitessReplication.md @@ -3,70 +3,16 @@ ## Statement vs Row Based Replication MySQL supports two primary modes of replication in its binary logs: statement or -row based. - -**Statement Based Replication**: - -* The statements executed on the master are copied almost as-is in the master - logs. -* The slaves replay these statements as is. -* If the statements are expensive (especially an update with a complicated WHERE - clause), they will be expensive on the slaves too. -* For current timestamp and auto-increment values, the master also puts - additional SET statements in the logs to make the statement have the same - effect, so the slaves end up with the same values. - -**Row Based Replication**: - -* The statements executed on the master result in updated rows. The new full - values for these rows are copied to the master logs. -* The slaves change their records for the rows they receive. The update is by - primary key, and contains the new values for each column, so usually it’s very - fast. -* Each updated row contains the entire row, not just the columns that were - updated (unless the flag --binlog\_row\_image=minimal is used). -* The replication stream is harder to read, as it contains almost binary data, - that don’t easily map to the original statements. -* There is a configurable limit on how many rows can be affected by one - binlog event, so the master logs are not flooded. -* The format of the logs depends on the master schema: each row has a list of - values, one value for each column. So if the master schema is different from - the slave schema, updates will misbehave (exception being if slave has extra - columns at the end). -* It is possible to revert to statement based replication for some commands to - avoid these drawbacks (for instance for DELETE statements that affect a large - number of rows). -* Schema changes always use statement based replication. -* If comments are added to a statement, they are stripped from the - replication stream (as only rows are transmitted). There is a flag - --binlog\_rows\_query\_log\_events to add the original statement to each row - update, but it is costly in terms of binlog size. - -For the longest time, MySQL replication has been single-threaded: only one -statement is applied by the slaves at a time. Since the master applies more -statements in parallel, replication can fall behind on the slaves fairly easily, -under higher load. Even though the situation has improved (parallel slave -apply), the slave replication speed is still a limiting factor for a lot of -applications. Since row based replication achieves higher update rates on the -slaves in most cases, it has been the only viable option for most performance -sensitive applications. - -Schema changes however are not easy to achieve with row based -replication. Adding columns can be done offline, but removing or changing -columns cannot easily be done (there are multiple ways to achieve this, but they -all have limitations or performance implications, and are not that easy to -setup). - -Vitess helps by using statement based replication (therefore allowing complex -schema changes), while at the same time simplifying the replication stream (so -slaves can be fast), by rewriting Update statements. - -Then, with statement based replication, it becomes easier to perform offline -advanced schema changes, or large data updates. Vitess’s solution is called -schema swap. +row based. Vitess supports both these modes. + +For schema changes, if the number of affected rows is greater > 100k (configurable), we don't allow direct application +of DDLs. The recommended tools in such cases are [gh-ost](https://github.com/github/gh-ost) or [pt-osc](https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html). -We plan to also support row based replication in the future, and adapt our tools -to provide the same features when possible. See Appendix for our plan. +Not all statements are safe for Statement Based Replication (SBR): https://dev.mysql.com/doc/refman/8.0/en/replication-rbr-safe-unsafe.html. Vitess rewrites some of these statements to be safe for SBR, and others are explicitly failed. This is described in detail below. + +With statement based replication, it becomes easier to perform offline +advanced schema changes, or large data updates. Vitess’s solution is called +schema swap (described below). ## Rewriting Update Statements diff --git a/go/cmd/vtcombo/main.go b/go/cmd/vtcombo/main.go index b3e30c44960..30eca302d16 100644 --- a/go/cmd/vtcombo/main.go +++ b/go/cmd/vtcombo/main.go @@ -38,6 +38,7 @@ import ( "vitess.io/vitess/go/vt/srvtopo" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vtcombo" "vitess.io/vitess/go/vt/vtctld" "vitess.io/vitess/go/vt/vtgate" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv" @@ -109,7 +110,7 @@ func main() { servenv.OnClose(mysqld.Close) // tablets configuration and init - if err := initTabletMap(ts, tpb, mysqld, *dbcfgs, *schemaDir, mycnf); err != nil { + if err := vtcombo.InitTabletMap(ts, tpb, mysqld, *dbcfgs, *schemaDir, mycnf); err != nil { log.Errorf("initTabletMapProto failed: %v", err) exit.Return(1) } diff --git a/go/mysql/conn.go b/go/mysql/conn.go index 343021eb344..183ae00a80e 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -579,31 +579,31 @@ func (c *Conn) writeEphemeralPacket(direct bool) error { // Just write c.buffer as a single buffer. // It has both header and data. if n, err := w.Write(c.buffer); err != nil { - return fmt.Errorf("Write(c.buffer) failed: %v", err) + return fmt.Errorf("Conn %v: Write(c.buffer) failed: %v", c.ID(), err) } else if n != len(c.buffer) { - return fmt.Errorf("Write(c.buffer) returned a short write: %v < %v", n, len(c.buffer)) + return fmt.Errorf("Conn %v: Write(c.buffer) returned a short write: %v < %v", c.ID(), n, len(c.buffer)) } case ephemeralWriteSingleBuffer: // Write the allocated buffer as a single buffer. // It has both header and data. if n, err := w.Write(c.currentEphemeralPacket); err != nil { - return fmt.Errorf("Write(c.currentEphemeralPacket) failed: %v", err) + return fmt.Errorf("Conn %v: Write(c.currentEphemeralPacket) failed: %v", c.ID(), err) } else if n != len(c.currentEphemeralPacket) { - return fmt.Errorf("Write(c.currentEphemeralPacket) returned a short write: %v < %v", n, len(c.currentEphemeralPacket)) + return fmt.Errorf("Conn %v: Write(c.currentEphemeralPacket) returned a short write: %v < %v", c.ID(), n, len(c.currentEphemeralPacket)) } case ephemeralWriteBigBuffer: // This is the slower path for big data. // With direct=true, the caller expects a flush, so we call it // manually. if err := c.writePacket(c.currentEphemeralPacket); err != nil { - return err + return fmt.Errorf("Conn %v: %v", c.ID(), err) } if direct { return c.flush() } case ephemeralUnused, ephemeralReadGlobalBuffer, ephemeralReadSingleBuffer, ephemeralReadBigBuffer: // Programming error. - panic(fmt.Errorf("trying to call writeEphemeralPacket while currentEphemeralPolicy is %v", c.currentEphemeralPolicy)) + panic(fmt.Errorf("Conn %v: trying to call writeEphemeralPacket while currentEphemeralPolicy is %v", c.ID(), c.currentEphemeralPolicy)) } return nil @@ -613,7 +613,7 @@ func (c *Conn) writeEphemeralPacket(direct bool) error { // This method returns a generic error, not a SQLError. func (c *Conn) flush() error { if err := c.writer.Flush(); err != nil { - return fmt.Errorf("Flush() failed: %v", err) + return fmt.Errorf("Conn %v: Flush() failed: %v", c.ID(), err) } return nil } diff --git a/go/mysql/ldapauthserver/auth_server_ldap.go b/go/mysql/ldapauthserver/auth_server_ldap.go index 1aeac844e59..a51e8ca3b11 100644 --- a/go/mysql/ldapauthserver/auth_server_ldap.go +++ b/go/mysql/ldapauthserver/auth_server_ldap.go @@ -25,7 +25,7 @@ import ( "sync" "time" - "gopkg.in/ldap.v2" + ldap "gopkg.in/ldap.v2" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/netutil" "vitess.io/vitess/go/vt/log" diff --git a/go/mysql/ldapauthserver/auth_server_ldap_test.go b/go/mysql/ldapauthserver/auth_server_ldap_test.go index 863df7a06cf..fd9daef65ac 100644 --- a/go/mysql/ldapauthserver/auth_server_ldap_test.go +++ b/go/mysql/ldapauthserver/auth_server_ldap_test.go @@ -20,7 +20,7 @@ import ( "fmt" "testing" - "gopkg.in/ldap.v2" + ldap "gopkg.in/ldap.v2" ) type MockLdapClient struct{} diff --git a/go/mysql/server.go b/go/mysql/server.go index 41923172747..10807762c32 100644 --- a/go/mysql/server.go +++ b/go/mysql/server.go @@ -42,7 +42,7 @@ const ( var ( // Metrics - timings = stats.NewTimings("MysqlServerTimings", "MySQL server timings") + timings = stats.NewTimings("MysqlServerTimings", "MySQL server timings", "operation") connCount = stats.NewGauge("MysqlServerConnCount", "Active MySQL server connections") connAccept = stats.NewCounter("MysqlServerConnAccepted", "Connections accepted by MySQL server") connSlow = stats.NewCounter("MysqlServerConnSlow", "Connections that took more than the configured mysql_slow_connect_warn_threshold to establish") diff --git a/go/stats/counter.go b/go/stats/counter.go new file mode 100644 index 00000000000..bf1956089a5 --- /dev/null +++ b/go/stats/counter.go @@ -0,0 +1,156 @@ +/* +Copyright 2018 The Vitess Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package stats + +import ( + "strconv" + "time" + + "vitess.io/vitess/go/sync2" + "vitess.io/vitess/go/vt/logutil" +) + +// logCounterNegative is for throttling adding a negative value to a counter messages in logs +var logCounterNegative = logutil.NewThrottledLogger("StatsCounterNegative", 1*time.Minute) + +// Counter tracks a cumulative count of a metric. +// For a one-dimensional or multi-dimensional counter, please use +// CountersWithSingleLabel or CountersWithMultiLabels instead. +type Counter struct { + i sync2.AtomicInt64 + help string +} + +// NewCounter returns a new Counter. +func NewCounter(name string, help string) *Counter { + v := &Counter{help: help} + if name != "" { + publish(name, v) + } + return v +} + +// Add adds the provided value to the Counter. +func (v *Counter) Add(delta int64) { + if delta < 0 { + logCounterNegative.Warningf("Adding a negative value to a counter, %v should be a gauge instead", v) + } + v.i.Add(delta) +} + +// Reset resets the counter value to 0. +func (v *Counter) Reset() { + v.i.Set(int64(0)) +} + +// Get returns the value. +func (v *Counter) Get() int64 { + return v.i.Get() +} + +// String implements the expvar.Var interface. +func (v *Counter) String() string { + return strconv.FormatInt(v.i.Get(), 10) +} + +// Help returns the help string. +func (v *Counter) Help() string { + return v.help +} + +// CounterFunc allows to provide the counter value via a custom function. +// For implementations that differentiate between Counters/Gauges, +// CounterFunc's values only go up (or are reset to 0). +type CounterFunc struct { + F func() int64 + help string +} + +// NewCounterFunc creates a new CounterFunc instance and publishes it if name is +// set. +func NewCounterFunc(name string, help string, f func() int64) *CounterFunc { + c := &CounterFunc{ + F: f, + help: help, + } + + if name != "" { + publish(name, c) + } + return c +} + +// Help returns the help string. +func (cf CounterFunc) Help() string { + return cf.help +} + +// String implements expvar.Var. +func (cf CounterFunc) String() string { + return strconv.FormatInt(cf.F(), 10) +} + +// Gauge tracks the current value of an integer metric. +// The emphasis here is on *current* i.e. this is not a cumulative counter. +// For a one-dimensional or multi-dimensional gauge, please use +// GaugeWithSingleLabel or GaugesWithMultiLabels instead. +type Gauge struct { + Counter +} + +// NewGauge creates a new Gauge and publishes it if name is set. +func NewGauge(name string, help string) *Gauge { + v := &Gauge{Counter: Counter{help: help}} + + if name != "" { + publish(name, v) + } + return v +} + +// Set overwrites the current value. +func (v *Gauge) Set(value int64) { + v.Counter.i.Set(value) +} + +// Add adds the provided value to the Gauge. +func (v *Gauge) Add(delta int64) { + v.Counter.i.Add(delta) +} + +// GaugeFunc is the same as CounterFunc but meant for gauges. +// It's a wrapper around CounterFunc for values that go up/down for +// implementations (like Prometheus) that need to differ between Counters and +// Gauges. +type GaugeFunc struct { + CounterFunc +} + +// NewGaugeFunc creates a new GaugeFunc instance and publishes it if name is +// set. +func NewGaugeFunc(name string, help string, f func() int64) *GaugeFunc { + i := &GaugeFunc{ + CounterFunc: CounterFunc{ + F: f, + help: help, + }} + + if name != "" { + publish(name, i) + } + return i +} diff --git a/go/stats/counter_test.go b/go/stats/counter_test.go new file mode 100644 index 00000000000..465621acf3e --- /dev/null +++ b/go/stats/counter_test.go @@ -0,0 +1,73 @@ +/* +Copyright 2018 The Vitess Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package stats + +import ( + "expvar" + "testing" +) + +func TestCounter(t *testing.T) { + var gotname string + var gotv *Counter + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*Counter) + }) + v := NewCounter("Int", "help") + if gotname != "Int" { + t.Errorf("want Int, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } + v.Add(1) + if v.Get() != 1 { + t.Errorf("want 1, got %v", v.Get()) + } + if v.String() != "1" { + t.Errorf("want 1, got %v", v.Get()) + } + v.Reset() + if v.Get() != 0 { + t.Errorf("want 0, got %v", v.Get()) + } +} + +func TestGaugeFunc(t *testing.T) { + var gotname string + var gotv *GaugeFunc + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*GaugeFunc) + }) + + v := NewGaugeFunc("name", "help", func() int64 { + return 1 + }) + if gotname != "name" { + t.Errorf("want name, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } + if v.String() != "1" { + t.Errorf("want 1, got %v", v.String()) + } +} diff --git a/go/stats/counters.go b/go/stats/counters.go index d71f01fbe8b..bc22dd7a2ca 100644 --- a/go/stats/counters.go +++ b/go/stats/counters.go @@ -19,98 +19,27 @@ package stats import ( "bytes" "fmt" - "strconv" "strings" "sync" "sync/atomic" - "time" - - "vitess.io/vitess/go/sync2" - "vitess.io/vitess/go/vt/logutil" ) -// logCounterNegative is for throttling adding a negative value to a counter messages in logs -var logCounterNegative = logutil.NewThrottledLogger("StatsCounterNegative", 1*time.Minute) - -// Counter is expvar.Int+Get+hook -type Counter struct { - i sync2.AtomicInt64 - help string -} - -// NewCounter returns a new Counter -func NewCounter(name string, help string) *Counter { - v := &Counter{help: help} - if name != "" { - publish(name, v) - } - return v -} - -// Add adds the provided value to the Counter -func (v *Counter) Add(delta int64) { - if delta < 0 { - logCounterNegative.Warningf("Adding a negative value to a counter, %v should be a gauge instead", v) - } - v.i.Add(delta) -} - -// Reset resets the counter value to 0 -func (v *Counter) Reset() { - v.i.Set(int64(0)) -} - -// Get returns the value -func (v *Counter) Get() int64 { - return v.i.Get() -} - -// String is the implementation of expvar.var -func (v *Counter) String() string { - return strconv.FormatInt(v.i.Get(), 10) -} - -// Help returns the help string -func (v *Counter) Help() string { - return v.help -} - -// Gauge is an unlabeled metric whose values can go up/down. -type Gauge struct { - Counter -} - -// NewGauge creates a new Gauge and publishes it if name is set -func NewGauge(name string, help string) *Gauge { - v := &Gauge{Counter: Counter{help: help}} - - if name != "" { - publish(name, v) - } - return v -} - -// Set sets the value -func (v *Gauge) Set(value int64) { - v.Counter.i.Set(value) -} - -// Add adds the provided value to the Gauge -func (v *Gauge) Add(delta int64) { - v.Counter.i.Add(delta) -} - -// counters is similar to expvar.Map, except that -// it doesn't allow floats. It is used to build CountersWithLabels and GaugesWithLabels. +// counters is similar to expvar.Map, except that it doesn't allow floats. +// It is used to build CountersWithSingleLabel and GaugesWithSingleLabel. type counters struct { - // mu only protects adding and retrieving the value (*int64) from the map, - // modification to the actual number (int64) should be done with atomic funcs. + // mu only protects adding and retrieving the value (*int64) from the + // map. + // The modification to the actual number (int64) must be done with + // atomic funcs. + // If a value for a given name already exists in the map, we only have + // to use a read-lock to retrieve it. This is an important performance + // optimizations because it allows to concurrently increment a counter. mu sync.RWMutex counts map[string]*int64 help string } -// String implements expvar +// String implements the expvar.Var interface. func (c *counters) String() string { b := bytes.NewBuffer(make([]byte, 0, 4096)) @@ -166,7 +95,7 @@ func (c *counters) ResetAll() { c.counts = make(map[string]*int64) } -// Reset resets a specific counter value to 0 +// Reset resets a specific counter value to 0. func (c *counters) Reset(name string) { a := c.getValueAddr(name) atomic.StoreInt64(a, int64(0)) @@ -189,24 +118,27 @@ func (c *counters) Help() string { return c.help } -// CountersWithLabels provides a labelName for the tagged values in Counters +// CountersWithSingleLabel tracks multiple counter values for a single +// dimension ("label"). // It provides a Counts method which can be used for tracking rates. -type CountersWithLabels struct { +type CountersWithSingleLabel struct { counters - labelName string + label string } -// NewCountersWithLabels create a new Counters instance. If name is set, the variable -// gets published. The function also accepts an optional list of tags that -// pre-creates them initialized to 0. -// labelName is a category name used to organize the tags in Prometheus. -func NewCountersWithLabels(name string, help string, labelName string, tags ...string) *CountersWithLabels { - c := &CountersWithLabels{ +// NewCountersWithSingleLabel create a new Counters instance. +// If name is set, the variable gets published. +// The function also accepts an optional list of tags that pre-creates them +// initialized to 0. +// label is a category name used to organize the tags. It is currently only +// used by Prometheus, but not by the expvar package. +func NewCountersWithSingleLabel(name, help, label string, tags ...string) *CountersWithSingleLabel { + c := &CountersWithSingleLabel{ counters: counters{ counts: make(map[string]*int64), help: help, }, - labelName: labelName, + label: label, } for _, tag := range tags { @@ -218,13 +150,13 @@ func NewCountersWithLabels(name string, help string, labelName string, tags ...s return c } -// LabelName returns the label name. -func (c *CountersWithLabels) LabelName() string { - return c.labelName +// Label returns the label name. +func (c *CountersWithSingleLabel) Label() string { + return c.label } // Add adds a value to a named counter. -func (c *CountersWithLabels) Add(name string, value int64) { +func (c *CountersWithSingleLabel) Add(name string, value int64) { if value < 0 { logCounterNegative.Warningf("Adding a negative value to a counter, %v should be a gauge instead", c) } @@ -232,123 +164,116 @@ func (c *CountersWithLabels) Add(name string, value int64) { atomic.AddInt64(a, value) } -// GaugesWithLabels is similar to CountersWithLabels, except its values can go up and down. -type GaugesWithLabels struct { - CountersWithLabels +// CountersWithMultiLabels is a multidimensional counters implementation. +// Internally, each tuple of dimensions ("labels") is stored as a single +// label value where all label values are joined with ".". +type CountersWithMultiLabels struct { + counters + labels []string } -// NewGaugesWithLabels creates a new GaugesWithLabels and publishes it if the name is set. -func NewGaugesWithLabels(name string, help string, labelName string, tags ...string) *GaugesWithLabels { - g := &GaugesWithLabels{CountersWithLabels: CountersWithLabels{counters: counters{ - counts: make(map[string]*int64), - help: help, - }, labelName: labelName}} - - for _, tag := range tags { - g.CountersWithLabels.counts[tag] = new(int64) +// NewCountersWithMultiLabels creates a new CountersWithMultiLabels +// instance, and publishes it if name is set. +func NewCountersWithMultiLabels(name, help string, labels []string) *CountersWithMultiLabels { + t := &CountersWithMultiLabels{ + counters: counters{ + counts: make(map[string]*int64), + help: help}, + labels: labels, } if name != "" { - publish(name, g) + publish(name, t) } - return g -} -// Set sets the value of a named gauge. -func (g *GaugesWithLabels) Set(name string, value int64) { - a := g.CountersWithLabels.getValueAddr(name) - atomic.StoreInt64(a, value) -} - -// Add adds a value to a named gauge. -func (g *GaugesWithLabels) Add(name string, value int64) { - a := g.getValueAddr(name) - atomic.AddInt64(a, value) + return t } -// CounterFunc converts a function that returns -// an int64 as an expvar. -// For implementations that differentiate between Counters/Gauges, -// CounterFunc's values only go up (or are reset to 0) -type CounterFunc struct { - Mf MetricFunc - help string +// Labels returns the list of labels. +func (mc *CountersWithMultiLabels) Labels() []string { + return mc.labels } -// NewCounterFunc creates a new CounterFunc instance and publishes it if name is set -func NewCounterFunc(name string, help string, Mf MetricFunc) *CounterFunc { - c := &CounterFunc{ - Mf: Mf, - help: help, +// Add adds a value to a named counter. +// len(names) must be equal to len(Labels) +func (mc *CountersWithMultiLabels) Add(names []string, value int64) { + if len(names) != len(mc.labels) { + panic("CountersWithMultiLabels: wrong number of values in Add") } - - if name != "" { - publish(name, c) + if value < 0 { + logCounterNegative.Warningf("Adding a negative value to a counter, %v should be a gauge instead", mc) } - return c -} -// Help returns the help string -func (cf *CounterFunc) Help() string { - return cf.help + mc.counters.Add(mapKey(names), value) } -// String implements expvar.Var -func (cf *CounterFunc) String() string { - return cf.Mf.String() -} +// Reset resets the value of a named counter back to 0. +// len(names) must be equal to len(Labels). +func (mc *CountersWithMultiLabels) Reset(names []string) { + if len(names) != len(mc.labels) { + panic("CountersWithMultiLabels: wrong number of values in Reset") + } -// MetricFunc defines an interface for things that can be exported with calls to stats.CounterFunc/stats.GaugeFunc -type MetricFunc interface { - FloatVal() float64 - String() string + mc.counters.Reset(mapKey(names)) } -// IntFunc converst a function that returns an int64 as both an expvar and a MetricFunc -type IntFunc func() int64 - -// FloatVal is the implementation of MetricFunc -func (f IntFunc) FloatVal() float64 { - return float64(f()) +// Counts returns a copy of the Counters' map. +// The key is a single string where all labels are joined by a "." e.g. +// "label1.label2". +func (mc *CountersWithMultiLabels) Counts() map[string]int64 { + return mc.counters.Counts() } -// String is the implementation of expvar.var -func (f IntFunc) String() string { - return strconv.FormatInt(f(), 10) +// CountersFuncWithMultiLabels is a multidimensional counters implementation +// where names of categories are compound names made with joining +// multiple strings with '.'. Since the map is returned by the +// function, we assume it's in the right format (meaning each key is +// of the form 'aaa.bbb.ccc' with as many elements as there are in +// Labels). +// +// Note that there is no CountersFuncWithSingleLabel object. That this +// because such an object would be identical to this one because these +// function-based counters have no Add() or Set() method which are different +// for the single vs. multiple labels cases. +// If you have only a single label, pass an array with a single element. +type CountersFuncWithMultiLabels struct { + f func() map[string]int64 + help string + labels []string } -// GaugeFunc converts a function that returns an int64 as an expvar. -// It's a wrapper around CounterFunc for values that go up/down -// for implementations (like Prometheus) that need to differ between Counters and Gauges. -type GaugeFunc struct { - CounterFunc +// Labels returns the list of labels. +func (c CountersFuncWithMultiLabels) Labels() []string { + return c.labels } -// NewGaugeFunc creates a new GaugeFunc instance and publishes it if name is set -func NewGaugeFunc(name string, help string, Mf MetricFunc) *GaugeFunc { - i := &GaugeFunc{ - CounterFunc: CounterFunc{ - Mf: Mf, - help: help, - }} +// Help returns the help string. +func (c CountersFuncWithMultiLabels) Help() string { + return c.help +} +// NewCountersFuncWithMultiLabels creates a new CountersFuncWithMultiLabels +// mapping to the provided function. +func NewCountersFuncWithMultiLabels(name, help string, labels []string, f func() map[string]int64) *CountersFuncWithMultiLabels { + t := &CountersFuncWithMultiLabels{ + f: f, + help: help, + labels: labels, + } if name != "" { - publish(name, i) + publish(name, t) } - return i -} -// CountersFunc converts a function that returns -// a map of int64 as an expvar. -type CountersFunc func() map[string]int64 + return t +} -// Counts returns a copy of the Counters' map. -func (f CountersFunc) Counts() map[string]int64 { - return f() +// Counts returns a copy of the counters' map. +func (c CountersFuncWithMultiLabels) Counts() map[string]int64 { + return c.f() } -// String is used by expvar. -func (f CountersFunc) String() string { - m := f() +// String implements the expvar.Var interface. +func (c CountersFuncWithMultiLabels) String() string { + m := c.f() if m == nil { return "{}" } @@ -367,78 +292,61 @@ func (f CountersFunc) String() string { return b.String() } -// CountersWithMultiLabels is a multidimensional Counters implementation where -// names of categories are compound names made with joining multiple -// strings with '.'. -type CountersWithMultiLabels struct { - counters - labels []string +// GaugesWithSingleLabel is similar to CountersWithSingleLabel, except its +// meant to track the current value and not a cumulative count. +type GaugesWithSingleLabel struct { + CountersWithSingleLabel } -// NewCountersWithMultiLabels creates a new CountersWithMultiLabels instance, and publishes it -// if name is set. -func NewCountersWithMultiLabels(name string, help string, labels []string) *CountersWithMultiLabels { - t := &CountersWithMultiLabels{ - counters: counters{ - counts: make(map[string]*int64), - help: help}, - labels: labels, - } - if name != "" { - publish(name, t) +// NewGaugesWithSingleLabel creates a new GaugesWithSingleLabel and +// publishes it if the name is set. +func NewGaugesWithSingleLabel(name, help, label string, tags ...string) *GaugesWithSingleLabel { + g := &GaugesWithSingleLabel{ + CountersWithSingleLabel: CountersWithSingleLabel{ + counters: counters{ + counts: make(map[string]*int64), + help: help, + }, + label: label, + }, } - return t -} - -// Labels returns the list of labels. -func (mc *CountersWithMultiLabels) Labels() []string { - return mc.labels -} - -// Add adds a value to a named counter. len(names) must be equal to -// len(Labels) -func (mc *CountersWithMultiLabels) Add(names []string, value int64) { - if len(names) != len(mc.labels) { - panic("CountersWithMultiLabels: wrong number of values in Add") + for _, tag := range tags { + g.counts[tag] = new(int64) } - if value < 0 { - logCounterNegative.Warningf("Adding a negative value to a counter, %v should be a gauge instead", mc) + if name != "" { + publish(name, g) } - - mc.counters.Add(mapKey(names), value) + return g } -// Reset resets the value of a named counter back to 0. len(names) -// must be equal to len(Labels) -func (mc *CountersWithMultiLabels) Reset(names []string) { - if len(names) != len(mc.labels) { - panic("CountersWithMultiLabels: wrong number of values in Reset") - } - - mc.counters.Reset(mapKey(names)) +// Set sets the value of a named gauge. +func (g *GaugesWithSingleLabel) Set(name string, value int64) { + a := g.getValueAddr(name) + atomic.StoreInt64(a, value) } -// Counts returns a copy of the Counters' map. -// The key is a single string where all labels are joiend by a "." e.g. -// "label1.label2". -func (mc *CountersWithMultiLabels) Counts() map[string]int64 { - return mc.counters.Counts() +// Add adds a value to a named gauge. +func (g *GaugesWithSingleLabel) Add(name string, value int64) { + a := g.getValueAddr(name) + atomic.AddInt64(a, value) } -// GaugesWithMultiLabels is a CountersWithMultiLabels implementation where the values can go up and down +// GaugesWithMultiLabels is a CountersWithMultiLabels implementation where +// the values can go up and down. type GaugesWithMultiLabels struct { CountersWithMultiLabels } -// NewGaugesWithMultiLabels creates a new GaugesWithMultiLabels instance, and publishes it -// if name is set. -func NewGaugesWithMultiLabels(name string, help string, labels []string) *GaugesWithMultiLabels { +// NewGaugesWithMultiLabels creates a new GaugesWithMultiLabels instance, +// and publishes it if name is set. +func NewGaugesWithMultiLabels(name, help string, labels []string) *GaugesWithMultiLabels { t := &GaugesWithMultiLabels{ - CountersWithMultiLabels: CountersWithMultiLabels{counters: counters{ - counts: make(map[string]*int64), - help: help, - }, + CountersWithMultiLabels: CountersWithMultiLabels{ + counters: counters{ + counts: make(map[string]*int64), + help: help, + }, labels: labels, }} if name != "" { @@ -448,8 +356,8 @@ func NewGaugesWithMultiLabels(name string, help string, labels []string) *Gauges return t } -// Set sets the value of a named counter. len(names) must be equal to -// len(Labels) +// Set sets the value of a named counter. +// len(names) must be equal to len(Labels). func (mg *GaugesWithMultiLabels) Set(names []string, value int64) { if len(names) != len(mg.CountersWithMultiLabels.labels) { panic("GaugesWithMultiLabels: wrong number of values in Set") @@ -458,8 +366,8 @@ func (mg *GaugesWithMultiLabels) Set(names []string, value int64) { atomic.StoreInt64(a, value) } -// Add adds a value to a named gauge. len(names) must be equal to -// len(Labels) +// Add adds a value to a named gauge. +// len(names) must be equal to len(Labels). func (mg *GaugesWithMultiLabels) Add(names []string, value int64) { if len(names) != len(mg.labels) { panic("CountersWithMultiLabels: wrong number of values in Add") @@ -468,57 +376,21 @@ func (mg *GaugesWithMultiLabels) Add(names []string, value int64) { mg.counters.Add(mapKey(names), value) } -// CountersFuncWithMultiLabels is a multidimensional CountersFunc implementation -// where names of categories are compound names made with joining -// multiple strings with '.'. Since the map is returned by the -// function, we assume it's in the right format (meaning each key is -// of the form 'aaa.bbb.ccc' with as many elements as there are in -// Labels). -type CountersFuncWithMultiLabels struct { - CountersFunc - labels []string - help string -} - -// Labels returns the list of labels. -func (mcf *CountersFuncWithMultiLabels) Labels() []string { - return mcf.labels -} - -// Help returns the help string -func (mcf *CountersFuncWithMultiLabels) Help() string { - return mcf.help -} - -// NewCountersFuncWithMultiLabels creates a new CountersFuncWithMultiLabels mapping to the provided -// function. -func NewCountersFuncWithMultiLabels(name string, labels []string, help string, f CountersFunc) *CountersFuncWithMultiLabels { - t := &CountersFuncWithMultiLabels{ - CountersFunc: f, - labels: labels, - help: help, - } - if name != "" { - publish(name, t) - } - - return t -} - // GaugesFuncWithMultiLabels is a wrapper around CountersFuncWithMultiLabels -// for values that go up/down for implementations (like Prometheus) that need to differ between Counters and Gauges. +// for values that go up/down for implementations (like Prometheus) that +// need to differ between Counters and Gauges. type GaugesFuncWithMultiLabels struct { CountersFuncWithMultiLabels } -// NewGaugesFuncWithMultiLabels creates a new GaugesFuncWithMultiLabels mapping to the provided -// function. -func NewGaugesFuncWithMultiLabels(name string, labels []string, help string, f CountersFunc) *GaugesFuncWithMultiLabels { +// NewGaugesFuncWithMultiLabels creates a new GaugesFuncWithMultiLabels +// mapping to the provided function. +func NewGaugesFuncWithMultiLabels(name, help string, labels []string, f func() map[string]int64) *GaugesFuncWithMultiLabels { t := &GaugesFuncWithMultiLabels{ CountersFuncWithMultiLabels: CountersFuncWithMultiLabels{ - CountersFunc: f, - labels: labels, - help: help, + f: f, + help: help, + labels: labels, }} if name != "" { diff --git a/go/stats/counters_test.go b/go/stats/counters_test.go index 43cf800f6da..be01e5637ce 100644 --- a/go/stats/counters_test.go +++ b/go/stats/counters_test.go @@ -27,7 +27,7 @@ import ( func TestCounters(t *testing.T) { clear() - c := NewCountersWithLabels("counter1", "help", "type") + c := NewCountersWithSingleLabel("counter1", "help", "label") c.Add("c1", 1) c.Add("c2", 1) c.Add("c2", 1) @@ -43,27 +43,18 @@ func TestCounters(t *testing.T) { if counts["c2"] != 2 { t.Errorf("want 2, got %d", counts["c2"]) } - f := CountersFunc(func() map[string]int64 { - return map[string]int64{ - "c1": 1, - "c2": 2, - } - }) - if s := f.String(); s != want1 && s != want2 { - t.Errorf("want %s or %s, got %s", want1, want2, s) - } } func TestCountersTags(t *testing.T) { clear() - c := NewCountersWithLabels("counterTag1", "help", "label") + c := NewCountersWithSingleLabel("counterTag1", "help", "label") want := map[string]int64{} got := c.Counts() if !reflect.DeepEqual(got, want) { t.Errorf("want %v, got %v", want, got) } - c = NewCountersWithLabels("counterTag2", "help", "label", "tag1", "tag2") + c = NewCountersWithSingleLabel("counterTag2", "help", "label", "tag1", "tag2") want = map[string]int64{"tag1": 0, "tag2": 0} got = c.Counts() if !reflect.DeepEqual(got, want) { @@ -89,7 +80,7 @@ func TestMultiCounters(t *testing.T) { if counts["c2a.c2b"] != 2 { t.Errorf("want 2, got %d", counts["c2a.c2b"]) } - f := NewCountersFuncWithMultiLabels("", []string{"aaa", "bbb"}, "help", func() map[string]int64 { + f := NewCountersFuncWithMultiLabels("", "help", []string{"aaa", "bbb"}, func() map[string]int64 { return map[string]int64{ "c1a.c1b": 1, "c2a.c2b": 2, @@ -122,14 +113,14 @@ func TestMultiCountersDot(t *testing.T) { func TestCountersHook(t *testing.T) { var gotname string - var gotv *CountersWithLabels + var gotv *CountersWithSingleLabel clear() Register(func(name string, v expvar.Var) { gotname = name - gotv = v.(*CountersWithLabels) + gotv = v.(*CountersWithSingleLabel) }) - v := NewCountersWithLabels("counter2", "help", "type") + v := NewCountersWithSingleLabel("counter2", "help", "label") if gotname != "counter2" { t.Errorf("want counter2, got %s", gotname) } @@ -138,7 +129,7 @@ func TestCountersHook(t *testing.T) { } } -var benchCounter = NewCountersWithLabels("bench", "help", "type") +var benchCounter = NewCountersWithSingleLabel("bench", "help", "label") func BenchmarkCounters(b *testing.B) { clear() @@ -208,3 +199,39 @@ func BenchmarkCountersTailLatency(b *testing.B) { close(c) <-done } + +func TestCountersFuncWithMultiLabels(t *testing.T) { + clear() + f := NewCountersFuncWithMultiLabels("TestCountersFuncWithMultiLabels", "help", []string{"label1"}, func() map[string]int64 { + return map[string]int64{ + "c1": 1, + "c2": 2, + } + }) + + want1 := `{"c1": 1, "c2": 2}` + want2 := `{"c2": 2, "c1": 1}` + if s := f.String(); s != want1 && s != want2 { + t.Errorf("want %s or %s, got %s", want1, want2, s) + } +} + +func TestCountersFuncWithMultiLabels_Hook(t *testing.T) { + var gotname string + var gotv *CountersFuncWithMultiLabels + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*CountersFuncWithMultiLabels) + }) + + v := NewCountersFuncWithMultiLabels("TestCountersFuncWithMultiLabels_Hook", "help", []string{"label1"}, func() map[string]int64 { + return map[string]int64{} + }) + if gotname != "TestCountersFuncWithMultiLabels_Hook" { + t.Errorf("want TestCountersFuncWithMultiLabels_Hook, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } +} diff --git a/go/stats/duration.go b/go/stats/duration.go new file mode 100644 index 00000000000..3e32054915f --- /dev/null +++ b/go/stats/duration.go @@ -0,0 +1,133 @@ +/* +Copyright 2018 The Vitess Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package stats + +import ( + "strconv" + "time" + + "vitess.io/vitess/go/sync2" +) + +// CounterDuration exports a time.Duration as counter. +type CounterDuration struct { + i sync2.AtomicDuration + help string +} + +// NewCounterDuration returns a new CounterDuration. +func NewCounterDuration(name, help string) *CounterDuration { + cd := &CounterDuration{ + help: help, + } + publish(name, cd) + return cd +} + +// Help implements the Variable interface. +func (cd CounterDuration) Help() string { + return cd.help +} + +// String is the implementation of expvar.var. +func (cd CounterDuration) String() string { + return strconv.FormatInt(int64(cd.i.Get()), 10) +} + +// Add adds the provided value to the CounterDuration. +func (cd *CounterDuration) Add(delta time.Duration) { + cd.i.Add(delta) +} + +// Get returns the value. +func (cd *CounterDuration) Get() time.Duration { + return cd.i.Get() +} + +// GaugeDuration exports a time.Duration as gauge. +// In addition to CounterDuration, it also has Set() which allows overriding +// the current value. +type GaugeDuration struct { + CounterDuration +} + +// NewGaugeDuration returns a new GaugeDuration. +func NewGaugeDuration(name, help string) *GaugeDuration { + gd := &GaugeDuration{ + CounterDuration: CounterDuration{ + help: help, + }, + } + publish(name, gd) + return gd +} + +// Set sets the value. +func (gd *GaugeDuration) Set(value time.Duration) { + gd.i.Set(value) +} + +// CounterDurationFunc allows to provide the value via a custom function. +type CounterDurationFunc struct { + F func() time.Duration + help string +} + +// NewCounterDurationFunc creates a new CounterDurationFunc instance and +// publishes it if name is set. +func NewCounterDurationFunc(name string, help string, f func() time.Duration) *CounterDurationFunc { + cf := &CounterDurationFunc{ + F: f, + help: help, + } + + if name != "" { + publish(name, cf) + } + return cf +} + +// Help implements the Variable interface. +func (cf CounterDurationFunc) Help() string { + return cf.help +} + +// String is the implementation of expvar.var. +func (cf CounterDurationFunc) String() string { + return strconv.FormatInt(int64(cf.F()), 10) +} + +// GaugeDurationFunc allows to provide the value via a custom function. +type GaugeDurationFunc struct { + CounterDurationFunc +} + +// NewGaugeDurationFunc creates a new GaugeDurationFunc instance and +// publishes it if name is set. +func NewGaugeDurationFunc(name string, help string, f func() time.Duration) *GaugeDurationFunc { + gf := &GaugeDurationFunc{ + CounterDurationFunc: CounterDurationFunc{ + F: f, + help: help, + }, + } + + if name != "" { + publish(name, gf) + } + return gf +} diff --git a/go/stats/duration_test.go b/go/stats/duration_test.go new file mode 100644 index 00000000000..f661a5be590 --- /dev/null +++ b/go/stats/duration_test.go @@ -0,0 +1,125 @@ +/* +Copyright 2018 The Vitess Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package stats + +import ( + "expvar" + "testing" + "time" +) + +func TestCounterDuration(t *testing.T) { + var gotname string + var gotv *CounterDuration + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*CounterDuration) + }) + v := NewCounterDuration("CounterDuration", "help") + if gotname != "CounterDuration" { + t.Errorf("want CounterDuration, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } + if v.Get() != 0 { + t.Errorf("want 0, got %v", v.Get()) + } + v.Add(time.Duration(1)) + if v.Get() != 1 { + t.Errorf("want 1, got %v", v.Get()) + } + if v.String() != "1" { + t.Errorf("want 1, got %v", v.Get()) + } +} + +func TestCounterDurationFunc(t *testing.T) { + var gotname string + var gotv *CounterDurationFunc + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*CounterDurationFunc) + }) + + v := NewCounterDurationFunc("CounterDurationFunc", "help", func() time.Duration { + return time.Duration(1) + }) + if gotname != "CounterDurationFunc" { + t.Errorf("want CounterDurationFunc, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } + if v.String() != "1" { + t.Errorf("want 1, got %v", v.String()) + } +} + +func TestGaugeDuration(t *testing.T) { + var gotname string + var gotv *GaugeDuration + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*GaugeDuration) + }) + v := NewGaugeDuration("GaugeDuration", "help") + if gotname != "GaugeDuration" { + t.Errorf("want GaugeDuration, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } + v.Set(time.Duration(5)) + if v.Get() != 5 { + t.Errorf("want 5, got %v", v.Get()) + } + v.Add(time.Duration(1)) + if v.Get() != 6 { + t.Errorf("want 6, got %v", v.Get()) + } + if v.String() != "6" { + t.Errorf("want 6, got %v", v.Get()) + } +} + +func TestGaugeDurationFunc(t *testing.T) { + var gotname string + var gotv *GaugeDurationFunc + clear() + Register(func(name string, v expvar.Var) { + gotname = name + gotv = v.(*GaugeDurationFunc) + }) + + v := NewGaugeDurationFunc("GaugeDurationFunc", "help", func() time.Duration { + return time.Duration(1) + }) + + if gotname != "GaugeDurationFunc" { + t.Errorf("want GaugeDurationFunc, got %s", gotname) + } + if gotv != v { + t.Errorf("want %#v, got %#v", v, gotv) + } + if v.String() != "1" { + t.Errorf("want 1, got %v", v.String()) + } +} diff --git a/go/stats/export.go b/go/stats/export.go index ffd5d51759c..6239cf6cb1a 100644 --- a/go/stats/export.go +++ b/go/stats/export.go @@ -36,7 +36,6 @@ import ( "sync" "time" - "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/vt/log" ) @@ -111,11 +110,14 @@ type PushBackend interface { } var pushBackends = make(map[string]PushBackend) +var pushBackendsLock sync.Mutex var once sync.Once // RegisterPushBackend allows modules to register PushBackend implementations. // Should be called on init(). func RegisterPushBackend(name string, backend PushBackend) { + pushBackendsLock.Lock() + defer pushBackendsLock.Unlock() if _, ok := pushBackends[name]; ok { log.Fatalf("PushBackend %s already exists; can't register the same name multiple times", name) } @@ -196,52 +198,6 @@ func (f FloatFunc) String() string { return strconv.FormatFloat(f(), 'g', -1, 64) } -// Duration exports a time.Duration -type Duration struct { - i sync2.AtomicDuration -} - -// NewDuration returns a new Duration -func NewDuration(name string) *Duration { - v := new(Duration) - publish(name, v) - return v -} - -// Add adds the provided value to the Duration -func (v *Duration) Add(delta time.Duration) { - v.i.Add(delta) -} - -// Set sets the value -func (v *Duration) Set(value time.Duration) { - v.i.Set(value) -} - -// Get returns the value -func (v *Duration) Get() time.Duration { - return v.i.Get() -} - -// String is the implementation of expvar.var -func (v *Duration) String() string { - return strconv.FormatInt(int64(v.i.Get()), 10) -} - -// DurationFunc converts a function that returns -// an time.Duration as an expvar. -type DurationFunc func() time.Duration - -// String is the implementation of expvar.var -func (f DurationFunc) String() string { - return strconv.FormatInt(int64(f()), 10) -} - -// FloatVal is the implementation of MetricFunc -func (f DurationFunc) FloatVal() float64 { - return f().Seconds() -} - // String is expvar.String+Get+hook type String struct { mu sync.Mutex diff --git a/go/stats/export_test.go b/go/stats/export_test.go index b95db711fa7..32d71057c40 100644 --- a/go/stats/export_test.go +++ b/go/stats/export_test.go @@ -19,7 +19,6 @@ package stats import ( "expvar" "testing" - "time" ) func clear() { @@ -71,111 +70,6 @@ func TestFloat(t *testing.T) { } } -func TestCounter(t *testing.T) { - var gotname string - var gotv *Counter - clear() - Register(func(name string, v expvar.Var) { - gotname = name - gotv = v.(*Counter) - }) - v := NewCounter("Int", "help") - if gotname != "Int" { - t.Errorf("want Int, got %s", gotname) - } - if gotv != v { - t.Errorf("want %#v, got %#v", v, gotv) - } - v.Add(1) - if v.Get() != 1 { - t.Errorf("want 1, got %v", v.Get()) - } - if v.String() != "1" { - t.Errorf("want 1, got %v", v.Get()) - } - v.Reset() - if v.Get() != 0 { - t.Errorf("want 0, got %v", v.Get()) - } - -} - -func TestGaugeFunc(t *testing.T) { - var gotname string - var gotv *GaugeFunc - clear() - Register(func(name string, v expvar.Var) { - gotname = name - gotv = v.(*GaugeFunc) - }) - - v := NewGaugeFunc("name", "help", IntFunc(func() int64 { - return 1 - })) - if v.String() != "1" { - t.Errorf("want 1, got %f", v.String()) - } - if gotv != v { - t.Errorf("want %#v, got %#v", v, gotv) - } - if gotname != "name" { - t.Errorf("want name, got %s", gotname) - } -} - -func TestDuration(t *testing.T) { - var gotname string - var gotv *Duration - clear() - Register(func(name string, v expvar.Var) { - gotname = name - gotv = v.(*Duration) - }) - v := NewDuration("Duration") - if gotname != "Duration" { - t.Errorf("want Duration, got %s", gotname) - } - if gotv != v { - t.Errorf("want %#v, got %#v", v, gotv) - } - v.Set(time.Duration(5)) - if v.Get() != 5 { - t.Errorf("want 5, got %v", v.Get()) - } - v.Add(time.Duration(1)) - if v.Get() != 6 { - t.Errorf("want 6, got %v", v.Get()) - } - if v.String() != "6" { - t.Errorf("want 6, got %v", v.Get()) - } - -} - -func TestDurationFunc(t *testing.T) { - var gotname string - var gotv *CounterFunc - clear() - Register(func(name string, v expvar.Var) { - gotname = name - gotv = v.(*CounterFunc) - }) - - v := NewCounterFunc("duration", "help", DurationFunc(func() time.Duration { - return time.Duration(1) - })) - - if gotv != v { - t.Errorf("want %#v, got %#v", v, gotv) - } - if v.String() != "1" { - t.Errorf("want 1, got %v", v.String()) - } - if gotname != "duration" { - t.Errorf("want duration, got %s", gotname) - } -} - func TestString(t *testing.T) { var gotname string var gotv *String diff --git a/go/stats/histogram.go b/go/stats/histogram.go index 993f321a74a..c6231998bb5 100644 --- a/go/stats/histogram.go +++ b/go/stats/histogram.go @@ -27,6 +27,7 @@ import ( // splitting the counts under different buckets // using specified cutoffs. type Histogram struct { + help string cutoffs []int64 labels []string countLabel string @@ -41,24 +42,25 @@ type Histogram struct { // based on the cutoffs. The buckets are categorized using the // following criterion: cutoff[i-1] < value <= cutoff[i]. Anything // higher than the highest cutoff is labeled as "inf". -func NewHistogram(name string, cutoffs []int64) *Histogram { +func NewHistogram(name, help string, cutoffs []int64) *Histogram { labels := make([]string, len(cutoffs)+1) for i, v := range cutoffs { labels[i] = fmt.Sprintf("%d", v) } labels[len(labels)-1] = "inf" - return NewGenericHistogram(name, cutoffs, labels, "Count", "Total") + return NewGenericHistogram(name, help, cutoffs, labels, "Count", "Total") } // NewGenericHistogram creates a histogram where all the labels are // supplied by the caller. The number of labels has to be one more than // the number of cutoffs because the last label captures everything that // exceeds the highest cutoff. -func NewGenericHistogram(name string, cutoffs []int64, labels []string, countLabel, totalLabel string) *Histogram { +func NewGenericHistogram(name, help string, cutoffs []int64, labels []string, countLabel, totalLabel string) *Histogram { if len(cutoffs) != len(labels)-1 { panic("mismatched cutoff and label lengths") } h := &Histogram{ + help: help, cutoffs: cutoffs, labels: labels, countLabel: countLabel, @@ -160,3 +162,8 @@ func (h *Histogram) Buckets() []int64 { } return buckets } + +// Help returns the help string. +func (h *Histogram) Help() string { + return h.help +} diff --git a/go/stats/histogram_test.go b/go/stats/histogram_test.go index f0cb07105ed..91e340b3b29 100644 --- a/go/stats/histogram_test.go +++ b/go/stats/histogram_test.go @@ -23,7 +23,7 @@ import ( func TestHistogram(t *testing.T) { clear() - h := NewHistogram("hist1", []int64{1, 5}) + h := NewHistogram("hist1", "help", []int64{1, 5}) for i := 0; i < 10; i++ { h.Add(int64(i)) } @@ -57,6 +57,7 @@ func TestGenericHistogram(t *testing.T) { clear() h := NewGenericHistogram( "histgen", + "help", []int64{1, 5}, []string{"one", "five", "max"}, "count", @@ -78,7 +79,7 @@ func TestHistogramHook(t *testing.T) { }) name := "hist2" - v := NewHistogram(name, []int64{1}) + v := NewHistogram(name, "help", []int64{1}) if gotname != name { t.Errorf("got %v; want %v", gotname, name) } diff --git a/go/stats/multidimensional.go b/go/stats/multidimensional.go index 007cc0a2216..0d85c073103 100644 --- a/go/stats/multidimensional.go +++ b/go/stats/multidimensional.go @@ -34,19 +34,21 @@ type MultiTracker interface { func CounterForDimension(mt MultiTracker, dimension string) CountTracker { for i, lab := range mt.Labels() { if lab == dimension { - return CountersFunc(func() map[string]int64 { - result := make(map[string]int64) - for k, v := range mt.Counts() { - if k == "All" { - result[k] = v - continue + return wrappedCountTracker{ + f: func() map[string]int64 { + result := make(map[string]int64) + for k, v := range mt.Counts() { + if k == "All" { + result[k] = v + continue + } + result[strings.Split(k, ".")[i]] += v } - result[strings.Split(k, ".")[i]] += v - } - return result - }) + return result + }, + } } } - panic(fmt.Sprintf("label %v is not one of %v", dimension, mt.Labels())) + panic(fmt.Sprintf("label %v is not one of %v", dimension, mt.Labels())) } diff --git a/go/stats/prometheusbackend/collectors.go b/go/stats/prometheusbackend/collectors.go index e5d02f80da6..65293154828 100644 --- a/go/stats/prometheusbackend/collectors.go +++ b/go/stats/prometheusbackend/collectors.go @@ -7,36 +7,63 @@ import ( "vitess.io/vitess/go/stats" ) -type metricCollector struct { - counter *stats.Counter - desc *prometheus.Desc - vt prometheus.ValueType +type metricFuncCollector struct { + // f returns the floating point value of the metric. + f func() float64 + desc *prometheus.Desc + vt prometheus.ValueType +} + +func newMetricFuncCollector(v stats.Variable, name string, vt prometheus.ValueType, f func() float64) { + collector := &metricFuncCollector{ + f: f, + desc: prometheus.NewDesc( + name, + v.Help(), + nil, + nil), + vt: vt} + + prometheus.MustRegister(collector) } // Describe implements Collector. -func (c *metricCollector) Describe(ch chan<- *prometheus.Desc) { - ch <- c.desc +func (mc *metricFuncCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- mc.desc } // Collect implements Collector. -func (c *metricCollector) Collect(ch chan<- prometheus.Metric) { - ch <- prometheus.MustNewConstMetric(c.desc, c.vt, float64(c.counter.Get())) +func (mc *metricFuncCollector) Collect(ch chan<- prometheus.Metric) { + ch <- prometheus.MustNewConstMetric(mc.desc, mc.vt, float64(mc.f())) } -// countersWithLabelsCollector collects stats.CountersWithLabels -type countersWithLabelsCollector struct { - counters *stats.CountersWithLabels +// countersWithSingleLabelCollector collects stats.CountersWithSingleLabel. +type countersWithSingleLabelCollector struct { + counters *stats.CountersWithSingleLabel desc *prometheus.Desc vt prometheus.ValueType } +func newCountersWithSingleLabelCollector(c *stats.CountersWithSingleLabel, name string, labelName string, vt prometheus.ValueType) { + collector := &countersWithSingleLabelCollector{ + counters: c, + desc: prometheus.NewDesc( + name, + c.Help(), + []string{labelName}, + nil), + vt: vt} + + prometheus.MustRegister(collector) +} + // Describe implements Collector. -func (c *countersWithLabelsCollector) Describe(ch chan<- *prometheus.Desc) { +func (c *countersWithSingleLabelCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.desc } // Collect implements Collector. -func (c *countersWithLabelsCollector) Collect(ch chan<- prometheus.Metric) { +func (c *countersWithSingleLabelCollector) Collect(ch chan<- prometheus.Metric) { for tag, val := range c.counters.Counts() { ch <- prometheus.MustNewConstMetric( c.desc, @@ -46,20 +73,33 @@ func (c *countersWithLabelsCollector) Collect(ch chan<- prometheus.Metric) { } } -// gaugesWithLabelsCollector collects stats.GaugesWithLabels -type gaugesWithLabelsCollector struct { - gauges *stats.GaugesWithLabels +// gaugesWithSingleLabelCollector collects stats.GaugesWithSingleLabel. +type gaugesWithSingleLabelCollector struct { + gauges *stats.GaugesWithSingleLabel desc *prometheus.Desc vt prometheus.ValueType } +func newGaugesWithSingleLabelCollector(g *stats.GaugesWithSingleLabel, name string, labelName string, vt prometheus.ValueType) { + collector := &gaugesWithSingleLabelCollector{ + gauges: g, + desc: prometheus.NewDesc( + name, + g.Help(), + []string{labelName}, + nil), + vt: vt} + + prometheus.MustRegister(collector) +} + // Describe implements Collector. -func (g *gaugesWithLabelsCollector) Describe(ch chan<- *prometheus.Desc) { +func (g *gaugesWithSingleLabelCollector) Describe(ch chan<- *prometheus.Desc) { ch <- g.desc } // Collect implements Collector. -func (g *gaugesWithLabelsCollector) Collect(ch chan<- prometheus.Metric) { +func (g *gaugesWithSingleLabelCollector) Collect(ch chan<- prometheus.Metric) { for tag, val := range g.gauges.Counts() { ch <- prometheus.MustNewConstMetric( g.desc, @@ -74,6 +114,19 @@ type metricWithMultiLabelsCollector struct { desc *prometheus.Desc } +func newMetricWithMultiLabelsCollector(cml *stats.CountersWithMultiLabels, name string) { + c := &metricWithMultiLabelsCollector{ + cml: cml, + desc: prometheus.NewDesc( + name, + cml.Help(), + labelsToSnake(cml.Labels()), + nil), + } + + prometheus.MustRegister(c) +} + // Describe implements Collector. func (c *metricWithMultiLabelsCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.desc @@ -88,18 +141,31 @@ func (c *metricWithMultiLabelsCollector) Collect(ch chan<- prometheus.Metric) { } } -type multiGaugesCollector struct { +type gaugesWithMultiLabelsCollector struct { gml *stats.GaugesWithMultiLabels desc *prometheus.Desc } +func newGaugesWithMultiLabelsCollector(gml *stats.GaugesWithMultiLabels, name string) { + c := &gaugesWithMultiLabelsCollector{ + gml: gml, + desc: prometheus.NewDesc( + name, + gml.Help(), + labelsToSnake(gml.Labels()), + nil), + } + + prometheus.MustRegister(c) +} + // Describe implements Collector. -func (c *multiGaugesCollector) Describe(ch chan<- *prometheus.Desc) { +func (c *gaugesWithMultiLabelsCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.desc } // Collect implements Collector. -func (c *multiGaugesCollector) Collect(ch chan<- prometheus.Metric) { +func (c *gaugesWithMultiLabelsCollector) Collect(ch chan<- prometheus.Metric) { for lvs, val := range c.gml.Counts() { labelValues := strings.Split(lvs, ".") value := float64(val) @@ -113,6 +179,20 @@ type metricsFuncWithMultiLabelsCollector struct { vt prometheus.ValueType } +func newMetricsFuncWithMultiLabelsCollector(cfml *stats.CountersFuncWithMultiLabels, name string, vt prometheus.ValueType) { + collector := &metricsFuncWithMultiLabelsCollector{ + cfml: cfml, + desc: prometheus.NewDesc( + name, + cfml.Help(), + labelsToSnake(cfml.Labels()), + nil), + vt: vt, + } + + prometheus.MustRegister(collector) +} + // Describe implements Collector. func (c *metricsFuncWithMultiLabelsCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.desc @@ -128,8 +208,28 @@ func (c *metricsFuncWithMultiLabelsCollector) Collect(ch chan<- prometheus.Metri } type timingsCollector struct { - t *stats.Timings - desc *prometheus.Desc + t *stats.Timings + cutoffs []float64 + desc *prometheus.Desc +} + +func newTimingsCollector(t *stats.Timings, name string) { + cutoffs := make([]float64, len(t.Cutoffs())) + for i, val := range t.Cutoffs() { + cutoffs[i] = float64(val) / 1000000000 + } + + collector := &timingsCollector{ + t: t, + cutoffs: cutoffs, + desc: prometheus.NewDesc( + name, + t.Help(), + []string{t.Label()}, + nil), + } + + prometheus.MustRegister(collector) } // Describe implements Collector. @@ -144,16 +244,15 @@ func (c *timingsCollector) Collect(ch chan<- prometheus.Metric) { c.desc, uint64(his.Count()), float64(his.Total()), - makePromBucket(his.Cutoffs(), his.Buckets()), + makeCumulativeBuckets(c.cutoffs, his.Buckets()), cat) } } -func makePromBucket(cutoffs []int64, buckets []int64) map[float64]uint64 { +func makeCumulativeBuckets(cutoffs []float64, buckets []int64) map[float64]uint64 { output := make(map[float64]uint64) last := uint64(0) - for i := range cutoffs { - key := float64(cutoffs[i]) / 1000000000 + for i, key := range cutoffs { //TODO(zmagg): int64 => uint64 conversion. error if it overflows? output[key] = uint64(buckets[i]) + last last = output[key] @@ -162,8 +261,28 @@ func makePromBucket(cutoffs []int64, buckets []int64) map[float64]uint64 { } type multiTimingsCollector struct { - mt *stats.MultiTimings - desc *prometheus.Desc + mt *stats.MultiTimings + cutoffs []float64 + desc *prometheus.Desc +} + +func newMultiTimingsCollector(mt *stats.MultiTimings, name string) { + cutoffs := make([]float64, len(mt.Cutoffs())) + for i, val := range mt.Cutoffs() { + cutoffs[i] = float64(val) / 1000000000 + } + + collector := &multiTimingsCollector{ + mt: mt, + cutoffs: cutoffs, + desc: prometheus.NewDesc( + name, + mt.Help(), + labelsToSnake(mt.Labels()), + nil), + } + + prometheus.MustRegister(collector) } // Describe implements Collector. @@ -179,23 +298,47 @@ func (c *multiTimingsCollector) Collect(ch chan<- prometheus.Metric) { c.desc, uint64(his.Count()), float64(his.Total()), - makePromBucket(his.Cutoffs(), his.Buckets()), + makeCumulativeBuckets(c.cutoffs, his.Buckets()), labelValues...) } } -type metricFuncCollector struct { - cf *stats.CounterFunc - desc *prometheus.Desc - vt prometheus.ValueType +type histogramCollector struct { + h *stats.Histogram + cutoffs []float64 + desc *prometheus.Desc +} + +func newHistogramCollector(h *stats.Histogram, name string) { + cutoffs := make([]float64, len(h.Cutoffs())) + for i, val := range h.Cutoffs() { + cutoffs[i] = float64(val) + } + + collector := &histogramCollector{ + h: h, + cutoffs: cutoffs, + desc: prometheus.NewDesc( + name, + h.Help(), + []string{}, + nil), + } + + prometheus.MustRegister(collector) } // Describe implements Collector. -func (c *metricFuncCollector) Describe(ch chan<- *prometheus.Desc) { +func (c *histogramCollector) Describe(ch chan<- *prometheus.Desc) { ch <- c.desc } // Collect implements Collector. -func (c *metricFuncCollector) Collect(ch chan<- prometheus.Metric) { - ch <- prometheus.MustNewConstMetric(c.desc, c.vt, float64(c.cf.Mf.FloatVal())) +func (c *histogramCollector) Collect(ch chan<- prometheus.Metric) { + ch <- prometheus.MustNewConstHistogram( + c.desc, + uint64(c.h.Count()), + float64(c.h.Total()), + makeCumulativeBuckets(c.cutoffs, c.h.Buckets()), + ) } diff --git a/go/stats/prometheusbackend/prometheusbackend.go b/go/stats/prometheusbackend/prometheusbackend.go index 2dbfaa027e3..00a3b55222b 100644 --- a/go/stats/prometheusbackend/prometheusbackend.go +++ b/go/stats/prometheusbackend/prometheusbackend.go @@ -18,170 +18,62 @@ type PromBackend struct { } var ( - be *PromBackend + be PromBackend logUnsupported *logutil.ThrottledLogger ) // Init initializes the Prometheus be with the given namespace. func Init(namespace string) { http.Handle("/metrics", promhttp.Handler()) - be := &PromBackend{namespace: namespace} + be.namespace = namespace logUnsupported = logutil.NewThrottledLogger("PrometheusUnsupportedMetricType", 1*time.Minute) stats.Register(be.publishPrometheusMetric) } // PublishPromMetric is used to publish the metric to Prometheus. -func (be *PromBackend) publishPrometheusMetric(name string, v expvar.Var) { +func (be PromBackend) publishPrometheusMetric(name string, v expvar.Var) { switch st := v.(type) { case *stats.Counter: - be.newMetric(st, name, prometheus.CounterValue) - case *stats.Gauge: - be.newMetric(&st.Counter, name, prometheus.GaugeValue) + newMetricFuncCollector(st, be.buildPromName(name), prometheus.CounterValue, func() float64 { return float64(st.Get()) }) case *stats.CounterFunc: - be.newMetricFunc(st, name, prometheus.CounterValue) + newMetricFuncCollector(st, be.buildPromName(name), prometheus.CounterValue, func() float64 { return float64(st.F()) }) + case *stats.Gauge: + newMetricFuncCollector(st, be.buildPromName(name), prometheus.GaugeValue, func() float64 { return float64(st.Get()) }) case *stats.GaugeFunc: - be.newMetricFunc(&st.CounterFunc, name, prometheus.GaugeValue) - case *stats.CountersWithLabels: - be.newCountersWithLabels(st, name, st.LabelName(), prometheus.CounterValue) + newMetricFuncCollector(st, be.buildPromName(name), prometheus.GaugeValue, func() float64 { return float64(st.F()) }) + case *stats.CountersWithSingleLabel: + newCountersWithSingleLabelCollector(st, be.buildPromName(name), st.Label(), prometheus.CounterValue) case *stats.CountersWithMultiLabels: - be.newCountersWithMultiLabels(st, name) + newMetricWithMultiLabelsCollector(st, be.buildPromName(name)) case *stats.CountersFuncWithMultiLabels: - be.newMetricsFuncWithMultiLabels(st, name, prometheus.CounterValue) + newMetricsFuncWithMultiLabelsCollector(st, be.buildPromName(name), prometheus.CounterValue) case *stats.GaugesFuncWithMultiLabels: - be.newMetricsFuncWithMultiLabels(&st.CountersFuncWithMultiLabels, name, prometheus.GaugeValue) - case *stats.GaugesWithLabels: - be.newGaugesWithLabels(st, name, st.LabelName(), prometheus.GaugeValue) + newMetricsFuncWithMultiLabelsCollector(&st.CountersFuncWithMultiLabels, be.buildPromName(name), prometheus.GaugeValue) + case *stats.GaugesWithSingleLabel: + newGaugesWithSingleLabelCollector(st, be.buildPromName(name), st.Label(), prometheus.GaugeValue) case *stats.GaugesWithMultiLabels: - be.newGaugesWithMultiLabels(st, name) + newGaugesWithMultiLabelsCollector(st, be.buildPromName(name)) + case *stats.CounterDuration: + newMetricFuncCollector(st, be.buildPromName(name), prometheus.CounterValue, func() float64 { return st.Get().Seconds() }) + case *stats.CounterDurationFunc: + newMetricFuncCollector(st, be.buildPromName(name), prometheus.CounterValue, func() float64 { return st.F().Seconds() }) + case *stats.GaugeDuration: + newMetricFuncCollector(st, be.buildPromName(name), prometheus.GaugeValue, func() float64 { return st.Get().Seconds() }) + case *stats.GaugeDurationFunc: + newMetricFuncCollector(st, be.buildPromName(name), prometheus.GaugeValue, func() float64 { return st.F().Seconds() }) case *stats.Timings: - be.newTiming(st, name) + newTimingsCollector(st, be.buildPromName(name)) case *stats.MultiTimings: - be.newMultiTiming(st, name) + newMultiTimingsCollector(st, be.buildPromName(name)) + case *stats.Histogram: + newHistogramCollector(st, be.buildPromName(name)) default: logUnsupported.Infof("Not exporting to Prometheus an unsupported metric type of %T: %s", st, name) } } -func (be *PromBackend) newCountersWithLabels(c *stats.CountersWithLabels, name string, labelName string, vt prometheus.ValueType) { - collector := &countersWithLabelsCollector{ - counters: c, - desc: prometheus.NewDesc( - be.buildPromName(name), - c.Help(), - []string{labelName}, - nil), - vt: vt} - - prometheus.MustRegister(collector) -} - -func (be *PromBackend) newGaugesWithLabels(g *stats.GaugesWithLabels, name string, labelName string, vt prometheus.ValueType) { - collector := &gaugesWithLabelsCollector{ - gauges: g, - desc: prometheus.NewDesc( - be.buildPromName(name), - g.Help(), - []string{labelName}, - nil), - vt: vt} - - prometheus.MustRegister(collector) -} - -func (be *PromBackend) newCountersWithMultiLabels(cml *stats.CountersWithMultiLabels, name string) { - c := &metricWithMultiLabelsCollector{ - cml: cml, - desc: prometheus.NewDesc( - be.buildPromName(name), - cml.Help(), - labelsToSnake(cml.Labels()), - nil), - } - - prometheus.MustRegister(c) -} - -func (be *PromBackend) newGaugesWithMultiLabels(gml *stats.GaugesWithMultiLabels, name string) { - c := &multiGaugesCollector{ - gml: gml, - desc: prometheus.NewDesc( - be.buildPromName(name), - gml.Help(), - labelsToSnake(gml.Labels()), - nil), - } - - prometheus.MustRegister(c) -} - -func (be *PromBackend) newMetricsFuncWithMultiLabels(cfml *stats.CountersFuncWithMultiLabels, name string, vt prometheus.ValueType) { - collector := &metricsFuncWithMultiLabelsCollector{ - cfml: cfml, - desc: prometheus.NewDesc( - be.buildPromName(name), - cfml.Help(), - labelsToSnake(cfml.Labels()), - nil), - vt: vt, - } - - prometheus.MustRegister(collector) -} - -func (be *PromBackend) newTiming(t *stats.Timings, name string) { - collector := &timingsCollector{ - t: t, - desc: prometheus.NewDesc( - be.buildPromName(name), - t.Help(), - []string{"Histograms"}, // hard coded label key - nil), - } - - prometheus.MustRegister(collector) -} - -func (be *PromBackend) newMultiTiming(mt *stats.MultiTimings, name string) { - collector := &multiTimingsCollector{ - mt: mt, - desc: prometheus.NewDesc( - be.buildPromName(name), - mt.Help(), - labelsToSnake(mt.Labels()), - nil), - } - - prometheus.MustRegister(collector) -} - -func (be *PromBackend) newMetric(c *stats.Counter, name string, vt prometheus.ValueType) { - collector := &metricCollector{ - counter: c, - desc: prometheus.NewDesc( - be.buildPromName(name), - c.Help(), - nil, - nil), - vt: vt} - - prometheus.MustRegister(collector) -} - -func (be *PromBackend) newMetricFunc(cf *stats.CounterFunc, name string, vt prometheus.ValueType) { - collector := &metricFuncCollector{ - cf: cf, - desc: prometheus.NewDesc( - be.buildPromName(name), - cf.Help(), - nil, - nil), - vt: vt} - - prometheus.MustRegister(collector) -} - // buildPromName specifies the namespace as a prefix to the metric name -func (be *PromBackend) buildPromName(name string) string { +func (be PromBackend) buildPromName(name string) string { s := strings.TrimPrefix(normalizeMetric(name), be.namespace+"_") return prometheus.BuildFQName("", be.namespace, s) } diff --git a/go/stats/prometheusbackend/prometheusbackend_test.go b/go/stats/prometheusbackend/prometheusbackend_test.go index a688389717f..354202c9d97 100644 --- a/go/stats/prometheusbackend/prometheusbackend_test.go +++ b/go/stats/prometheusbackend/prometheusbackend_test.go @@ -42,9 +42,9 @@ func TestPrometheusGauge(t *testing.T) { func TestPrometheusCounterFunc(t *testing.T) { name := "blah_counterfunc" - stats.NewCounterFunc(name, "help", stats.IntFunc(func() int64 { + stats.NewCounterFunc(name, "help", func() int64 { return 2 - })) + }) checkHandlerForMetrics(t, name, 2) } @@ -52,13 +52,47 @@ func TestPrometheusCounterFunc(t *testing.T) { func TestPrometheusGaugeFunc(t *testing.T) { name := "blah_gaugefunc" - stats.NewGaugeFunc(name, "help", stats.IntFunc(func() int64 { + stats.NewGaugeFunc(name, "help", func() int64 { return -3 - })) + }) checkHandlerForMetrics(t, name, -3) } +func TestPrometheusCounterDuration(t *testing.T) { + name := "blah_counterduration" + + d := stats.NewCounterDuration(name, "help") + d.Add(1 * time.Second) + + checkHandlerForMetrics(t, name, 1) +} + +func TestPrometheusCounterDurationFunc(t *testing.T) { + name := "blah_counterdurationfunc" + + stats.NewCounterDurationFunc(name, "help", func() time.Duration { return 1 * time.Second }) + + checkHandlerForMetrics(t, name, 1) +} + +func TestPrometheusGaugeDuration(t *testing.T) { + name := "blah_gaugeduration" + + d := stats.NewGaugeDuration(name, "help") + d.Set(1 * time.Second) + + checkHandlerForMetrics(t, name, 1) +} + +func TestPrometheusGaugeDurationFunc(t *testing.T) { + name := "blah_gaugedurationfunc" + + stats.NewGaugeDurationFunc(name, "help", func() time.Duration { return 1 * time.Second }) + + checkHandlerForMetrics(t, name, 1) +} + func checkHandlerForMetrics(t *testing.T, metric string, value int) { response := testMetricsHandler(t) @@ -69,41 +103,41 @@ func checkHandlerForMetrics(t *testing.T, metric string, value int) { } } -func TestPrometheusCountersWithLabels(t *testing.T) { - name := "blah_counterswithlabels" - c := stats.NewCountersWithLabels(name, "help", "tag", "tag1", "tag2") +func TestPrometheusCountersWithSingleLabel(t *testing.T) { + name := "blah_counterswithsinglelabel" + c := stats.NewCountersWithSingleLabel(name, "help", "label", "tag1", "tag2") c.Add("tag1", 1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag1", 1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag2", 0) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag1", 1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag2", 0) c.Add("tag2", 41) - checkHandlerForMetricWithLabels(t, name, "tag", "tag1", 1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag2", 41) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag1", 1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag2", 41) c.Reset("tag2") - checkHandlerForMetricWithLabels(t, name, "tag", "tag1", 1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag2", 0) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag1", 1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag2", 0) } -func TestPrometheusGaugesWithLabels(t *testing.T) { - name := "blah_gaugeswithlabels" - c := stats.NewGaugesWithLabels(name, "help", "tag", "tag1", "tag2") +func TestPrometheusGaugesWithSingleLabel(t *testing.T) { + name := "blah_gaugeswithsinglelabel" + c := stats.NewGaugesWithSingleLabel(name, "help", "label", "tag1", "tag2") c.Add("tag1", 1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag1", 1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag1", 1) c.Add("tag2", 1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag2", 1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag2", 1) c.Set("tag1", -1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag1", -1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag1", -1) c.Reset("tag2") - checkHandlerForMetricWithLabels(t, name, "tag", "tag1", -1) - checkHandlerForMetricWithLabels(t, name, "tag", "tag2", 0) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag1", -1) + checkHandlerForMetricWithSingleLabel(t, name, "label", "tag2", 0) } -func checkHandlerForMetricWithLabels(t *testing.T, metric string, tagName string, tagValue string, value int) { +func checkHandlerForMetricWithSingleLabel(t *testing.T, metric, label, tag string, value int) { response := testMetricsHandler(t) - expected := fmt.Sprintf("%s_%s{%s=\"%s\"} %d", namespace, metric, tagName, tagValue, value) + expected := fmt.Sprintf("%s_%s{%s=\"%s\"} %d", namespace, metric, label, tag, value) if !strings.Contains(response.Body.String(), expected) { t.Fatalf("Expected %s got %s", expected, response.Body.String()) @@ -163,7 +197,7 @@ func TestPrometheusCountersFuncWithMultiLabels(t *testing.T) { name := "blah_countersfuncwithmultilabels" labels := []string{"label1", "label2"} - stats.NewCountersFuncWithMultiLabels(name, labels, "help", func() map[string]int64 { + stats.NewCountersFuncWithMultiLabels(name, "help", labels, func() map[string]int64 { m := make(map[string]int64) m["foo.bar"] = 1 m["bar.baz"] = 1 @@ -187,25 +221,25 @@ func checkHandlerForMetricWithMultiLabels(t *testing.T, metric string, labels [] func TestPrometheusTimings(t *testing.T) { name := "blah_timings" cats := []string{"cat1", "cat2"} - timing := stats.NewTimings(name, "help", cats...) + timing := stats.NewTimings(name, "help", "category", cats...) timing.Add("cat1", time.Duration(1000000000)) response := testMetricsHandler(t) var s []string - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.0005\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.001\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.005\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.01\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.05\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.1\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"0.5\"} %d", namespace, name, cats[0], 0)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"1\"} %d", namespace, name, cats[0], 1)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"5\"} %d", namespace, name, cats[0], 1)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"10\"} %d", namespace, name, cats[0], 1)) - s = append(s, fmt.Sprintf("%s_%s_bucket{Histograms=\"%s\",le=\"+Inf\"} %d", namespace, name, cats[0], 1)) - s = append(s, fmt.Sprintf("%s_%s_sum{Histograms=\"%s\"} %d", namespace, name, cats[0], 1)) - s = append(s, fmt.Sprintf("%s_%s_count{Histograms=\"%s\"} %d", namespace, name, cats[0], 1)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.0005\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.001\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.005\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.01\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.05\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.1\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"0.5\"} %d", namespace, name, cats[0], 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"1\"} %d", namespace, name, cats[0], 1)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"5\"} %d", namespace, name, cats[0], 1)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"10\"} %d", namespace, name, cats[0], 1)) + s = append(s, fmt.Sprintf("%s_%s_bucket{category=\"%s\",le=\"+Inf\"} %d", namespace, name, cats[0], 1)) + s = append(s, fmt.Sprintf("%s_%s_sum{category=\"%s\"} %d", namespace, name, cats[0], 1)) + s = append(s, fmt.Sprintf("%s_%s_count{category=\"%s\"} %d", namespace, name, cats[0], 1)) for _, line := range s { if !strings.Contains(response.Body.String(), line) { @@ -256,6 +290,29 @@ func TestPrometheusMultiTimings_PanicWrongLength(t *testing.T) { c.Add([]string{"label1"}, time.Duration(100000000)) } +func TestPrometheusHistogram(t *testing.T) { + name := "blah_hist" + hist := stats.NewHistogram(name, "help", []int64{1, 5, 10}) + hist.Add(2) + hist.Add(3) + hist.Add(6) + + response := testMetricsHandler(t) + var s []string + + s = append(s, fmt.Sprintf("%s_%s_bucket{le=\"1\"} %d", namespace, name, 0)) + s = append(s, fmt.Sprintf("%s_%s_bucket{le=\"5\"} %d", namespace, name, 2)) + s = append(s, fmt.Sprintf("%s_%s_bucket{le=\"10\"} %d", namespace, name, 3)) + s = append(s, fmt.Sprintf("%s_%s_sum %d", namespace, name, 1)) + s = append(s, fmt.Sprintf("%s_%s_count %d", namespace, name, 3)) + + for _, line := range s { + if !strings.Contains(response.Body.String(), line) { + t.Fatalf("Expected result to contain %s, got %s", line, response.Body.String()) + } + } +} + func testMetricsHandler(t *testing.T) *httptest.ResponseRecorder { req, _ := http.NewRequest("GET", "/metrics", nil) response := httptest.NewRecorder() diff --git a/go/stats/rates.go b/go/stats/rates.go index 5290bec8bfb..7cb7ded97f0 100644 --- a/go/stats/rates.go +++ b/go/stats/rates.go @@ -37,6 +37,15 @@ type CountTracker interface { Counts() map[string]int64 } +// wrappedCountTracker implements the CountTracker interface. +// It is used in multidimensional.go to publish specific, one-dimensional +// counters. +type wrappedCountTracker struct { + f func() map[string]int64 +} + +func (t wrappedCountTracker) Counts() map[string]int64 { return t.f() } + // Rates is capable of reporting the rate (typically QPS) // for any variable that satisfies the CountTracker interface. type Rates struct { diff --git a/go/stats/rates_test.go b/go/stats/rates_test.go index 7e8cc901a65..ba150bb65fa 100644 --- a/go/stats/rates_test.go +++ b/go/stats/rates_test.go @@ -42,7 +42,7 @@ func TestRates(t *testing.T) { } clear() - c := NewCountersWithLabels("rcounter1", "rcounter help", "type") + c := NewCountersWithSingleLabel("rcounter1", "rcounter help", "label") r := NewRates("rates1", c, 3, -1*time.Second) r.snapshot() now = now.Add(epsilon) @@ -90,7 +90,7 @@ func TestRatesConsistency(t *testing.T) { // covered by rates, the sum of the rates reported must be // equal to the count reported by the counter. clear() - c := NewCountersWithLabels("rcounter4", "rcounter4 help", "type") + c := NewCountersWithSingleLabel("rcounter4", "rcounter4 help", "label") r := NewRates("rates4", c, 100, -1*time.Second) r.snapshot() @@ -123,7 +123,7 @@ func TestRatesConsistency(t *testing.T) { func TestRatesHook(t *testing.T) { clear() - c := NewCountersWithLabels("rcounter2", "rcounter2 help", "type") + c := NewCountersWithSingleLabel("rcounter2", "rcounter2 help", "label") var gotname string var gotv *Rates clear() diff --git a/go/stats/timings.go b/go/stats/timings.go index ce3cd685e72..8ec33a842bd 100644 --- a/go/stats/timings.go +++ b/go/stats/timings.go @@ -38,19 +38,21 @@ type Timings struct { histograms map[string]*Histogram hook func(string, time.Duration) help string + label string } // NewTimings creates a new Timings object, and publishes it if name is set. // categories is an optional list of categories to initialize to 0. // Categories that aren't initialized will be missing from the map until the // first time they are updated. -func NewTimings(name string, help string, categories ...string) *Timings { +func NewTimings(name, help, label string, categories ...string) *Timings { t := &Timings{ histograms: make(map[string]*Histogram), help: help, + label: label, } for _, cat := range categories { - t.histograms[cat] = NewGenericHistogram("", bucketCutoffs, bucketLabels, "Count", "Time") + t.histograms[cat] = NewGenericHistogram("", "", bucketCutoffs, bucketLabels, "Count", "Time") } if name != "" { publish(name, t) @@ -72,7 +74,7 @@ func (t *Timings) Add(name string, elapsed time.Duration) { t.mu.Lock() hist, ok = t.histograms[name] if !ok { - hist = NewGenericHistogram("", bucketCutoffs, bucketLabels, "Count", "Time") + hist = NewGenericHistogram("", "", bucketCutoffs, bucketLabels, "Count", "Time") t.histograms[name] = hist } t.mu.Unlock() @@ -160,6 +162,11 @@ func (t *Timings) Help() string { return t.help } +// Label returns the label name. +func (t *Timings) Label() string { + return t.label +} + var bucketCutoffs = []int64{5e5, 1e6, 5e6, 1e7, 5e7, 1e8, 5e8, 1e9, 5e9, 1e10} var bucketLabels []string diff --git a/go/stats/timings_test.go b/go/stats/timings_test.go index e5a76426269..9409cc01f7d 100644 --- a/go/stats/timings_test.go +++ b/go/stats/timings_test.go @@ -24,7 +24,7 @@ import ( func TestTimings(t *testing.T) { clear() - tm := NewTimings("timings1", "help") + tm := NewTimings("timings1", "help", "category") tm.Add("tag1", 500*time.Microsecond) tm.Add("tag1", 1*time.Millisecond) tm.Add("tag2", 1*time.Millisecond) @@ -56,7 +56,7 @@ func TestTimingsHook(t *testing.T) { }) name := "timings2" - v := NewTimings(name, "help") + v := NewTimings(name, "help", "") if gotname != name { t.Errorf("got %q, want %q", gotname, name) } diff --git a/go/stats/variable_interface.go b/go/stats/variable_interface.go new file mode 100644 index 00000000000..49b9201e4af --- /dev/null +++ b/go/stats/variable_interface.go @@ -0,0 +1,29 @@ +/* +Copyright 2018 The Vitess Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package stats + +// Variable is the minimal interface which each type in this "stats" package +// must implement. +// When integrating the Vitess stats types ("variables") with the different +// monitoring systems, you can rely on this interface. +type Variable interface { + // Help returns the description of the variable. + Help() string + + // String must implement String() from the expvar.Var interface. + String() string +} diff --git a/go/streamlog/streamlog.go b/go/streamlog/streamlog.go index 1db23fa8362..f3fe16c8990 100644 --- a/go/streamlog/streamlog.go +++ b/go/streamlog/streamlog.go @@ -40,7 +40,7 @@ var ( // QueryLogFormat controls the format of the query log (either text or json) QueryLogFormat = flag.String("querylog-format", "text", "format for query logs (\"text\" or \"json\")") - sendCount = stats.NewCountersWithLabels("StreamlogSend", "stream log send count", "logger_names") + sendCount = stats.NewCountersWithSingleLabel("StreamlogSend", "stream log send count", "logger_names") deliveredCount = stats.NewCountersWithMultiLabels( "StreamlogDelivered", "Stream log delivered", diff --git a/go/vt/binlog/binlog_streamer.go b/go/vt/binlog/binlog_streamer.go index 2dcd9999043..ab56eb4d323 100644 --- a/go/vt/binlog/binlog_streamer.go +++ b/go/vt/binlog/binlog_streamer.go @@ -37,7 +37,7 @@ import ( ) var ( - binlogStreamerErrors = stats.NewCountersWithLabels("BinlogStreamerErrors", "error count when streaming binlog", "state") + binlogStreamerErrors = stats.NewCountersWithSingleLabel("BinlogStreamerErrors", "error count when streaming binlog", "state") // ErrClientEOF is returned by Streamer if the stream ended because the // consumer of the stream indicated it doesn't want any more events. diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index f972e43046f..74010a88f69 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -88,7 +88,7 @@ func (bps *Stats) GetLastPosition() mysql.Position { // NewStats creates a new Stats structure func NewStats() *Stats { bps := &Stats{} - bps.Timings = stats.NewTimings("", "") + bps.Timings = stats.NewTimings("", "", "") bps.Rates = stats.NewRates("", bps.Timings, 15, 60e9) return bps } diff --git a/go/vt/binlog/updatestreamctl.go b/go/vt/binlog/updatestreamctl.go index 0c5f4bb05f9..3525c28a2b8 100644 --- a/go/vt/binlog/updatestreamctl.go +++ b/go/vt/binlog/updatestreamctl.go @@ -47,8 +47,8 @@ var usStateNames = map[int64]string{ } var ( - streamCount = stats.NewCountersWithLabels("UpdateStreamStreamCount", "update stream count", "type") - updateStreamErrors = stats.NewCountersWithLabels("UpdateStreamErrors", "update stream error count", "type") + streamCount = stats.NewCountersWithSingleLabel("UpdateStreamStreamCount", "update stream count", "type") + updateStreamErrors = stats.NewCountersWithSingleLabel("UpdateStreamErrors", "update stream error count", "type") keyrangeStatements = stats.NewCounter("UpdateStreamKeyRangeStatements", "update stream key range statement count") keyrangeTransactions = stats.NewCounter("UpdateStreamKeyRangeTransactions", "update stream key range transaction count") tablesStatements = stats.NewCounter("UpdateStreamTablesStatements", "update stream table statement count") diff --git a/go/vt/dbconnpool/connection_pool.go b/go/vt/dbconnpool/connection_pool.go index 2d27c337aaf..3a9e4b00cc8 100644 --- a/go/vt/dbconnpool/connection_pool.go +++ b/go/vt/dbconnpool/connection_pool.go @@ -65,15 +65,15 @@ func NewConnectionPool(name string, capacity int, idleTimeout time.Duration) *Co return cp } usedNames[name] = true - stats.NewGaugeFunc(name+"Capacity", "Connection pool capacity", stats.IntFunc(cp.Capacity)) - stats.NewGaugeFunc(name+"Available", "Connection pool available", stats.IntFunc(cp.Available)) - stats.NewGaugeFunc(name+"Active", "Connection pool active", stats.IntFunc(cp.Active)) - stats.NewGaugeFunc(name+"InUse", "Connection pool in-use", stats.IntFunc(cp.InUse)) - stats.NewGaugeFunc(name+"MaxCap", "Connection pool max cap", stats.IntFunc(cp.MaxCap)) - stats.NewCounterFunc(name+"WaitCount", "Connection pool wait count", stats.IntFunc(cp.WaitCount)) - stats.NewCounterFunc(name+"WaitTime", "Connection pool wait time", stats.DurationFunc(cp.WaitTime)) - stats.NewCounterFunc(name+"IdleTimeout", "Connection pool idle timeout", stats.DurationFunc(cp.IdleTimeout)) - stats.NewGaugeFunc(name+"IdleClosed", "Connection pool idle closed", stats.IntFunc(cp.IdleClosed)) + stats.NewGaugeFunc(name+"Capacity", "Connection pool capacity", cp.Capacity) + stats.NewGaugeFunc(name+"Available", "Connection pool available", cp.Available) + stats.NewGaugeFunc(name+"Active", "Connection pool active", cp.Active) + stats.NewGaugeFunc(name+"InUse", "Connection pool in-use", cp.InUse) + stats.NewGaugeFunc(name+"MaxCap", "Connection pool max cap", cp.MaxCap) + stats.NewCounterFunc(name+"WaitCount", "Connection pool wait count", cp.WaitCount) + stats.NewCounterDurationFunc(name+"WaitTime", "Connection pool wait time", cp.WaitTime) + stats.NewGaugeDurationFunc(name+"IdleTimeout", "Connection pool idle timeout", cp.IdleTimeout) + stats.NewGaugeFunc(name+"IdleClosed", "Connection pool idle closed", cp.IdleClosed) return cp } diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 440f1d3de06..9067acbcab2 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -39,6 +39,7 @@ package discovery import ( "bytes" "encoding/json" + "flag" "fmt" "html/template" "net/http" @@ -47,9 +48,8 @@ import ( "sync" "time" - "golang.org/x/net/context" - "github.com/golang/protobuf/proto" + "golang.org/x/net/context" "vitess.io/vitess/go/netutil" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/grpcclient" @@ -67,6 +67,8 @@ var ( hcErrorCounters = stats.NewCountersWithMultiLabels("HealthcheckErrors", "Healthcheck Errors", []string{"Keyspace", "ShardName", "TabletType"}) hcMasterPromotedCounters = stats.NewCountersWithMultiLabels("HealthcheckMasterPromoted", "Master promoted in keyspace/shard name because of health check errors", []string{"Keyspace", "ShardName"}) healthcheckOnce sync.Once + tabletURLTemplateString = flag.String("tablet_url_template", "http://{{.GetTabletHostPort}}", "format string describing debug tablet url formatting. See the Go code for getTabletDebugURL() how to customize this.") + tabletURLTemplate *template.Template ) // See the documentation for NewHealthCheck below for an explanation of these parameters. @@ -117,6 +119,20 @@ const ( ` ) +func init() { + loadTabletURLTemplate() +} + +// loadTabletURLTemplate loads or reloads the URL template. +// Should only be used independently for testing. +func loadTabletURLTemplate() { + tabletURLTemplate = template.New("") + _, err := tabletURLTemplate.Parse(*tabletURLTemplateString) + if err != nil { + log.Exitf("error parsing template: %v", err) + } +} + // HealthCheckStatsListener is the listener to receive health check stats update. type HealthCheckStatsListener interface { // StatsUpdate is called when: @@ -187,6 +203,44 @@ func (e *TabletStats) DeepEqual(f *TabletStats) bool { (e.LastError != nil && f.LastError != nil && e.LastError.Error() == f.LastError.Error())) } +// GetTabletHostPort formats a tablet host port address. +func (e TabletStats) GetTabletHostPort() string { + vtPort := e.Tablet.PortMap["vt"] + return netutil.JoinHostPort(e.Tablet.Hostname, vtPort) +} + +// GetHostNameLevel returns the specified hostname level. If the level does not exist it will pick the closest level. +// This seems unused but can be utilized by certain url formatting templates. See getTabletDebugURL for more details. +func (e TabletStats) GetHostNameLevel(level int) string { + chunkedHostname := strings.Split(e.Tablet.Hostname, ".") + + if level < 0 { + return chunkedHostname[0] + } else if level >= len(chunkedHostname) { + return chunkedHostname[len(chunkedHostname)-1] + } else { + return chunkedHostname[level] + } +} + +// getTabletDebugURL formats a debug url to the tablet. +// It uses a format string that can be passed into the app to format +// the debug URL to accommodate different network setups. It applies +// the html/template string defined to a TabletStats object. The +// format string can refer to members and functions of TabletStats +// like a regular html/template string. +// +// For instance given a tablet with hostname:port of host.dc.domain:22 +// could be configured as follows: +// http://{{.GetTabletHostPort}} -> http://host.dc.domain:22 +// https://{{.Tablet.Hostname}} -> https://host.dc.domain +// https://{{.GetHostNameLevel 0}}.bastion.corp -> https://host.bastion.corp +func (e TabletStats) getTabletDebugURL() string { + var buffer bytes.Buffer + tabletURLTemplate.Execute(&buffer, e) + return buffer.String() +} + // HealthCheck defines the interface of health checking module. // The goal of this object is to maintain a StreamHealth RPC // to a lot of tablets. Tablets are added / removed by calling the @@ -332,10 +386,10 @@ func NewHealthCheck(retryDelay, healthCheckTimeout time.Duration) HealthCheck { // RegisterStats registers the connection counts stats func (hc *HealthCheckImpl) RegisterStats() { - stats.NewCountersFuncWithMultiLabels( + stats.NewGaugesFuncWithMultiLabels( "HealthcheckConnections", + "the number of healthcheck connections registered", []string{"Keyspace", "ShardName", "TabletType"}, - "the numb of healthcheck connections registered", hc.servingConnStats) } @@ -377,10 +431,9 @@ func (hc *HealthCheckImpl) servingConnStats() map[string]int64 { // checkConn(). func (hc *HealthCheckImpl) finalizeConn(hcc *healthCheckConn) { hcc.mu.Lock() - if hcc.conn != nil { - hcc.conn.Close(hcc.ctx) - hcc.conn = nil - } + hccConn := hcc.conn + hccCtx := hcc.ctx + hcc.conn = nil hcc.tabletStats.Up = false hcc.tabletStats.Serving = false // Note: checkConn() exits only when hcc.ctx.Done() is closed. Thus it's @@ -388,6 +441,11 @@ func (hc *HealthCheckImpl) finalizeConn(hcc *healthCheckConn) { hcc.tabletStats.LastError = hcc.ctx.Err() ts := hcc.tabletStats hcc.mu.Unlock() + + if hccConn != nil { + hccConn.Close(hccCtx) + } + if hc.listener != nil { hc.listener.StatsUpdate(&ts) } @@ -457,7 +515,7 @@ func (hcc *healthCheckConn) stream(ctx context.Context, hc *HealthCheckImpl, cal if err := conn.StreamHealth(ctx, callback); err != nil { hcc.mu.Lock() - hcc.conn.Close(ctx) + log.Infof("StreamHealth failed from %v %v/%v (%v): %v", hcc.tabletStats.Tablet.GetAlias(), hcc.tabletStats.Tablet.GetKeyspace(), hcc.tabletStats.Tablet.GetShard(), hcc.tabletStats.Tablet.GetHostname(), err) hcc.conn = nil hcc.tabletStats.Serving = false hcc.tabletStats.LastError = err @@ -467,6 +525,7 @@ func (hcc *healthCheckConn) stream(ctx context.Context, hc *HealthCheckImpl, cal if hc.listener != nil { hc.listener.StatsUpdate(&ts) } + conn.Close(ctx) return } return @@ -687,11 +746,12 @@ func (hc *HealthCheckImpl) WaitForInitialStatsUpdates() { // GetConnection returns the TabletConn of the given tablet. func (hc *HealthCheckImpl) GetConnection(key string) queryservice.QueryService { hc.mu.RLock() - defer hc.mu.RUnlock() hcc := hc.addrToConns[key] if hcc == nil { + hc.mu.RUnlock() return nil } + hc.mu.RUnlock() hcc.mu.RLock() defer hcc.mu.RUnlock() return hcc.conn @@ -737,7 +797,6 @@ func (tcs *TabletsCacheStatus) StatusAsHTML() template.HTML { sort.Sort(tcs.TabletsStats) } for _, ts := range tcs.TabletsStats { - vtPort := ts.Tablet.PortMap["vt"] color := "green" extra := "" if ts.LastError != nil { @@ -755,11 +814,10 @@ func (tcs *TabletsCacheStatus) StatusAsHTML() template.HTML { extra = fmt.Sprintf(" (RepLag: %v)", ts.Stats.SecondsBehindMaster) } name := ts.Name - addr := netutil.JoinHostPort(ts.Tablet.Hostname, vtPort) if name == "" { - name = addr + name = ts.GetTabletHostPort() } - tLinks = append(tLinks, fmt.Sprintf(`%v%v`, addr, color, name, extra)) + tLinks = append(tLinks, fmt.Sprintf(`%v%v`, ts.getTabletDebugURL(), color, name, extra)) } return template.HTML(strings.Join(tLinks, "
")) } diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index 637d8445a81..1e6086da33f 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -23,6 +23,8 @@ import ( "html/template" "io" "reflect" + "strings" + "sync" "testing" "time" @@ -35,9 +37,6 @@ import ( "vitess.io/vitess/go/vt/vttablet/queryservice/fakes" "vitess.io/vitess/go/vt/vttablet/tabletconn" - "strings" - "sync" - querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) @@ -573,6 +572,42 @@ func TestTemplate(t *testing.T) { } } +func TestDebugURLFormatting(t *testing.T) { + flag.Set("tablet_url_template", "https://{{.GetHostNameLevel 0}}.bastion.{{.Tablet.Alias.Cell}}.corp") + loadTabletURLTemplate() + + tablet := topo.NewTablet(0, "cell", "host.dc.domain") + ts := []*TabletStats{ + { + Key: "a", + Tablet: tablet, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}, + Up: true, + Serving: false, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 1, CpuUsage: 0.3}, + TabletExternallyReparentedTimestamp: 0, + }, + } + tcs := &TabletsCacheStatus{ + Cell: "cell", + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}, + TabletsStats: ts, + } + templ := template.New("").Funcs(status.StatusFuncs) + templ, err := templ.Parse(HealthCheckTemplate) + if err != nil { + t.Fatalf("error parsing template: %v", err) + } + wr := &bytes.Buffer{} + if err := templ.Execute(wr, []*TabletsCacheStatus{tcs}); err != nil { + t.Fatalf("error executing template: %v", err) + } + expectedURL := `"https://host.bastion.cell.corp"` + if !strings.Contains(wr.String(), expectedURL) { + t.Fatalf("output missing formatted URL, expectedURL: %s , output: %s", expectedURL, wr.String()) + } +} + type listener struct { output chan *TabletStats } diff --git a/go/vt/log/log.go b/go/vt/log/log.go index 2a6b9a3b3a8..4f06ec38cc6 100644 --- a/go/vt/log/log.go +++ b/go/vt/log/log.go @@ -5,9 +5,7 @@ package log -import ( - glog "github.com/golang/glog" -) +import "github.com/golang/glog" // Level is used with V() to test log verbosity. type Level = glog.Level diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index e1cd194e222..bab2c668222 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -402,7 +402,7 @@ func backupFiles(ctx context.Context, mysqld MysqlDaemon, logger logutil.Logger, } // open the MANIFEST - wc, err := bh.AddFile(ctx, backupManifest) + wc, err := bh.AddFile(ctx, backupManifest, 0) if err != nil { return fmt.Errorf("cannot add %v to backup: %v", backupManifest, err) } @@ -440,8 +440,13 @@ func backupFile(ctx context.Context, mysqld MysqlDaemon, logger logutil.Logger, } defer source.Close() + fi, err := source.Stat() + if err != nil { + return err + } + // Open the destination file for writing, and a buffer. - wc, err := bh.AddFile(ctx, name) + wc, err := bh.AddFile(ctx, name, fi.Size()) if err != nil { return fmt.Errorf("cannot add file: %v", err) } diff --git a/go/vt/mysqlctl/backupstorage/interface.go b/go/vt/mysqlctl/backupstorage/interface.go index 7d8e55ee936..e6dacb05177 100644 --- a/go/vt/mysqlctl/backupstorage/interface.go +++ b/go/vt/mysqlctl/backupstorage/interface.go @@ -49,7 +49,7 @@ type BackupHandle interface { // multiple go routines once a backup has been started. // The context is valid for the duration of the writes, until the // WriteCloser is closed. - AddFile(ctx context.Context, filename string) (io.WriteCloser, error) + AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) // EndBackup stops and closes a backup. The contents should be kept. // Only works for read-write backups (created by StartBackup). diff --git a/go/vt/mysqlctl/cephbackupstorage/ceph.go b/go/vt/mysqlctl/cephbackupstorage/ceph.go index 5f2d9277baa..7d5f3c64670 100644 --- a/go/vt/mysqlctl/cephbackupstorage/ceph.go +++ b/go/vt/mysqlctl/cephbackupstorage/ceph.go @@ -73,7 +73,7 @@ func (bh *CephBackupHandle) Name() string { } // AddFile implements BackupHandle. -func (bh *CephBackupHandle) AddFile(ctx context.Context, filename string) (io.WriteCloser, error) { +func (bh *CephBackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { if bh.readOnly { return nil, fmt.Errorf("AddFile cannot be called on read-only backup") } diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index 7f2d4a76e4c..1ee21d7c057 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -146,7 +146,7 @@ func NewFakeMysqlDaemon(db *fakesqldb.DB) *FakeMysqlDaemon { } if db != nil { result.appPool = dbconnpool.NewConnectionPool("AppConnPool", 5, time.Minute) - result.appPool.Open(db.ConnParams(), stats.NewTimings("", "")) + result.appPool.Open(db.ConnParams(), stats.NewTimings("", "", "")) } return result } @@ -410,12 +410,12 @@ func (fmd *FakeMysqlDaemon) GetAppConnection(ctx context.Context) (*dbconnpool.P // GetDbaConnection is part of the MysqlDaemon interface. func (fmd *FakeMysqlDaemon) GetDbaConnection() (*dbconnpool.DBConnection, error) { - return dbconnpool.NewDBConnection(fmd.db.ConnParams(), stats.NewTimings("", "")) + return dbconnpool.NewDBConnection(fmd.db.ConnParams(), stats.NewTimings("", "", "")) } // GetAllPrivsConnection is part of the MysqlDaemon interface. func (fmd *FakeMysqlDaemon) GetAllPrivsConnection() (*dbconnpool.DBConnection, error) { - return dbconnpool.NewDBConnection(fmd.db.ConnParams(), stats.NewTimings("", "")) + return dbconnpool.NewDBConnection(fmd.db.ConnParams(), stats.NewTimings("", "", "")) } // SetSemiSyncEnabled is part of the MysqlDaemon interface. diff --git a/go/vt/mysqlctl/filebackupstorage/file.go b/go/vt/mysqlctl/filebackupstorage/file.go index 52f10707f0b..d2a93ea0ddc 100644 --- a/go/vt/mysqlctl/filebackupstorage/file.go +++ b/go/vt/mysqlctl/filebackupstorage/file.go @@ -56,7 +56,7 @@ func (fbh *FileBackupHandle) Name() string { } // AddFile is part of the BackupHandle interface -func (fbh *FileBackupHandle) AddFile(ctx context.Context, filename string) (io.WriteCloser, error) { +func (fbh *FileBackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { if fbh.readOnly { return nil, fmt.Errorf("AddFile cannot be called on read-only backup") } diff --git a/go/vt/mysqlctl/filebackupstorage/file_test.go b/go/vt/mysqlctl/filebackupstorage/file_test.go index 41718e8f7fa..fe23d949fbc 100644 --- a/go/vt/mysqlctl/filebackupstorage/file_test.go +++ b/go/vt/mysqlctl/filebackupstorage/file_test.go @@ -140,7 +140,7 @@ func TestListBackups(t *testing.T) { } // check we cannot chaneg a backup we listed - if _, err := bhs[0].AddFile(ctx, "test"); err == nil { + if _, err := bhs[0].AddFile(ctx, "test", 0); err == nil { t.Fatalf("was able to AddFile to read-only backup") } if err := bhs[0].EndBackup(ctx); err == nil { @@ -166,7 +166,7 @@ func TestFileContents(t *testing.T) { if err != nil { t.Fatalf("fbs.StartBackup failed: %v", err) } - wc, err := bh.AddFile(ctx, filename1) + wc, err := bh.AddFile(ctx, filename1, 0) if err != nil { t.Fatalf("bh.AddFile failed: %v", err) } diff --git a/go/vt/mysqlctl/gcsbackupstorage/gcs.go b/go/vt/mysqlctl/gcsbackupstorage/gcs.go index d62a2c21a00..b6fbcfdc69c 100644 --- a/go/vt/mysqlctl/gcsbackupstorage/gcs.go +++ b/go/vt/mysqlctl/gcsbackupstorage/gcs.go @@ -66,7 +66,7 @@ func (bh *GCSBackupHandle) Name() string { } // AddFile implements BackupHandle. -func (bh *GCSBackupHandle) AddFile(ctx context.Context, filename string) (io.WriteCloser, error) { +func (bh *GCSBackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { if bh.readOnly { return nil, fmt.Errorf("AddFile cannot be called on read-only backup") } diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index 9902a559876..8880a568484 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -73,9 +73,9 @@ var ( // masterConnectRetry is used in 'SET MASTER' commands masterConnectRetry = flag.Duration("master_connect_retry", 10*time.Second, "how long to wait in between slave -> connection attempts. Only precise to the second.") - dbaMysqlStats = stats.NewTimings("MysqlDba", "MySQL DBA stats") - allprivsMysqlStats = stats.NewTimings("MysqlAllPrivs", "MySQl Stats for all privs") - appMysqlStats = stats.NewTimings("MysqlApp", "MySQL app stats") + dbaMysqlStats = stats.NewTimings("MysqlDba", "MySQL DBA stats", "operation") + allprivsMysqlStats = stats.NewTimings("MysqlAllPrivs", "MySQl Stats for all privs", "operation") + appMysqlStats = stats.NewTimings("MysqlApp", "MySQL app stats", "operation") ) // Mysqld is the object that represents a mysqld daemon running on this server. diff --git a/go/vt/mysqlctl/s3backupstorage/s3.go b/go/vt/mysqlctl/s3backupstorage/s3.go index f9436f240a7..03bdd41b72b 100644 --- a/go/vt/mysqlctl/s3backupstorage/s3.go +++ b/go/vt/mysqlctl/s3backupstorage/s3.go @@ -27,6 +27,7 @@ import ( "flag" "fmt" "io" + "math" "sort" "strings" "sync" @@ -80,17 +81,30 @@ func (bh *S3BackupHandle) Name() string { } // AddFile is part of the backupstorage.BackupHandle interface. -func (bh *S3BackupHandle) AddFile(ctx context.Context, filename string) (io.WriteCloser, error) { +func (bh *S3BackupHandle) AddFile(ctx context.Context, filename string, filesize int64) (io.WriteCloser, error) { if bh.readOnly { return nil, fmt.Errorf("AddFile cannot be called on read-only backup") } + // Calculate s3 upload part size using the source filesize + partSizeMB := s3manager.DefaultUploadPartSize + if filesize > 0 { + minimumPartSize := float64(filesize) / float64(s3manager.MaxUploadParts) + // Convert partsize to mb and round up to ensure large enough partsize + calculatedPartSizeMB := int64(math.Ceil(minimumPartSize / 1024 * 1024)) + if calculatedPartSizeMB > partSizeMB { + partSizeMB = calculatedPartSizeMB + } + } + reader, writer := io.Pipe() bh.waitGroup.Add(1) go func() { defer bh.waitGroup.Done() - uploader := s3manager.NewUploaderWithClient(bh.client) + uploader := s3manager.NewUploaderWithClient(bh.client, func(u *s3manager.Uploader) { + u.PartSize = partSizeMB + }) object := objName(bh.dir, bh.name, filename) var sseOption *string diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index ff3c9a27e24..b52c148e3fc 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -665,6 +665,9 @@ var ( input: "delete a from a join b on a.id = b.id where b.name = 'test'", }, { input: "delete a, b from a, b where a.id = b.id and b.name = 'test'", + }, { + input: "delete from a1, a2 using t1 as a1 inner join t2 as a2 where a1.id=a2.id", + output: "delete a1, a2 from t1 as a1 join t2 as a2 where a1.id = a2.id", }, { input: "set /* simple */ a = 3", }, { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 72485c55817..d6117590bc9 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -567,322 +567,302 @@ var yyExca = [...]int{ 5, 27, -2, 4, -1, 227, - 109, 554, - -2, 550, - -1, 228, 109, 555, -2, 551, + -1, 228, + 109, 556, + -2, 552, -1, 296, - 80, 706, - -2, 46, - -1, 297, - 80, 673, + 80, 707, -2, 47, + -1, 297, + 80, 674, + -2, 48, -1, 302, - 80, 658, - -2, 516, + 80, 659, + -2, 517, -1, 304, - 80, 691, - -2, 518, - -1, 686, - 109, 557, - -2, 553, - -1, 880, + 80, 692, + -2, 519, + -1, 562, + 52, 41, + 54, 41, + -2, 43, + -1, 687, + 109, 558, + -2, 554, + -1, 882, 5, 28, - -2, 363, - -1, 905, + -2, 364, + -1, 907, 5, 27, - -2, 492, - -1, 1112, - 5, 28, -2, 493, - -1, 1156, - 5, 27, - -2, 495, - -1, 1209, + -1, 1116, 5, 28, + -2, 494, + -1, 1160, + 5, 27, -2, 496, + -1, 1213, + 5, 28, + -2, 497, } const yyPrivate = 57344 -const yyLast = 9538 +const yyLast = 9530 var yyAct = [...]int{ - 258, 47, 627, 509, 748, 1026, 232, 1200, 257, 1118, - 1050, 825, 822, 766, 1027, 781, 805, 960, 554, 556, - 1023, 206, 780, 819, 777, 924, 53, 908, 749, 872, - 951, 1000, 718, 711, 913, 508, 3, 963, 791, 737, - 688, 721, 442, 448, 295, 558, 200, 454, 47, 398, - 745, 230, 815, 462, 301, 854, 211, 799, 293, 523, - 215, 52, 288, 543, 1187, 475, 474, 484, 485, 477, - 478, 479, 480, 481, 482, 483, 476, 1228, 1218, 486, - 282, 1226, 1207, 205, 1224, 826, 1217, 283, 1018, 1106, - 201, 202, 203, 204, 402, 1056, 1057, 1058, 57, 1206, - 1172, 219, 942, 1061, 1059, 798, 284, 171, 167, 168, - 169, 1130, 1145, 806, 1095, 1093, 199, 434, 435, 1225, - 1223, 1201, 984, 59, 60, 61, 62, 63, 423, 746, - 767, 769, 412, 411, 475, 474, 484, 485, 477, 478, - 479, 480, 481, 482, 483, 476, 405, 164, 486, 165, - 165, 635, 626, 923, 793, 922, 1170, 793, 921, 400, - 408, 179, 1192, 166, 793, 1065, 477, 478, 479, 480, - 481, 482, 483, 476, 1115, 228, 486, 498, 499, 873, - 778, 486, 399, 987, 429, 429, 429, 429, 888, 429, - 429, 425, 936, 427, 866, 981, 429, 660, 466, 418, - 657, 983, 476, 170, 768, 486, 76, 1188, 461, 695, - 176, 1075, 47, 176, 911, 1066, 1020, 424, 426, 459, - 569, 738, 234, 693, 694, 692, 738, 495, 895, 1001, - 497, 630, 806, 940, 404, 461, 450, 176, 176, 76, - 1195, 456, 1136, 176, 428, 76, 792, 451, 163, 792, - 1060, 790, 788, 1171, 1169, 789, 792, 507, 1003, 511, - 512, 513, 514, 515, 516, 517, 518, 519, 1135, 522, + 258, 47, 628, 827, 749, 509, 232, 1204, 1122, 1029, + 508, 3, 824, 779, 767, 257, 1054, 1030, 556, 963, + 783, 206, 554, 782, 910, 807, 750, 1026, 200, 926, + 712, 874, 301, 1003, 722, 719, 966, 954, 821, 793, + 915, 689, 53, 738, 442, 448, 817, 746, 47, 398, + 295, 284, 454, 558, 543, 230, 211, 462, 205, 856, + 215, 291, 288, 293, 283, 52, 1232, 1222, 1230, 1211, + 1228, 828, 201, 202, 203, 204, 1221, 1021, 1110, 402, + 234, 1176, 945, 423, 282, 1210, 800, 1060, 1061, 1062, + 1134, 808, 1099, 1097, 219, 1065, 1063, 171, 167, 168, + 169, 57, 523, 199, 1149, 434, 435, 1191, 475, 474, + 484, 485, 477, 478, 479, 480, 481, 482, 483, 476, + 1229, 844, 486, 411, 1227, 1205, 59, 60, 61, 62, + 63, 987, 747, 412, 1004, 843, 405, 165, 1174, 768, + 770, 164, 287, 165, 636, 984, 425, 627, 427, 780, + 925, 986, 924, 923, 400, 408, 1196, 795, 179, 166, + 498, 499, 848, 1006, 795, 721, 1119, 990, 890, 868, + 661, 842, 424, 426, 466, 225, 228, 418, 486, 476, + 1079, 1069, 486, 658, 429, 429, 429, 429, 461, 429, + 429, 913, 939, 170, 570, 1008, 429, 1012, 1023, 1007, + 739, 1005, 696, 739, 795, 897, 1010, 76, 460, 459, + 185, 176, 47, 769, 176, 1009, 694, 695, 693, 839, + 836, 837, 451, 835, 808, 461, 631, 495, 1011, 1013, + 497, 1070, 399, 1199, 195, 1175, 1173, 459, 176, 176, + 76, 422, 1064, 985, 176, 983, 76, 846, 849, 794, + 1192, 943, 450, 461, 456, 660, 794, 507, 801, 511, + 512, 513, 514, 515, 516, 517, 518, 519, 1209, 522, 524, 524, 524, 524, 524, 524, 524, 524, 532, 533, - 534, 535, 1205, 712, 287, 713, 422, 50, 842, 555, - 1005, 955, 1009, 982, 1004, 980, 1002, 691, 885, 954, - 943, 1007, 841, 414, 415, 416, 406, 407, 1211, 281, - 1006, 452, 474, 484, 485, 477, 478, 479, 480, 481, - 482, 483, 476, 1008, 1010, 486, 460, 459, 1152, 846, - 525, 526, 527, 528, 529, 530, 531, 1053, 840, 795, - 176, 1133, 176, 461, 796, 952, 460, 459, 176, 460, - 459, 1214, 441, 568, 1052, 176, 1022, 663, 664, 76, - 76, 76, 76, 461, 76, 76, 461, 678, 680, 681, - 937, 76, 679, 484, 485, 477, 478, 479, 480, 481, - 482, 483, 476, 225, 971, 486, 837, 834, 835, 441, - 833, 479, 480, 481, 482, 483, 476, 76, 928, 486, - 1160, 1198, 429, 460, 459, 863, 864, 865, 1160, 441, - 429, 828, 969, 714, 844, 847, 1160, 1161, 1127, 1126, - 461, 429, 429, 429, 429, 429, 429, 429, 429, 431, - 432, 433, 641, 436, 437, 429, 429, 1045, 441, 1176, - 439, 640, 884, 631, 883, 1114, 441, 1175, 720, 839, - 1072, 1071, 496, 1068, 1069, 1068, 1067, 176, 878, 441, - 460, 459, 629, 659, 176, 176, 176, 23, 540, 441, - 76, 838, 665, 644, 642, 76, 970, 461, 689, 723, - 441, 975, 972, 965, 966, 973, 968, 967, 624, 576, - 575, 903, 420, 565, 904, 413, 843, 974, 47, 658, - 399, 21, 23, 977, 256, 1024, 1062, 539, 909, 845, - 990, 287, 511, 667, 50, 460, 459, 682, 910, 910, - 54, 686, 684, 730, 733, 909, 723, 1110, 430, 1155, - 540, 540, 461, 1074, 566, 74, 564, 1070, 890, 23, - 929, 288, 288, 288, 288, 288, 750, 725, 878, 50, - 715, 716, 887, 878, 567, 661, 555, 210, 770, 878, - 540, 909, 212, 50, 288, 1140, 742, 735, 300, 545, - 548, 549, 550, 546, 403, 547, 551, 76, 800, 914, - 915, 889, 773, 176, 176, 76, 50, 176, 820, 1039, - 176, 725, 298, 932, 176, 886, 76, 76, 76, 76, - 76, 76, 76, 76, 816, 771, 807, 808, 809, 50, - 76, 76, 775, 772, 176, 763, 914, 915, 628, 500, - 501, 502, 503, 504, 505, 506, 785, 811, 751, 76, - 429, 754, 429, 176, 810, 65, 823, 1055, 1024, 76, - 429, 956, 801, 802, 803, 804, 625, 821, 752, 753, - 917, 755, 638, 438, 634, 673, 971, 760, 812, 813, - 814, 440, 761, 920, 919, 645, 646, 647, 648, 649, - 650, 651, 652, 817, 818, 762, 758, 549, 550, 653, - 654, 759, 76, 757, 969, 756, 867, 1222, 300, 300, - 300, 300, 690, 300, 300, 216, 217, 1216, 76, 986, - 300, 689, 851, 1221, 861, 855, 860, 455, 856, 947, - 443, 574, 421, 176, 939, 686, 176, 176, 176, 176, - 176, 453, 444, 1197, 1196, 1153, 464, 933, 176, 1108, - 1141, 176, 830, 868, 637, 176, 553, 213, 214, 176, - 176, 455, 859, 76, 207, 1181, 906, 907, 970, 208, - 858, 76, 54, 975, 972, 965, 966, 973, 968, 967, - 1180, 1143, 457, 287, 287, 287, 287, 287, 910, 974, - 1189, 221, 1131, 656, 56, 964, 894, 58, 287, 563, - 51, 905, 1, 827, 959, 836, 287, 1199, 1049, 918, - 787, 545, 548, 549, 550, 546, 930, 547, 551, 300, - 926, 927, 176, 779, 571, 76, 397, 76, 64, 786, - 1168, 176, 1129, 794, 176, 76, 941, 797, 944, 945, - 1054, 1194, 938, 298, 581, 429, 579, 580, 934, 935, - 946, 578, 948, 949, 950, 247, 246, 249, 250, 251, - 252, 583, 953, 582, 248, 253, 577, 187, 294, 552, - 429, 441, 687, 570, 458, 696, 697, 698, 699, 700, - 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, - 66, 979, 976, 978, 829, 832, 831, 494, 857, 962, - 299, 1031, 662, 447, 850, 1179, 1142, 475, 474, 484, - 485, 477, 478, 479, 480, 481, 482, 483, 476, 994, - 993, 486, 893, 520, 736, 1029, 300, 47, 1025, 233, - 750, 677, 245, 1028, 300, 690, 750, 1012, 1011, 1019, - 999, 242, 1041, 1042, 1043, 300, 300, 300, 300, 300, - 300, 300, 300, 1033, 244, 1034, 243, 668, 1035, 300, - 300, 902, 1030, 686, 468, 231, 76, 1048, 223, 286, - 536, 544, 1047, 1046, 542, 541, 76, 291, 669, 916, - 912, 726, 727, 285, 989, 1105, 1186, 734, 464, 1063, - 1064, 300, 672, 25, 55, 218, 19, 18, 17, 445, - 449, 741, 20, 743, 744, 16, 15, 14, 29, 13, - 12, 288, 11, 10, 9, 685, 467, 8, 7, 76, - 76, 6, 76, 5, 4, 209, 22, 2, 0, 1084, - 1076, 717, 0, 0, 0, 0, 0, 1083, 0, 1104, - 0, 731, 731, 1078, 0, 76, 1081, 739, 0, 1091, - 510, 0, 0, 176, 0, 0, 0, 0, 0, 521, - 0, 0, 76, 0, 731, 0, 1109, 0, 0, 0, - 0, 1120, 1121, 1122, 0, 0, 1117, 0, 0, 1088, - 1089, 0, 1090, 930, 1123, 1092, 0, 1094, 1125, 958, - 0, 0, 300, 0, 429, 0, 0, 869, 870, 871, - 300, 0, 76, 76, 1132, 0, 1134, 0, 0, 0, - 0, 1139, 1138, 0, 985, 0, 298, 0, 0, 0, - 0, 0, 0, 0, 782, 76, 1144, 76, 76, 1128, - 0, 1029, 0, 666, 1157, 0, 0, 0, 0, 1028, - 0, 862, 0, 0, 0, 1154, 0, 0, 0, 0, - 0, 0, 176, 0, 300, 0, 300, 1165, 1167, 1166, - 76, 0, 1178, 0, 300, 0, 0, 0, 0, 1156, - 1177, 0, 0, 76, 176, 0, 1029, 1173, 47, 1174, - 76, 1190, 0, 76, 1028, 300, 176, 0, 877, 0, - 722, 724, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 892, 1203, 740, 0, 0, 685, - 0, 0, 0, 1191, 1208, 0, 750, 1102, 441, 0, - 0, 1212, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 287, 0, 76, 765, 76, 76, 76, - 176, 76, 1220, 76, 1219, 0, 1227, 0, 0, 0, - 0, 675, 676, 0, 475, 474, 484, 485, 477, 478, - 479, 480, 481, 482, 483, 476, 0, 0, 486, 76, - 76, 76, 0, 0, 0, 0, 0, 996, 997, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, - 1013, 1014, 0, 1016, 1017, 925, 0, 0, 0, 0, - 0, 0, 0, 510, 0, 300, 728, 729, 0, 0, - 76, 76, 0, 195, 0, 0, 0, 0, 0, 446, - 0, 0, 0, 76, 0, 0, 0, 0, 0, 782, - 0, 0, 0, 0, 0, 0, 76, 0, 1137, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 957, 300, - 0, 300, 0, 0, 174, 0, 76, 198, 0, 289, - 0, 776, 0, 180, 0, 0, 1103, 0, 0, 182, - 0, 0, 0, 0, 300, 961, 188, 184, 0, 222, - 0, 174, 174, 0, 0, 0, 0, 174, 76, 0, - 0, 300, 0, 0, 173, 0, 875, 76, 0, 1086, - 876, 0, 186, 0, 0, 190, 0, 880, 881, 882, - 0, 0, 0, 300, 0, 992, 891, 0, 0, 0, - 0, 897, 292, 898, 899, 900, 901, 401, 731, 0, - 0, 1032, 925, 181, 731, 0, 0, 1015, 475, 474, + 534, 535, 841, 1140, 180, 865, 866, 867, 887, 555, + 182, 659, 1215, 414, 415, 416, 794, 188, 184, 50, + 1139, 792, 790, 163, 840, 791, 797, 460, 459, 692, + 496, 798, 958, 957, 452, 477, 478, 479, 480, 481, + 482, 483, 476, 186, 461, 486, 190, 946, 404, 845, + 479, 480, 481, 482, 483, 476, 460, 459, 486, 1156, + 974, 176, 847, 176, 428, 664, 665, 1137, 955, 176, + 460, 459, 563, 461, 181, 1057, 176, 1025, 569, 1056, + 76, 76, 76, 76, 281, 76, 76, 461, 972, 287, + 1218, 441, 76, 525, 526, 527, 528, 529, 530, 531, + 940, 183, 189, 191, 192, 193, 194, 1164, 1202, 197, + 196, 460, 459, 931, 679, 681, 682, 830, 76, 680, + 406, 407, 429, 713, 715, 714, 1164, 441, 461, 642, + 429, 500, 501, 502, 503, 504, 505, 506, 1164, 1165, + 441, 429, 429, 429, 429, 429, 429, 429, 429, 430, + 1131, 1130, 973, 1048, 441, 429, 429, 978, 975, 968, + 969, 976, 971, 970, 886, 641, 885, 1118, 441, 1076, + 1075, 645, 632, 977, 1072, 1073, 1072, 1071, 176, 980, + 880, 441, 460, 459, 630, 176, 176, 176, 540, 441, + 23, 76, 666, 724, 441, 1180, 76, 625, 643, 461, + 577, 576, 21, 420, 566, 690, 247, 246, 249, 250, + 251, 252, 413, 298, 905, 248, 253, 906, 47, 687, + 399, 1179, 1066, 911, 1027, 23, 256, 911, 54, 912, + 724, 539, 511, 668, 993, 1114, 892, 50, 912, 889, + 23, 683, 726, 731, 734, 567, 685, 565, 540, 431, + 432, 433, 1159, 436, 437, 540, 1078, 74, 210, 1074, + 439, 288, 288, 288, 288, 288, 751, 880, 932, 880, + 691, 540, 50, 50, 716, 717, 555, 880, 771, 891, + 911, 774, 888, 565, 568, 288, 726, 50, 1144, 743, + 300, 662, 736, 212, 802, 822, 403, 1042, 76, 935, + 916, 917, 629, 440, 176, 176, 76, 775, 176, 818, + 813, 176, 812, 753, 754, 176, 756, 76, 76, 76, + 76, 76, 76, 76, 76, 752, 764, 65, 755, 825, + 773, 76, 76, 772, 1059, 176, 809, 810, 811, 777, + 50, 287, 287, 287, 287, 287, 1027, 787, 959, 919, + 76, 429, 639, 429, 176, 438, 287, 761, 759, 922, + 76, 429, 762, 760, 688, 287, 674, 697, 698, 699, + 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, + 710, 711, 763, 823, 549, 550, 921, 758, 819, 820, + 545, 548, 549, 550, 546, 757, 547, 551, 727, 728, + 916, 917, 1226, 76, 735, 216, 217, 869, 1220, 989, + 300, 300, 300, 300, 687, 300, 300, 853, 742, 76, + 744, 745, 300, 1225, 863, 862, 950, 575, 857, 690, + 421, 858, 455, 443, 176, 942, 1201, 176, 176, 176, + 176, 176, 1145, 1200, 298, 444, 453, 1157, 464, 176, + 936, 1112, 176, 832, 638, 870, 176, 553, 213, 214, + 455, 176, 176, 861, 207, 76, 626, 908, 909, 1185, + 208, 860, 54, 76, 635, 1184, 1147, 907, 912, 457, + 1193, 1135, 657, 56, 58, 646, 647, 648, 649, 650, + 651, 652, 653, 564, 691, 288, 51, 1, 829, 654, + 655, 896, 974, 484, 485, 477, 478, 479, 480, 481, + 482, 483, 476, 962, 838, 486, 920, 929, 928, 1203, + 930, 300, 1053, 933, 176, 789, 572, 76, 781, 76, + 972, 397, 64, 176, 788, 1172, 176, 76, 1133, 796, + 944, 949, 799, 951, 952, 953, 1058, 429, 1198, 947, + 948, 937, 938, 941, 545, 548, 549, 550, 546, 864, + 547, 551, 582, 580, 803, 804, 805, 806, 581, 579, + 584, 956, 429, 583, 578, 287, 187, 294, 552, 571, + 814, 815, 816, 965, 458, 66, 982, 981, 834, 494, + 871, 872, 873, 979, 973, 859, 299, 1034, 663, 978, + 975, 968, 969, 976, 971, 970, 879, 447, 1183, 1146, + 895, 520, 737, 233, 678, 977, 686, 245, 242, 244, + 243, 967, 894, 997, 669, 996, 904, 1032, 300, 47, + 1028, 468, 751, 231, 223, 1002, 300, 1014, 751, 1033, + 286, 1015, 1031, 687, 1044, 1045, 1046, 300, 300, 300, + 300, 300, 300, 300, 300, 536, 544, 1022, 1038, 1036, + 542, 300, 300, 541, 918, 914, 285, 992, 76, 1109, + 1190, 176, 673, 1037, 1050, 1052, 1051, 25, 55, 76, + 670, 1067, 1068, 218, 19, 18, 17, 20, 16, 15, + 464, 1049, 14, 300, 29, 831, 221, 833, 13, 12, + 11, 10, 9, 8, 7, 852, 6, 5, 4, 209, + 22, 2, 0, 0, 288, 1080, 0, 0, 298, 0, + 0, 0, 76, 76, 0, 76, 784, 0, 1082, 0, + 0, 1085, 0, 718, 0, 0, 1088, 1087, 0, 0, + 0, 0, 1108, 732, 732, 0, 0, 0, 76, 740, + 0, 0, 0, 0, 0, 667, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 76, 732, 1095, 0, 0, + 0, 999, 1000, 1124, 1125, 1126, 1113, 0, 0, 1121, + 0, 0, 0, 0, 1016, 1017, 1127, 1019, 1020, 0, + 0, 1129, 933, 0, 287, 300, 0, 0, 429, 0, + 0, 0, 0, 300, 0, 76, 76, 0, 0, 0, + 0, 686, 723, 725, 0, 0, 0, 1136, 1142, 1138, + 1143, 0, 0, 0, 0, 0, 0, 0, 741, 76, + 0, 76, 76, 0, 0, 1032, 0, 0, 1161, 1148, + 0, 0, 0, 0, 0, 0, 0, 0, 1160, 0, + 1031, 0, 1158, 0, 0, 0, 176, 300, 766, 300, + 0, 0, 1169, 1170, 76, 0, 1182, 300, 1171, 0, + 1177, 0, 1178, 1181, 0, 0, 0, 76, 176, 0, + 1032, 0, 47, 0, 76, 0, 0, 76, 300, 1194, + 176, 961, 1195, 0, 1090, 1031, 0, 0, 0, 0, + 0, 0, 0, 0, 445, 449, 0, 0, 0, 0, + 0, 1207, 0, 0, 0, 0, 988, 0, 1212, 0, + 751, 467, 0, 0, 0, 1216, 0, 0, 0, 0, + 0, 0, 784, 0, 0, 0, 0, 0, 0, 76, + 1223, 76, 76, 76, 176, 76, 1224, 0, 76, 0, + 1231, 0, 0, 0, 0, 510, 0, 0, 0, 0, + 0, 0, 0, 0, 521, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 76, 76, 76, 0, 964, 0, + 0, 0, 0, 1092, 1093, 0, 1094, 0, 0, 1096, + 0, 1098, 0, 0, 0, 0, 0, 0, 927, 1150, + 1151, 0, 1152, 1153, 1154, 0, 0, 446, 0, 300, + 0, 0, 0, 0, 0, 76, 76, 0, 995, 877, + 0, 0, 0, 878, 0, 0, 0, 0, 76, 0, + 882, 883, 884, 289, 1132, 0, 0, 0, 0, 893, + 1018, 76, 174, 0, 899, 198, 900, 901, 902, 903, + 0, 0, 960, 300, 0, 300, 0, 0, 0, 0, + 0, 76, 0, 0, 0, 0, 0, 222, 173, 174, + 174, 0, 0, 0, 0, 174, 0, 0, 300, 0, + 0, 0, 784, 0, 784, 0, 0, 0, 0, 0, + 0, 0, 0, 76, 0, 300, 292, 0, 0, 0, + 0, 401, 76, 0, 475, 474, 484, 485, 477, 478, + 479, 480, 481, 482, 483, 476, 0, 300, 486, 0, + 0, 0, 0, 0, 0, 0, 0, 1233, 0, 0, + 0, 0, 732, 0, 0, 1035, 927, 0, 732, 0, + 995, 0, 1141, 0, 0, 0, 0, 0, 0, 875, + 0, 0, 0, 0, 0, 0, 676, 677, 0, 300, + 0, 300, 1055, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 174, 0, 174, 0, 0, 0, 0, 0, + 174, 0, 0, 1001, 0, 0, 0, 174, 0, 0, + 0, 0, 0, 0, 1081, 0, 0, 0, 409, 0, + 410, 784, 0, 0, 0, 0, 417, 1083, 510, 0, + 0, 729, 730, 419, 1086, 1106, 441, 300, 0, 0, + 0, 23, 24, 48, 26, 27, 0, 0, 964, 784, + 1047, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 42, 0, 0, 0, 0, 28, 599, 0, 0, 0, + 0, 0, 475, 474, 484, 485, 477, 478, 479, 480, + 481, 482, 483, 476, 37, 0, 486, 778, 50, 1123, + 0, 1123, 1123, 1123, 0, 1128, 0, 0, 300, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 174, + 0, 0, 0, 0, 0, 0, 174, 560, 174, 0, + 1089, 0, 0, 0, 300, 300, 300, 1091, 0, 0, + 0, 0, 0, 0, 0, 538, 0, 0, 1100, 1101, + 1102, 0, 587, 1105, 562, 0, 0, 30, 31, 33, + 32, 35, 0, 0, 0, 0, 1115, 1116, 1117, 0, + 1120, 0, 0, 0, 0, 1162, 1163, 36, 43, 44, + 0, 600, 45, 46, 34, 0, 854, 855, 1055, 449, + 0, 0, 0, 0, 0, 0, 38, 39, 0, 40, + 41, 1123, 613, 614, 615, 616, 617, 618, 619, 0, + 620, 621, 622, 623, 624, 601, 602, 603, 604, 585, + 586, 1197, 0, 588, 0, 589, 590, 591, 592, 593, + 594, 595, 596, 597, 598, 605, 606, 607, 608, 609, + 610, 611, 612, 1155, 0, 174, 174, 0, 0, 174, + 732, 881, 174, 1214, 0, 0, 644, 0, 1166, 1167, + 1168, 0, 1219, 0, 0, 0, 898, 49, 1103, 441, + 0, 633, 634, 0, 0, 637, 174, 0, 640, 0, + 0, 0, 0, 0, 1186, 1187, 1188, 1189, 0, 0, + 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, + 0, 0, 656, 0, 644, 475, 474, 484, 485, 477, + 478, 479, 480, 481, 482, 483, 476, 0, 0, 486, + 0, 675, 0, 0, 1208, 0, 0, 0, 0, 1213, + 0, 0, 0, 0, 0, 0, 0, 1217, 0, 0, + 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, + 222, 222, 0, 0, 733, 733, 222, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1235, 1236, 441, + 222, 222, 222, 222, 0, 174, 1107, 733, 174, 174, + 174, 174, 174, 0, 0, 0, 0, 0, 0, 0, + 765, 0, 0, 174, 0, 0, 0, 560, 0, 0, + 0, 748, 174, 174, 0, 475, 474, 484, 485, 477, + 478, 479, 480, 481, 482, 483, 476, 0, 0, 486, + 0, 0, 0, 0, 1024, 0, 0, 0, 0, 776, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1039, + 1040, 0, 0, 1041, 1104, 0, 1043, 0, 475, 474, 484, 485, 477, 478, 479, 480, 481, 482, 483, 476, - 852, 853, 486, 449, 300, 0, 300, 1051, 0, 0, - 183, 189, 191, 192, 193, 194, 0, 0, 197, 196, - 0, 0, 0, 0, 0, 0, 0, 0, 782, 0, - 782, 0, 0, 0, 174, 0, 174, 0, 0, 1077, - 0, 0, 174, 0, 0, 0, 0, 0, 0, 174, - 0, 1100, 1079, 1146, 1147, 0, 1148, 1149, 1150, 1082, - 1099, 441, 300, 0, 0, 879, 0, 0, 0, 0, - 0, 0, 0, 0, 409, 0, 410, 0, 0, 0, - 896, 0, 417, 0, 0, 0, 992, 0, 0, 419, - 0, 0, 0, 0, 0, 0, 0, 475, 474, 484, - 485, 477, 478, 479, 480, 481, 482, 483, 476, 998, - 0, 486, 0, 0, 1119, 0, 1119, 1119, 1119, 0, - 1124, 0, 300, 475, 474, 484, 485, 477, 478, 479, - 480, 481, 482, 483, 476, 0, 0, 486, 0, 0, - 0, 995, 0, 0, 0, 0, 782, 0, 300, 300, - 300, 174, 0, 0, 0, 0, 1044, 0, 174, 560, - 174, 475, 474, 484, 485, 477, 478, 479, 480, 481, - 482, 483, 476, 961, 782, 486, 0, 0, 0, 0, - 0, 1229, 0, 874, 0, 0, 0, 0, 0, 1158, - 1159, 538, 0, 0, 0, 0, 0, 0, 0, 0, - 562, 0, 1051, 475, 474, 484, 485, 477, 478, 479, - 480, 481, 482, 483, 476, 1119, 0, 486, 0, 0, - 0, 0, 0, 0, 0, 1085, 0, 0, 0, 0, - 0, 0, 1087, 0, 0, 1193, 0, 1021, 0, 0, - 0, 0, 0, 1096, 1097, 1098, 0, 0, 1101, 0, - 0, 0, 1036, 1037, 0, 0, 1038, 0, 0, 1040, - 0, 1111, 1112, 1113, 731, 1116, 0, 1210, 0, 0, - 0, 0, 0, 0, 0, 0, 1215, 174, 174, 0, - 0, 174, 0, 0, 174, 0, 0, 0, 643, 475, - 474, 484, 485, 477, 478, 479, 480, 481, 482, 483, - 476, 0, 0, 486, 0, 0, 0, 0, 174, 0, - 0, 0, 0, 0, 0, 0, 0, 632, 633, 0, - 0, 636, 0, 0, 639, 0, 0, 174, 0, 0, - 0, 0, 0, 0, 0, 0, 643, 1151, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 655, 0, - 0, 0, 1162, 1163, 1164, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1107, 0, 0, 674, 0, 0, - 0, 510, 0, 0, 0, 0, 0, 222, 1182, 1183, - 1184, 1185, 222, 222, 0, 0, 732, 732, 222, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 222, 222, 222, 222, 0, 174, 0, 732, - 174, 174, 174, 174, 174, 0, 0, 0, 1204, 0, - 0, 0, 764, 1209, 0, 174, 0, 0, 0, 560, - 0, 1213, 0, 174, 174, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 747, 0, 0, + 0, 0, 486, 0, 0, 174, 0, 121, 0, 0, + 0, 0, 0, 0, 174, 0, 92, 174, 0, 0, + 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, + 0, 826, 0, 0, 0, 0, 0, 0, 0, 644, + 850, 0, 0, 851, 0, 75, 0, 0, 0, 0, + 0, 222, 0, 0, 86, 0, 475, 474, 484, 485, + 477, 478, 479, 480, 481, 482, 483, 476, 0, 0, + 486, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 475, 474, 484, 485, 477, 478, 479, 480, 481, 482, + 483, 476, 1111, 0, 486, 0, 0, 0, 222, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1231, 1232, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 774, 0, 0, 0, 0, 0, + 177, 0, 0, 0, 222, 126, 0, 0, 137, 97, + 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, + 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, + 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, + 102, 79, 174, 129, 91, 95, 90, 120, 142, 143, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, + 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, + 108, 125, 99, 116, 115, 117, 998, 0, 0, 135, + 150, 162, 0, 0, 156, 157, 158, 159, 118, 85, + 100, 133, 0, 0, 0, 0, 475, 474, 484, 485, + 477, 478, 479, 480, 481, 482, 483, 476, 0, 77, + 486, 105, 160, 128, 94, 151, 474, 484, 485, 477, + 478, 479, 480, 481, 482, 483, 476, 174, 0, 486, + 0, 0, 0, 0, 0, 0, 0, 222, 0, 0, + 0, 1206, 510, 0, 0, 0, 0, 0, 222, 0, + 0, 0, 0, 991, 0, 0, 0, 0, 644, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 121, 0, 0, 0, 0, 0, 174, 0, 0, 92, - 0, 0, 0, 0, 104, 174, 106, 0, 174, 134, - 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1202, 510, 0, 0, 0, 0, 75, 0, - 643, 0, 0, 0, 0, 0, 824, 86, 0, 0, - 0, 0, 222, 0, 0, 848, 0, 0, 849, 0, + 0, 0, 470, 733, 473, 0, 0, 0, 0, 733, + 487, 488, 489, 490, 491, 492, 493, 876, 471, 472, + 469, 475, 474, 484, 485, 477, 478, 479, 480, 481, + 482, 483, 476, 0, 0, 486, 0, 475, 474, 484, + 485, 477, 478, 479, 480, 481, 482, 483, 476, 0, + 0, 486, 0, 0, 0, 0, 0, 174, 475, 474, + 484, 485, 477, 478, 479, 480, 481, 482, 483, 476, + 0, 0, 486, 0, 0, 0, 0, 0, 0, 174, + 0, 0, 0, 1077, 0, 0, 0, 0, 0, 0, + 0, 174, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1084, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 475, 474, 484, 485, 477, 478, 479, - 480, 481, 482, 483, 476, 0, 0, 486, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, - 0, 0, 0, 177, 0, 0, 0, 0, 126, 0, - 0, 137, 97, 96, 0, 222, 0, 88, 0, 131, - 122, 149, 0, 123, 130, 107, 141, 127, 148, 178, - 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, - 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, - 120, 142, 143, 89, 161, 83, 153, 82, 84, 152, - 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, - 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, - 0, 0, 135, 150, 162, 0, 0, 156, 157, 158, - 159, 118, 85, 100, 133, 0, 0, 0, 0, 0, - 0, 23, 24, 48, 26, 27, 0, 0, 0, 0, - 0, 0, 77, 0, 105, 160, 128, 94, 151, 0, - 42, 0, 0, 0, 0, 28, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, - 0, 0, 0, 0, 37, 0, 0, 222, 50, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 222, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 643, 0, - 0, 0, 0, 0, 0, 0, 0, 988, 0, 0, - 0, 0, 0, 732, 0, 0, 0, 0, 0, 732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 30, 31, 33, - 32, 35, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 36, 43, 44, - 0, 0, 45, 46, 34, 0, 174, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 38, 39, 0, 40, - 41, 0, 0, 0, 0, 0, 0, 0, 174, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 174, 0, 0, 0, 0, 0, 1073, 0, 0, 0, - 0, 0, 0, 470, 0, 473, 0, 0, 0, 0, - 0, 487, 488, 489, 490, 491, 492, 493, 1080, 471, - 472, 469, 475, 474, 484, 485, 477, 478, 479, 480, - 481, 482, 483, 476, 0, 0, 486, 49, 0, 0, - 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 386, 376, 0, 348, - 388, 326, 340, 396, 341, 342, 369, 312, 356, 121, - 338, 0, 329, 307, 335, 308, 327, 350, 92, 353, - 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, - 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, - 389, 339, 367, 390, 0, 0, 0, 75, 0, 783, - 784, 0, 0, 0, 0, 0, 86, 0, 366, 385, - 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, - 333, 931, 0, 0, 0, 0, 0, 0, 351, 355, - 371, 345, 0, 0, 0, 0, 0, 0, 0, 0, - 330, 0, 362, 0, 0, 0, 314, 311, 0, 349, - 0, 0, 0, 316, 0, 331, 372, 0, 305, 375, - 381, 346, 177, 384, 344, 343, 387, 126, 0, 732, - 137, 97, 96, 379, 328, 336, 88, 334, 131, 122, - 149, 361, 123, 130, 107, 141, 127, 148, 178, 155, - 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, - 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, - 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, - 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, - 98, 124, 108, 125, 99, 116, 115, 117, 0, 309, - 0, 135, 150, 162, 324, 382, 156, 157, 158, 159, - 118, 85, 100, 133, 320, 323, 318, 319, 357, 358, - 391, 392, 393, 373, 315, 0, 321, 322, 0, 377, - 360, 77, 0, 105, 160, 128, 94, 151, 386, 376, + 0, 0, 0, 0, 0, 0, 0, 0, 386, 376, 0, 348, 388, 326, 340, 396, 341, 342, 369, 312, 356, 121, 338, 0, 329, 307, 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, 389, 339, 367, 390, 0, 0, 0, 75, - 0, 783, 784, 0, 0, 0, 0, 0, 86, 0, + 0, 785, 786, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, - 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, + 383, 332, 333, 934, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 362, 0, 0, 0, 314, 311, 0, 349, 0, 0, 0, 316, 0, 331, 372, 0, 305, 375, 381, 346, 177, 384, 344, 343, 387, 126, - 0, 0, 137, 97, 96, 379, 328, 336, 88, 334, + 0, 733, 137, 97, 96, 379, 328, 336, 88, 334, 131, 122, 149, 361, 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, @@ -897,8 +877,8 @@ var yyAct = [...]int{ 369, 312, 356, 121, 338, 0, 329, 307, 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, - 347, 370, 317, 363, 389, 339, 367, 390, 50, 0, - 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 347, 370, 317, 363, 389, 339, 367, 390, 0, 0, + 0, 75, 0, 785, 786, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, 0, 0, 0, 0, @@ -921,11 +901,11 @@ var yyAct = [...]int{ 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, 389, 339, 367, 390, - 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, + 50, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, 0, 0, - 0, 0, 0, 0, 991, 0, 330, 0, 362, 0, + 0, 0, 0, 0, 0, 0, 330, 0, 362, 0, 0, 0, 314, 311, 0, 349, 0, 0, 0, 316, 0, 331, 372, 0, 305, 375, 381, 346, 177, 384, 344, 343, 387, 126, 0, 0, 137, 97, 96, 379, @@ -944,11 +924,11 @@ var yyAct = [...]int{ 329, 307, 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, 389, 339, - 367, 390, 0, 0, 0, 227, 0, 0, 0, 0, + 367, 390, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, - 0, 0, 0, 0, 0, 0, 683, 0, 330, 0, + 0, 0, 0, 0, 0, 0, 994, 0, 330, 0, 362, 0, 0, 0, 314, 311, 0, 349, 0, 0, 0, 316, 0, 331, 372, 0, 305, 375, 381, 346, 177, 384, 344, 343, 387, 126, 0, 0, 137, 97, @@ -967,11 +947,11 @@ var yyAct = [...]int{ 338, 0, 329, 307, 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, - 389, 339, 367, 390, 0, 0, 0, 75, 0, 0, + 389, 339, 367, 390, 0, 0, 0, 227, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, - 371, 345, 0, 0, 0, 0, 0, 0, 0, 0, + 371, 345, 0, 0, 0, 0, 0, 0, 684, 0, 330, 0, 362, 0, 0, 0, 314, 311, 0, 349, 0, 0, 0, 316, 0, 331, 372, 0, 305, 375, 381, 346, 177, 384, 344, 343, 387, 126, 0, 0, @@ -990,7 +970,7 @@ var yyAct = [...]int{ 356, 121, 338, 0, 329, 307, 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, - 317, 363, 389, 339, 367, 390, 0, 0, 0, 227, + 317, 363, 389, 339, 367, 390, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, @@ -1014,7 +994,7 @@ var yyAct = [...]int{ 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, 389, 339, 367, 390, 0, 0, - 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 227, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, 0, 0, 0, 0, @@ -1026,10 +1006,10 @@ var yyAct = [...]int{ 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, 83, 153, - 82, 303, 152, 119, 140, 146, 113, 110, 81, 144, + 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, 309, 0, 135, 150, 162, 324, 382, - 156, 157, 158, 159, 304, 302, 100, 133, 320, 323, + 156, 157, 158, 159, 118, 85, 100, 133, 320, 323, 318, 319, 357, 358, 391, 392, 393, 373, 315, 0, 321, 322, 0, 377, 360, 77, 0, 105, 160, 128, 94, 151, 386, 376, 0, 348, 388, 326, 340, 396, @@ -1037,7 +1017,7 @@ var yyAct = [...]int{ 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, 389, 339, 367, 390, - 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, 0, 0, @@ -1049,10 +1029,10 @@ var yyAct = [...]int{ 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, + 83, 153, 82, 303, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, 309, 0, 135, 150, 162, - 324, 382, 156, 157, 158, 159, 118, 85, 100, 133, + 324, 382, 156, 157, 158, 159, 304, 302, 100, 133, 320, 323, 318, 319, 357, 358, 391, 392, 393, 373, 315, 0, 321, 322, 0, 377, 360, 77, 0, 105, 160, 128, 94, 151, 386, 376, 0, 348, 388, 326, @@ -1060,7 +1040,7 @@ var yyAct = [...]int{ 329, 307, 335, 308, 327, 350, 92, 353, 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, 389, 339, - 367, 390, 0, 0, 0, 75, 0, 0, 0, 0, + 367, 390, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, 371, 345, @@ -1072,79 +1052,80 @@ var yyAct = [...]int{ 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, - 89, 161, 83, 153, 82, 303, 152, 119, 140, 146, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, 309, 0, 135, - 150, 162, 324, 382, 156, 157, 158, 159, 304, 302, - 297, 296, 320, 323, 318, 319, 357, 358, 391, 392, + 150, 162, 324, 382, 156, 157, 158, 159, 118, 85, + 100, 133, 320, 323, 318, 319, 357, 358, 391, 392, 393, 373, 315, 0, 321, 322, 0, 377, 360, 77, - 0, 105, 160, 128, 94, 151, 121, 0, 0, 719, - 0, 229, 0, 0, 0, 92, 0, 226, 0, 0, - 104, 268, 106, 0, 0, 134, 114, 0, 0, 0, - 0, 259, 260, 0, 0, 0, 0, 0, 0, 0, - 0, 50, 0, 0, 227, 247, 246, 249, 250, 251, - 252, 0, 0, 86, 248, 253, 254, 255, 0, 0, - 224, 240, 0, 267, 0, 0, 0, 0, 0, 0, + 0, 105, 160, 128, 94, 151, 386, 376, 0, 348, + 388, 326, 340, 396, 341, 342, 369, 312, 356, 121, + 338, 0, 329, 307, 335, 308, 327, 350, 92, 353, + 325, 378, 359, 104, 394, 106, 364, 0, 134, 114, + 0, 0, 352, 380, 354, 374, 347, 370, 317, 363, + 389, 339, 367, 390, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 0, 86, 0, 366, 385, + 337, 368, 306, 365, 0, 310, 313, 395, 383, 332, + 333, 0, 0, 0, 0, 0, 0, 0, 351, 355, + 371, 345, 0, 0, 0, 0, 0, 0, 0, 0, + 330, 0, 362, 0, 0, 0, 314, 311, 0, 349, + 0, 0, 0, 316, 0, 331, 372, 0, 305, 375, + 381, 346, 177, 384, 344, 343, 387, 126, 0, 0, + 137, 97, 96, 379, 328, 336, 88, 334, 131, 122, + 149, 361, 123, 130, 107, 141, 127, 148, 178, 155, + 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, + 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, + 142, 143, 89, 161, 83, 153, 82, 303, 152, 119, + 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, + 98, 124, 108, 125, 99, 116, 115, 117, 0, 309, + 0, 135, 150, 162, 324, 382, 156, 157, 158, 159, + 304, 302, 297, 296, 320, 323, 318, 319, 357, 358, + 391, 392, 393, 373, 315, 0, 321, 322, 0, 377, + 360, 77, 0, 105, 160, 128, 94, 151, 121, 0, + 0, 720, 0, 229, 0, 0, 0, 92, 0, 226, + 0, 0, 104, 268, 106, 0, 0, 134, 114, 0, + 0, 0, 0, 259, 260, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 227, 247, 246, 249, + 250, 251, 252, 0, 0, 86, 248, 253, 254, 255, + 0, 0, 224, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 238, 220, 0, 0, 0, 279, - 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, - 0, 0, 277, 0, 126, 0, 0, 137, 97, 96, - 0, 0, 0, 88, 0, 131, 122, 149, 0, 123, - 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, - 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, - 79, 0, 129, 91, 95, 90, 120, 142, 143, 89, - 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, - 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, - 125, 99, 116, 115, 117, 0, 0, 0, 135, 150, - 162, 0, 0, 156, 157, 158, 159, 118, 85, 100, - 133, 269, 278, 275, 276, 273, 274, 272, 271, 270, - 280, 261, 262, 263, 264, 266, 0, 265, 77, 0, - 105, 160, 128, 94, 151, 121, 0, 0, 0, 0, - 229, 0, 0, 0, 92, 0, 226, 0, 0, 104, - 268, 106, 0, 0, 134, 114, 0, 0, 0, 0, - 259, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 441, 227, 247, 246, 249, 250, 251, 252, - 0, 0, 86, 248, 253, 254, 255, 0, 0, 224, - 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 238, 220, 0, 0, + 0, 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 238, 0, 0, 0, 0, 279, 0, - 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, - 0, 277, 0, 126, 0, 0, 137, 97, 96, 0, - 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, - 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, - 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, - 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, - 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, - 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, - 0, 0, 156, 157, 158, 159, 118, 85, 100, 133, - 269, 278, 275, 276, 273, 274, 272, 271, 270, 280, - 261, 262, 263, 264, 266, 0, 265, 77, 0, 105, - 160, 128, 94, 151, 121, 0, 0, 0, 0, 229, - 0, 0, 0, 92, 0, 226, 0, 0, 104, 268, - 106, 0, 0, 134, 114, 0, 0, 0, 0, 259, - 260, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 0, 0, 227, 247, 246, 249, 250, 251, 252, 0, - 0, 86, 248, 253, 254, 255, 0, 0, 224, 240, - 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 177, 0, 0, 277, 0, 126, 0, 0, 137, + 97, 96, 0, 0, 0, 88, 0, 131, 122, 149, + 0, 123, 130, 107, 141, 127, 148, 178, 155, 139, + 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, + 101, 102, 79, 0, 129, 91, 95, 90, 120, 142, + 143, 89, 161, 83, 153, 82, 84, 152, 119, 140, + 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, + 124, 108, 125, 99, 116, 115, 117, 0, 0, 0, + 135, 150, 162, 0, 0, 156, 157, 158, 159, 118, + 85, 100, 133, 269, 278, 275, 276, 273, 274, 272, + 271, 270, 280, 261, 262, 263, 264, 266, 0, 265, + 77, 0, 105, 160, 128, 94, 151, 121, 0, 0, + 0, 0, 229, 0, 0, 0, 92, 0, 226, 0, + 0, 104, 268, 106, 0, 0, 134, 114, 0, 0, + 0, 0, 259, 260, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 0, 441, 227, 247, 246, 249, 250, + 251, 252, 0, 0, 86, 248, 253, 254, 255, 0, + 0, 224, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 238, 220, 0, 0, 0, 279, 0, 239, - 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, - 277, 0, 126, 0, 0, 137, 97, 96, 0, 0, - 0, 88, 0, 131, 122, 149, 0, 123, 130, 107, - 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, - 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, - 129, 91, 95, 90, 120, 142, 143, 89, 161, 83, - 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, - 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, - 116, 115, 117, 0, 0, 0, 135, 150, 162, 0, - 0, 156, 157, 158, 159, 118, 85, 100, 133, 269, - 278, 275, 276, 273, 274, 272, 271, 270, 280, 261, - 262, 263, 264, 266, 23, 265, 77, 0, 105, 160, - 128, 94, 151, 0, 0, 0, 121, 0, 0, 0, + 0, 0, 0, 0, 237, 238, 0, 0, 0, 0, + 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 177, 0, 0, 277, 0, 126, 0, 0, 137, 97, + 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, + 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, + 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, + 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, + 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, + 108, 125, 99, 116, 115, 117, 0, 0, 0, 135, + 150, 162, 0, 0, 156, 157, 158, 159, 118, 85, + 100, 133, 269, 278, 275, 276, 273, 274, 272, 271, + 270, 280, 261, 262, 263, 264, 266, 0, 265, 77, + 0, 105, 160, 128, 94, 151, 121, 0, 0, 0, 0, 229, 0, 0, 0, 92, 0, 226, 0, 0, 104, 268, 106, 0, 0, 134, 114, 0, 0, 0, 0, 259, 260, 0, 0, 0, 0, 0, 0, 0, @@ -1152,7 +1133,7 @@ var yyAct = [...]int{ 252, 0, 0, 86, 248, 253, 254, 255, 0, 0, 224, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 238, 0, 0, 0, 0, 279, + 0, 0, 0, 237, 238, 220, 0, 0, 0, 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 277, 0, 126, 0, 0, 137, 97, 96, @@ -1165,196 +1146,181 @@ var yyAct = [...]int{ 125, 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, 0, 0, 156, 157, 158, 159, 118, 85, 100, 133, 269, 278, 275, 276, 273, 274, 272, 271, 270, - 280, 261, 262, 263, 264, 266, 0, 265, 77, 0, - 105, 160, 128, 94, 151, 121, 0, 0, 0, 0, - 229, 0, 0, 0, 92, 0, 226, 0, 0, 104, - 268, 106, 0, 0, 134, 114, 0, 0, 0, 0, - 259, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 0, 227, 247, 246, 249, 250, 251, 252, - 0, 0, 86, 248, 253, 254, 255, 0, 0, 224, - 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, + 280, 261, 262, 263, 264, 266, 23, 265, 77, 0, + 105, 160, 128, 94, 151, 0, 0, 0, 121, 0, + 0, 0, 0, 229, 0, 0, 0, 92, 0, 226, + 0, 0, 104, 268, 106, 0, 0, 134, 114, 0, + 0, 0, 0, 259, 260, 0, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 0, 227, 247, 246, 249, + 250, 251, 252, 0, 0, 86, 248, 253, 254, 255, + 0, 0, 224, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 238, 0, 0, 0, 0, 279, 0, - 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, - 0, 277, 0, 126, 0, 0, 137, 97, 96, 0, - 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, - 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, - 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, - 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, - 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, - 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, - 0, 0, 156, 157, 158, 159, 118, 85, 100, 133, - 269, 278, 275, 276, 273, 274, 272, 271, 270, 280, - 261, 262, 263, 264, 266, 121, 265, 77, 0, 105, - 160, 128, 94, 151, 92, 0, 0, 0, 0, 104, - 268, 106, 0, 0, 134, 114, 0, 0, 0, 0, - 259, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 0, 227, 247, 246, 249, 250, 251, 252, - 0, 0, 86, 248, 253, 254, 255, 0, 0, 0, - 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 238, 0, 0, 0, + 0, 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 238, 0, 0, 0, 0, 279, 0, - 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, - 0, 277, 0, 126, 0, 0, 137, 97, 96, 0, - 0, 0, 88, 0, 131, 122, 149, 1230, 123, 130, - 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, - 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, - 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, - 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, - 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, - 0, 0, 156, 157, 158, 159, 118, 85, 100, 133, - 269, 278, 275, 276, 273, 274, 272, 271, 270, 280, - 261, 262, 263, 264, 266, 121, 265, 77, 0, 105, - 160, 128, 94, 151, 92, 0, 0, 0, 0, 104, - 268, 106, 0, 0, 134, 114, 0, 0, 0, 0, - 259, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 50, 0, 0, 227, 247, 246, 249, 250, 251, 252, - 0, 0, 86, 248, 253, 254, 255, 0, 0, 0, - 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, + 0, 177, 0, 0, 277, 0, 126, 0, 0, 137, + 97, 96, 0, 0, 0, 88, 0, 131, 122, 149, + 0, 123, 130, 107, 141, 127, 148, 178, 155, 139, + 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, + 101, 102, 79, 0, 129, 91, 95, 90, 120, 142, + 143, 89, 161, 83, 153, 82, 84, 152, 119, 140, + 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, + 124, 108, 125, 99, 116, 115, 117, 0, 0, 0, + 135, 150, 162, 0, 0, 156, 157, 158, 159, 118, + 85, 100, 133, 269, 278, 275, 276, 273, 274, 272, + 271, 270, 280, 261, 262, 263, 264, 266, 0, 265, + 77, 0, 105, 160, 128, 94, 151, 121, 0, 0, + 0, 0, 229, 0, 0, 0, 92, 0, 226, 0, + 0, 104, 268, 106, 0, 0, 134, 114, 0, 0, + 0, 0, 259, 260, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 227, 247, 246, 249, 250, + 251, 252, 0, 0, 86, 248, 253, 254, 255, 0, + 0, 224, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 238, 0, 0, 0, 0, 279, 0, - 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, - 0, 277, 0, 126, 0, 0, 137, 97, 96, 0, - 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, - 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, - 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, - 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, - 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, - 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, - 0, 0, 156, 157, 158, 159, 118, 85, 100, 133, - 269, 278, 275, 276, 273, 274, 272, 271, 270, 280, - 261, 262, 263, 264, 266, 0, 265, 77, 0, 105, - 160, 128, 94, 151, 121, 0, 0, 0, 463, 0, - 0, 0, 0, 92, 0, 0, 0, 0, 104, 0, - 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 238, 0, 0, 0, 0, + 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 75, 0, 465, 0, 0, 0, 0, 0, - 0, 86, 0, 0, 0, 0, 460, 459, 0, 0, + 177, 0, 0, 277, 0, 126, 0, 0, 137, 97, + 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, + 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, + 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, + 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, + 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, + 108, 125, 99, 116, 115, 117, 0, 0, 0, 135, + 150, 162, 0, 0, 156, 157, 158, 159, 118, 85, + 100, 133, 269, 278, 275, 276, 273, 274, 272, 271, + 270, 280, 261, 262, 263, 264, 266, 121, 265, 77, + 0, 105, 160, 128, 94, 151, 92, 0, 0, 0, + 0, 104, 268, 106, 0, 0, 134, 114, 0, 0, + 0, 0, 259, 260, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 227, 247, 246, 249, 250, + 251, 252, 0, 0, 86, 248, 253, 254, 255, 0, + 0, 0, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 238, 0, 0, 0, 0, + 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 177, 0, 0, 277, 0, 126, 0, 0, 137, 97, + 96, 0, 0, 0, 88, 0, 131, 122, 149, 1234, + 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, + 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, + 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, + 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, + 108, 125, 99, 116, 115, 117, 0, 0, 0, 135, + 150, 162, 0, 0, 156, 157, 158, 159, 118, 85, + 100, 133, 269, 278, 275, 276, 273, 274, 272, 271, + 270, 280, 261, 262, 263, 264, 266, 121, 265, 77, + 0, 105, 160, 128, 94, 151, 92, 0, 0, 0, + 0, 104, 268, 106, 0, 0, 134, 114, 0, 0, + 0, 0, 259, 260, 0, 0, 0, 0, 0, 0, + 0, 0, 50, 0, 0, 227, 247, 246, 249, 250, + 251, 252, 0, 0, 86, 248, 253, 254, 255, 0, + 0, 0, 240, 0, 267, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, - 0, 0, 126, 0, 0, 137, 97, 96, 0, 0, - 0, 88, 0, 131, 122, 149, 0, 123, 130, 107, - 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, - 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, - 129, 91, 95, 90, 120, 142, 143, 89, 161, 83, - 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, - 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, - 116, 115, 117, 0, 0, 0, 135, 150, 162, 0, - 121, 156, 157, 158, 159, 118, 85, 100, 133, 92, - 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, - 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, - 128, 94, 151, 0, 0, 0, 0, 0, 75, 0, - 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, - 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 238, 0, 0, 0, 0, + 279, 0, 239, 0, 0, 235, 236, 241, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 177, 0, 0, 277, 0, 126, 0, 0, 137, 97, + 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, + 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, + 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, + 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, + 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, + 108, 125, 99, 116, 115, 117, 0, 0, 0, 135, + 150, 162, 0, 0, 156, 157, 158, 159, 118, 85, + 100, 133, 269, 278, 275, 276, 273, 274, 272, 271, + 270, 280, 261, 262, 263, 264, 266, 0, 265, 77, + 0, 105, 160, 128, 94, 151, 121, 0, 0, 0, + 463, 0, 0, 0, 0, 92, 0, 0, 0, 0, + 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 75, 0, 465, 0, 0, 0, + 0, 0, 0, 86, 0, 0, 0, 0, 460, 459, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 71, 72, 0, 67, 0, 0, 0, 73, 126, 0, - 0, 137, 97, 96, 0, 0, 0, 88, 0, 131, - 122, 149, 0, 123, 130, 107, 141, 127, 148, 69, - 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, - 136, 112, 101, 102, 79, 598, 129, 91, 95, 90, - 120, 142, 143, 89, 161, 83, 153, 82, 84, 152, - 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, - 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, - 0, 0, 135, 150, 162, 0, 0, 156, 157, 158, - 159, 118, 85, 100, 133, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 77, 0, 105, 160, 128, 94, 151, 121, - 0, 586, 0, 559, 0, 0, 0, 0, 92, 0, - 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, + 0, 0, 0, 0, 126, 0, 0, 137, 97, 96, + 0, 0, 0, 88, 0, 131, 122, 149, 0, 123, + 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, + 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, + 79, 0, 129, 91, 95, 90, 120, 142, 143, 89, + 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, + 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, + 125, 99, 116, 115, 117, 0, 0, 0, 135, 150, + 162, 0, 121, 156, 157, 158, 159, 118, 85, 100, + 133, 92, 0, 0, 0, 0, 104, 0, 106, 0, + 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, + 105, 160, 128, 94, 151, 0, 0, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 86, + 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 599, 0, 0, 0, 0, 0, 0, 175, 0, 561, - 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, - 0, 612, 613, 614, 615, 616, 617, 618, 0, 619, - 620, 621, 622, 623, 600, 601, 602, 603, 584, 585, - 0, 0, 587, 0, 588, 589, 590, 591, 592, 593, - 594, 595, 596, 597, 604, 605, 606, 607, 608, 609, - 610, 611, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 126, 0, 0, - 137, 97, 96, 0, 0, 0, 88, 0, 131, 122, - 149, 0, 123, 130, 107, 141, 127, 148, 178, 155, - 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, - 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, - 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, - 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, - 98, 124, 108, 125, 99, 116, 115, 117, 0, 0, - 0, 135, 150, 162, 0, 0, 156, 157, 158, 159, - 118, 85, 100, 133, 0, 0, 0, 23, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, - 0, 77, 0, 105, 160, 128, 94, 151, 92, 0, - 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 0, 0, 75, 0, 0, - 0, 0, 0, 0, 0, 0, 86, 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, 71, 72, 0, 67, 0, 0, 0, 73, + 126, 0, 0, 137, 97, 96, 0, 0, 0, 88, + 0, 131, 122, 149, 0, 123, 130, 107, 141, 127, + 148, 69, 155, 139, 154, 78, 138, 147, 87, 132, + 80, 145, 136, 112, 101, 102, 79, 0, 129, 91, + 95, 90, 120, 142, 143, 89, 161, 83, 153, 82, + 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, + 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, + 117, 0, 0, 0, 135, 150, 162, 0, 0, 156, + 157, 158, 159, 118, 85, 100, 133, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 77, 0, 105, 160, 128, 94, + 151, 121, 0, 0, 0, 559, 0, 0, 0, 0, + 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, + 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, + 0, 561, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 126, 0, 0, - 137, 97, 96, 0, 0, 0, 88, 0, 131, 122, - 149, 0, 123, 130, 107, 141, 127, 148, 178, 155, - 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, - 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, - 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, - 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, - 98, 124, 108, 125, 99, 116, 115, 117, 0, 0, - 0, 135, 150, 162, 0, 0, 156, 157, 158, 159, - 118, 85, 100, 133, 0, 0, 0, 23, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, - 0, 77, 0, 105, 160, 128, 94, 151, 92, 0, - 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 0, 0, 175, 0, 0, - 0, 0, 0, 0, 0, 0, 86, 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, 0, 0, 177, 0, 0, 0, 0, 126, + 0, 0, 137, 97, 96, 0, 0, 0, 88, 0, + 131, 122, 149, 0, 123, 130, 107, 141, 127, 148, + 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, + 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, + 90, 120, 142, 143, 89, 161, 83, 153, 82, 84, + 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, + 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, + 0, 0, 0, 135, 150, 162, 0, 0, 156, 157, + 158, 159, 118, 85, 100, 133, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 121, 0, 77, 0, 105, 160, 128, 94, 151, + 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, + 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 126, 0, 0, - 137, 97, 96, 0, 0, 0, 88, 0, 131, 122, - 149, 0, 123, 130, 107, 141, 127, 148, 178, 155, - 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, - 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, - 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, - 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, - 98, 124, 108, 125, 99, 116, 115, 117, 0, 0, - 0, 135, 150, 162, 0, 121, 156, 157, 158, 159, - 118, 85, 100, 133, 92, 0, 0, 0, 0, 104, - 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, - 0, 77, 0, 105, 160, 128, 94, 151, 0, 0, - 0, 0, 0, 75, 0, 0, 670, 0, 0, 671, - 0, 0, 86, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 177, 0, 0, 0, 0, 126, + 0, 0, 137, 97, 96, 0, 0, 0, 88, 0, + 131, 122, 149, 0, 123, 130, 107, 141, 127, 148, + 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, + 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, + 90, 120, 142, 143, 89, 161, 83, 153, 82, 84, + 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, + 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, + 0, 0, 0, 135, 150, 162, 0, 0, 156, 157, + 158, 159, 118, 85, 100, 133, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, - 0, 0, 0, 126, 0, 0, 137, 97, 96, 0, - 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, - 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, - 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, - 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, - 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, - 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, - 0, 121, 156, 157, 158, 159, 118, 85, 100, 133, - 92, 0, 573, 0, 0, 104, 0, 106, 0, 0, - 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, - 160, 128, 94, 151, 0, 0, 0, 0, 0, 75, - 0, 572, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 121, 0, 77, 0, 105, 160, 128, 94, 151, + 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, + 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 50, 0, 0, 175, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 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, 0, 0, 0, 0, 0, 0, @@ -1368,51 +1334,51 @@ var yyAct = [...]int{ 90, 120, 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, - 0, 0, 0, 135, 150, 162, 0, 0, 156, 157, - 158, 159, 118, 85, 100, 133, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 135, 150, 162, 0, 121, 156, 157, + 158, 159, 118, 85, 100, 133, 92, 0, 0, 0, + 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, 128, 94, 151, - 121, 0, 0, 0, 559, 0, 0, 0, 0, 92, - 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, - 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, - 561, 0, 0, 0, 0, 0, 0, 86, 0, 0, + 0, 0, 0, 0, 0, 75, 0, 0, 671, 0, + 0, 672, 0, 0, 86, 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, 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, 0, 0, 0, 0, 0, - 0, 0, 0, 177, 0, 0, 0, 0, 126, 0, - 0, 137, 97, 96, 0, 0, 0, 88, 0, 131, - 122, 149, 0, 557, 130, 107, 141, 127, 148, 178, - 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, - 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, - 120, 142, 143, 89, 161, 83, 153, 82, 84, 152, - 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, - 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, - 0, 0, 135, 150, 162, 0, 121, 156, 157, 158, - 159, 118, 85, 100, 133, 92, 0, 0, 0, 0, - 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, - 0, 0, 77, 0, 105, 160, 128, 94, 151, 0, - 0, 50, 0, 0, 175, 0, 0, 0, 0, 0, - 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, + 177, 0, 0, 0, 0, 126, 0, 0, 137, 97, + 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, + 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, + 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, + 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, + 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, + 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, + 108, 125, 99, 116, 115, 117, 0, 0, 0, 135, + 150, 162, 0, 121, 156, 157, 158, 159, 118, 85, + 100, 133, 92, 0, 574, 0, 0, 104, 0, 106, + 0, 0, 134, 114, 0, 0, 0, 0, 0, 77, + 0, 105, 160, 128, 94, 151, 0, 0, 0, 0, + 0, 75, 0, 573, 0, 0, 0, 0, 0, 0, + 86, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 177, - 0, 0, 0, 0, 126, 0, 0, 137, 97, 96, - 0, 0, 0, 88, 0, 131, 122, 149, 0, 123, - 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, - 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, - 79, 0, 129, 91, 95, 90, 120, 142, 143, 89, - 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, - 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, - 125, 99, 116, 115, 117, 0, 0, 0, 135, 150, - 162, 0, 121, 156, 157, 158, 159, 118, 85, 100, - 133, 92, 0, 0, 0, 0, 104, 0, 106, 0, - 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, - 105, 160, 128, 94, 151, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, + 0, 126, 0, 0, 137, 97, 96, 0, 0, 0, + 88, 0, 131, 122, 149, 0, 123, 130, 107, 141, + 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, + 132, 80, 145, 136, 112, 101, 102, 79, 0, 129, + 91, 95, 90, 120, 142, 143, 89, 161, 83, 153, + 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, + 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, + 115, 117, 0, 0, 0, 135, 150, 162, 0, 0, + 156, 157, 158, 159, 118, 85, 100, 133, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 77, 0, 105, 160, 128, + 94, 151, 121, 0, 0, 0, 559, 0, 0, 0, + 0, 92, 0, 0, 0, 0, 104, 0, 106, 0, + 0, 134, 114, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, 561, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1421,7 +1387,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, 0, 0, 126, 0, 0, 137, 97, 96, 0, 0, 0, 88, - 0, 131, 122, 149, 0, 123, 130, 107, 141, 127, + 0, 131, 122, 149, 0, 557, 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, 83, 153, 82, @@ -1431,7 +1397,7 @@ var yyAct = [...]int{ 157, 158, 159, 118, 85, 100, 133, 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, 128, 94, - 151, 0, 0, 0, 0, 0, 75, 0, 465, 0, + 151, 0, 0, 50, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1446,57 +1412,57 @@ var yyAct = [...]int{ 143, 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, 0, 0, - 135, 150, 162, 0, 0, 156, 157, 158, 159, 118, - 85, 100, 133, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, - 77, 0, 105, 160, 128, 94, 151, 537, 92, 0, - 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, + 135, 150, 162, 0, 121, 156, 157, 158, 159, 118, + 85, 100, 133, 92, 0, 0, 0, 0, 104, 0, + 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, + 77, 0, 105, 160, 128, 94, 151, 0, 0, 0, + 0, 0, 175, 0, 561, 0, 0, 0, 0, 0, + 0, 86, 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, 175, 0, 0, - 0, 0, 0, 0, 0, 0, 86, 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, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 177, 0, 0, + 0, 0, 126, 0, 0, 137, 97, 96, 0, 0, + 0, 88, 0, 131, 122, 149, 0, 123, 130, 107, + 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, + 87, 132, 80, 145, 136, 112, 101, 102, 79, 0, + 129, 91, 95, 90, 120, 142, 143, 89, 161, 83, + 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, + 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, + 116, 115, 117, 0, 0, 0, 135, 150, 162, 0, + 121, 156, 157, 158, 159, 118, 85, 100, 133, 92, + 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, + 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, + 128, 94, 151, 0, 0, 0, 0, 0, 75, 0, + 465, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 177, 0, 0, 0, 0, 126, 0, 0, - 137, 97, 96, 0, 0, 0, 88, 0, 131, 122, - 149, 0, 123, 130, 107, 141, 127, 148, 178, 155, - 139, 154, 78, 138, 147, 87, 132, 80, 145, 136, - 112, 101, 102, 79, 0, 129, 91, 95, 90, 120, - 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, - 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, - 98, 124, 108, 125, 99, 116, 115, 117, 290, 0, - 0, 135, 150, 162, 0, 121, 156, 157, 158, 159, - 118, 85, 100, 133, 92, 0, 0, 0, 0, 104, - 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, - 0, 77, 0, 105, 160, 128, 94, 151, 0, 0, - 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, - 0, 0, 86, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 177, 0, 0, 0, 0, 126, 0, + 0, 137, 97, 96, 0, 0, 0, 88, 0, 131, + 122, 149, 0, 123, 130, 107, 141, 127, 148, 178, + 155, 139, 154, 78, 138, 147, 87, 132, 80, 145, + 136, 112, 101, 102, 79, 0, 129, 91, 95, 90, + 120, 142, 143, 89, 161, 83, 153, 82, 84, 152, + 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, + 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, + 0, 0, 135, 150, 162, 0, 0, 156, 157, 158, + 159, 118, 85, 100, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 177, 0, - 0, 0, 0, 126, 0, 0, 137, 97, 96, 0, - 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, - 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, - 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, - 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, - 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, - 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, - 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, - 0, 121, 156, 157, 158, 159, 118, 85, 100, 133, + 0, 121, 77, 0, 105, 160, 128, 94, 151, 537, 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, - 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, - 160, 128, 94, 151, 0, 0, 0, 0, 0, 175, + 134, 114, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 86, 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, 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, 0, - 0, 0, 172, 0, 177, 0, 0, 0, 0, 126, + 0, 0, 0, 0, 177, 0, 0, 0, 0, 126, 0, 0, 137, 97, 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, @@ -1504,11 +1470,11 @@ var yyAct = [...]int{ 90, 120, 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, - 0, 0, 0, 135, 150, 162, 0, 121, 156, 157, + 290, 0, 0, 135, 150, 162, 0, 121, 156, 157, 158, 159, 118, 85, 100, 133, 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, 128, 94, 151, - 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 86, 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, @@ -1527,13 +1493,13 @@ var yyAct = [...]int{ 100, 133, 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, 128, 94, 151, 0, 0, 0, 0, - 0, 227, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 86, 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, 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, 0, 0, 0, 0, 0, 177, 0, 0, 0, + 0, 0, 0, 0, 172, 0, 177, 0, 0, 0, 0, 126, 0, 0, 137, 97, 96, 0, 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, 147, 87, @@ -1545,7 +1511,7 @@ var yyAct = [...]int{ 156, 157, 158, 159, 118, 85, 100, 133, 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, 160, 128, - 94, 151, 0, 0, 0, 0, 0, 175, 0, 0, + 94, 151, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1560,21 +1526,59 @@ var yyAct = [...]int{ 142, 143, 89, 161, 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, 0, 0, - 0, 135, 150, 162, 0, 0, 156, 157, 158, 159, - 118, 85, 100, 133, 0, 0, 0, 0, 0, 0, + 0, 135, 150, 162, 0, 121, 156, 157, 158, 159, + 118, 85, 100, 133, 92, 0, 0, 0, 0, 104, + 0, 106, 0, 0, 134, 114, 0, 0, 0, 0, + 0, 77, 0, 105, 160, 128, 94, 151, 0, 0, + 0, 0, 0, 227, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 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, 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, 0, 0, 0, 0, 0, 177, 0, + 0, 0, 0, 126, 0, 0, 137, 97, 96, 0, + 0, 0, 88, 0, 131, 122, 149, 0, 123, 130, + 107, 141, 127, 148, 178, 155, 139, 154, 78, 138, + 147, 87, 132, 80, 145, 136, 112, 101, 102, 79, + 0, 129, 91, 95, 90, 120, 142, 143, 89, 161, + 83, 153, 82, 84, 152, 119, 140, 146, 113, 110, + 81, 144, 111, 109, 103, 93, 98, 124, 108, 125, + 99, 116, 115, 117, 0, 0, 0, 135, 150, 162, + 0, 121, 156, 157, 158, 159, 118, 85, 100, 133, + 92, 0, 0, 0, 0, 104, 0, 106, 0, 0, + 134, 114, 0, 0, 0, 0, 0, 77, 0, 105, + 160, 128, 94, 151, 0, 0, 0, 0, 0, 175, + 0, 0, 0, 0, 0, 0, 0, 0, 86, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 77, 0, 105, 160, 128, 94, 151, + 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 177, 0, 0, 0, 0, 126, + 0, 0, 137, 97, 96, 0, 0, 0, 88, 0, + 131, 122, 149, 0, 123, 130, 107, 141, 127, 148, + 178, 155, 139, 154, 78, 138, 147, 87, 132, 80, + 145, 136, 112, 101, 102, 79, 0, 129, 91, 95, + 90, 120, 142, 143, 89, 161, 83, 153, 82, 84, + 152, 119, 140, 146, 113, 110, 81, 144, 111, 109, + 103, 93, 98, 124, 108, 125, 99, 116, 115, 117, + 0, 0, 0, 135, 150, 162, 0, 0, 156, 157, + 158, 159, 118, 85, 100, 133, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 77, 0, 105, 160, 128, 94, 151, } var yyPact = [...]int{ - 2115, -1000, -176, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1495, -1000, -172, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 737, 758, -1000, -1000, -1000, -1000, -1000, -1000, 554, + 6364, 20, 40, -21, 8735, 39, 178, 9293, -1000, -50, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 514, -1000, -1000, + -1000, -1000, -1000, 727, 734, 567, 718, 646, -1000, 5098, + 14, 7780, 8549, 4441, -1000, 444, 34, 9293, -143, 8921, + 12, 12, 12, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 737, 769, -1000, -1000, -1000, -1000, -1000, -1000, 582, - 6372, 26, 44, -11, 8743, 42, 1237, 9301, -1000, -37, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 533, -1000, -1000, - -1000, -1000, -1000, 727, 733, 556, 717, 656, -1000, 5106, - 27, 7788, 8557, 4449, -1000, 444, 39, 9301, -128, 8929, - 22, 22, 22, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -1582,22 +1586,22 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 36, 9293, -1000, 9293, 9, 436, 9, + 9, 9, 9293, -1000, 68, -1000, -1000, -1000, -1000, 9293, + 427, 680, 27, 2817, 2817, 2817, 2817, -44, 2817, 2817, + 584, -1000, -1000, -1000, -1000, 2817, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 365, 694, 5539, 5539, 737, + -1000, 514, -1000, -1000, -1000, 691, -1000, -1000, 190, 748, + -1000, 6178, 65, -1000, 5539, 2120, 500, -1000, -1000, 500, + -1000, -1000, 50, -1000, -1000, 5959, 5959, 5959, 5959, 5959, + 5959, 5959, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 500, -1000, 5320, 500, + 500, 500, 500, 500, 500, 500, 500, 5539, 500, 500, + 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, + 500, 8363, 481, 793, -1000, -1000, -1000, 715, 7003, 7594, + 9293, 473, -1000, 510, 3977, -1000, -1000, -1000, 114, 7375, + -1000, -1000, -1000, 677, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 41, 9301, -1000, 9301, 8, 439, 8, - 8, 8, 9301, -1000, 90, -1000, -1000, -1000, -1000, 9301, - 436, 682, 72, 2825, 2825, 2825, 2825, -32, 2825, 2825, - 602, -1000, -1000, -1000, -1000, 2825, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 334, 691, 5547, 5547, 737, - -1000, 533, -1000, -1000, -1000, 686, -1000, -1000, 177, 751, - -1000, 6186, 89, -1000, 5547, 2231, 510, -1000, -1000, 510, - -1000, -1000, 67, -1000, -1000, 5967, 5967, 5967, 5967, 5967, - 5967, 5967, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 510, -1000, 5328, 510, - 510, 510, 510, 510, 510, 510, 510, 5547, 510, 510, - 510, 510, 510, 510, 510, 510, 510, 510, 510, 510, - 510, 8371, 477, 750, -1000, -1000, -1000, 714, 7011, 7602, - 9301, 482, -1000, 500, 3985, -1000, -1000, -1000, 140, 7383, - -1000, -1000, -1000, 681, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -1605,172 +1609,171 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 426, -1000, 1496, + 421, 2817, 26, 530, 408, 154, 396, 9293, 9293, 2817, + 22, 9293, 711, 581, 9293, 389, 353, -1000, 4209, -1000, + 2817, 2817, 2817, 2817, 2817, 2817, 2817, 2817, -1000, -1000, + -1000, -1000, -1000, -1000, 2817, 2817, -1000, -1000, 9293, -1000, + -1000, -1000, -1000, 753, 93, 237, 61, 517, -1000, 321, + 727, 365, 646, 7189, 604, -1000, -1000, 9293, -1000, 5539, + 5539, 327, -1000, 8152, -1000, -1000, 3281, 101, 5959, 246, + 128, 5959, 5959, 5959, 5959, 5959, 5959, 5959, 5959, 5959, + 5959, 5959, 5959, 5959, 5959, 5959, 347, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 348, -1000, 514, 429, 429, + 73, 73, 73, 73, 73, 73, 1899, 4660, 365, 419, + 138, 5320, 5098, 5098, 5539, 5539, 9107, 9107, 5098, 719, + 124, 138, 8921, -1000, 365, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 5098, 5098, 5098, 5098, -9, 9293, -1000, 9107, + 7780, 7780, 7780, 7780, 7780, -1000, 634, 626, -1000, 597, + 596, 621, 9293, -1000, 414, 7003, 90, 500, -1000, 7966, + -1000, -1000, -9, 509, 7780, 9293, -1000, -1000, 3977, 510, + 5539, 44, -1000, -1000, -1000, -1000, 2585, 176, 239, -115, + -1000, -1000, -1000, 521, -1000, 521, 521, 521, 521, -85, + -85, -85, -85, -1000, -1000, -1000, -1000, -1000, 539, 537, + -1000, 521, 521, 521, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 435, -1000, 6505, - 432, 2825, 31, 566, 406, 159, 387, 9301, 9301, 2825, - 29, 9301, 711, 601, 9301, 385, 376, -1000, 4217, -1000, - 2825, 2825, 2825, 2825, 2825, 2825, 2825, 2825, -1000, -1000, - -1000, -1000, -1000, -1000, 2825, 2825, -1000, -1000, 9301, -1000, - -1000, -1000, -1000, 764, 110, 445, 88, 501, -1000, 333, - 727, 334, 656, 7197, 613, -1000, -1000, 9301, -1000, 5547, - 5547, 300, -1000, 8160, -1000, -1000, 3289, 121, 5967, 234, - 135, 5967, 5967, 5967, 5967, 5967, 5967, 5967, 5967, 5967, - 5967, 5967, 5967, 5967, 5967, 5967, 227, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 357, -1000, 533, 778, 778, - 76, 76, 76, 76, 76, 76, 1902, 4668, 334, 425, - 256, 5328, 5106, 5106, 5547, 5547, 9115, 9115, 5106, 720, - 145, 256, 8929, -1000, 334, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 5106, 5106, 5106, 5106, -12, 9301, -1000, 9115, - 7788, 7788, 7788, 7788, 7788, -1000, 644, 642, -1000, 635, - 616, 634, 9301, -1000, 414, 7011, 81, 510, -1000, 7974, - -1000, -1000, -12, 7788, 9301, -1000, -1000, 3985, 500, 5547, - 75, -1000, -1000, -1000, -1000, 2593, 126, 272, -96, -1000, - -1000, -1000, 525, -1000, 525, 525, 525, 525, -63, -63, - -63, -63, -1000, -1000, -1000, -1000, -1000, 581, 574, -1000, - 525, 525, 525, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 551, - 551, 551, 535, 535, 584, -1000, 9301, -148, 355, 2825, - 709, 2825, -1000, 273, -1000, 9301, -1000, -1000, 9301, 2825, + 536, 536, 536, 522, 522, 557, -1000, 9293, -162, 341, + 2817, 710, 2817, -1000, 106, -1000, 9293, -1000, -1000, 9293, + 2817, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 660, 5539, + 5539, 3745, 5539, -1000, -1000, -1000, 694, -1000, 719, 732, + -1000, 672, 671, 5098, -1000, -1000, 101, 166, -1000, -1000, + 218, -1000, -1000, -1000, -1000, 60, 500, -1000, 2157, -1000, + -1000, -1000, -1000, 246, 5959, 5959, 5959, 1293, 2157, 2136, + 690, 2044, 73, 233, 233, 77, 77, 77, 77, 77, + 220, 220, -1000, -1000, -1000, 365, -1000, -1000, -1000, 365, + 5098, 495, -1000, -1000, 5539, -1000, 365, 406, 406, 392, + 266, 508, -1000, 59, 505, 406, 5098, 127, -1000, 5539, + 365, -1000, 406, 365, 406, 406, 464, 500, -1000, 506, + -1000, 111, 793, 529, 578, 629, -1000, -1000, -1000, -1000, + 625, -1000, 598, -1000, -1000, -1000, -1000, -1000, 33, 32, + 30, 8921, -1000, 746, 7780, 497, -1000, -1000, 138, -1000, + 337, 494, 2353, -1000, -1000, -1000, -1000, -1000, -1000, 526, + 702, 129, 136, 324, -1000, -1000, 686, -1000, 184, -120, + -1000, -1000, 268, -85, -85, -1000, -1000, 44, 676, 44, + 44, 44, 290, 290, -1000, -1000, -1000, -1000, 254, -1000, + -1000, -1000, 253, -1000, 577, 8921, 2817, -1000, 3513, -1000, + -1000, -1000, -1000, -1000, -1000, 754, 312, 123, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -10, + -1000, 2817, -1000, 651, 138, 138, 58, -1000, -1000, 9293, + -1000, -1000, -1000, -1000, 503, -1000, -1000, -1000, 3049, 5098, + -1000, 1293, 2157, 2025, -1000, 5959, 5959, -1000, -1000, 406, + 5098, 138, -1000, -1000, -1000, 28, 347, 28, 5959, 5959, + 3745, 5959, 5959, -153, 493, 119, -1000, 5539, 280, -1000, + -1000, -1000, -1000, -1000, 575, 9107, 500, -1000, 6793, 8921, + 737, 9107, 5539, 5539, -1000, -1000, 5539, 524, -1000, 5539, + -1000, -1000, -1000, 500, 500, 500, 379, -1000, 737, 497, + -1000, -1000, 2585, -1000, 2585, 8921, -1000, 303, 299, -1000, + -1000, 563, 29, -1000, -1000, -1000, 447, 44, 44, -1000, + 125, -1000, -1000, -1000, 402, -1000, 400, 485, 395, 9293, + -1000, -1000, 482, -1000, 100, -1000, -1000, 8921, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 665, 5547, 5547, - 3753, 5547, -1000, -1000, -1000, 691, -1000, 720, 731, -1000, - 673, 671, 5106, -1000, -1000, 121, 148, -1000, -1000, 338, - -1000, -1000, -1000, -1000, 85, 510, -1000, 1628, -1000, -1000, - -1000, -1000, 234, 5967, 5967, 5967, 43, 1628, 1542, 280, - 220, 76, 294, 294, 100, 100, 100, 100, 100, 71, - 71, -1000, -1000, -1000, 334, -1000, -1000, -1000, 334, 5106, - 494, -1000, -1000, 5547, -1000, 334, 404, 404, 390, 276, - 541, -1000, 79, 527, 404, 5106, 150, -1000, 5547, 334, - -1000, 404, 334, 404, 404, 461, 510, -1000, 507, -1000, - 134, 750, 565, 599, 528, -1000, -1000, -1000, -1000, 623, - -1000, 622, -1000, -1000, -1000, -1000, -1000, 38, 35, 33, - 8929, -1000, 756, 506, -1000, -1000, 256, -1000, 342, 486, - 2361, -1000, -1000, -1000, -1000, -1000, -1000, 540, 699, 129, - 136, 314, -1000, -1000, 685, -1000, 166, -100, -1000, -1000, - 241, -63, -63, -1000, -1000, 75, 679, 75, 75, 75, - 287, 287, -1000, -1000, -1000, -1000, 240, -1000, -1000, -1000, - 232, -1000, 590, 8929, 2825, -1000, 3521, -1000, -1000, -1000, - -1000, -1000, -1000, 628, 356, 173, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -19, -1000, 2825, - -1000, 661, 256, 256, 74, -1000, -1000, 9301, -1000, -1000, - -1000, -1000, 499, -1000, -1000, -1000, 3057, 5106, -1000, 43, - 1628, 1500, -1000, 5967, 5967, -1000, -1000, 404, 5106, 256, - -1000, -1000, -1000, 123, 227, 123, 5967, 5967, 3753, 5967, - 5967, -142, 505, 137, -1000, 5547, 279, -1000, -1000, -1000, - -1000, -1000, 587, 9115, 510, -1000, 6801, 8929, 737, 9115, - 5547, 5547, -1000, -1000, 5547, 536, -1000, 5547, -1000, -1000, - -1000, 510, 510, 510, 383, -1000, 737, -1000, -1000, 2593, - -1000, 2593, 8929, -1000, 298, 281, -1000, -1000, 586, 37, - -1000, -1000, -1000, 451, 75, 75, -1000, 109, -1000, -1000, - -1000, 401, -1000, 399, 483, 396, 9301, -1000, -1000, 479, - -1000, 131, -1000, -1000, 8929, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 8929, 9301, -1000, - -1000, -1000, -1000, -1000, 8929, -1000, -1000, 3521, -1000, 756, - 7788, -1000, -1000, 334, -1000, 5967, 1628, 1628, -1000, -1000, - 334, 525, 525, -1000, 525, 535, -1000, 525, -46, 525, - -47, 334, 334, 1436, 1462, -1000, 1143, 1327, 510, -139, - -1000, 256, 5547, -1000, 702, 454, 473, -1000, -1000, 4887, - 334, 391, 65, 383, 727, -1000, 256, 256, 256, 8929, - 256, 8929, 8929, 8929, 6591, 8929, 727, 2361, -1000, 364, - -1000, 525, -1000, -1000, -87, 763, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -63, 283, -63, - 209, -1000, 183, 2825, 3521, 2593, -1000, 512, -1000, -1000, - -1000, -1000, 704, 748, 476, -1000, 1628, -1000, -1000, 56, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 5967, - 5967, -1000, 5967, 5967, 5967, 334, 270, 256, 697, -1000, - 510, -1000, -1000, 496, 8929, 8929, -1000, -1000, 362, -1000, - 354, 354, 354, 81, -1000, -1000, 584, 8929, -1000, 128, - -1000, -113, 75, -1000, 75, 392, 384, -1000, -1000, -1000, - 8929, 510, 746, 729, -1000, -1000, 796, 796, 796, 796, - -26, -1000, -1000, 761, -1000, 510, -1000, 533, 53, -1000, - 8929, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 175, 696, - -1000, 695, -1000, -1000, -1000, -1000, -1000, 346, -20, -1000, - 5547, 5547, -1000, -1000, -1000, -1000, 334, 51, -152, 9115, - 473, 334, 8929, -1000, -1000, 250, -1000, -1000, 566, 297, - -1000, 8929, 256, 472, -1000, 659, -146, -157, 471, -1000, - -1000, -1000, -148, -1000, -20, 670, -1000, 649, -1000, -1000, - -1000, -23, -149, -25, -153, 510, -158, 5757, -1000, 796, - 334, -1000, -1000, + 8921, 9293, -1000, -1000, -1000, -1000, -1000, 8921, -1000, -1000, + 3513, -1000, 746, 7780, -1000, -1000, 365, -1000, 5959, 2157, + 2157, -1000, -1000, 365, 521, 521, -1000, 521, 522, -1000, + 521, -68, 521, -69, 365, 365, 1664, 1875, -1000, 1441, + 1807, 500, -150, -1000, 138, 5539, -1000, 704, 453, 461, + -1000, -1000, 4879, 365, 393, 57, 379, 727, -1000, 138, + 138, 138, 8921, 138, 8921, 8921, 8921, 6583, 8921, 727, + -1000, 2353, -1000, 376, -1000, 521, -1000, -1000, -108, 752, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -85, 289, -85, 241, -1000, 224, 2817, 3513, 2585, + -1000, 515, -1000, -1000, -1000, -1000, 696, 743, 474, -1000, + 2157, -1000, -1000, 48, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 5959, 5959, -1000, 5959, 5959, 5959, 365, + 281, 138, 699, -1000, 500, -1000, -1000, 499, 8921, 8921, + -1000, -1000, 364, -1000, 352, 352, 352, 90, -1000, -1000, + 557, 8921, -1000, 110, -1000, -132, 44, -1000, 44, 446, + 420, -1000, -1000, -1000, 8921, 500, 741, 733, -1000, -1000, + 1764, 1764, 1764, 1764, 17, -1000, -1000, 751, -1000, 500, + -1000, 514, 47, -1000, 8921, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 168, 695, -1000, 688, -1000, -1000, -1000, -1000, + -1000, 333, -16, -1000, 5539, 5539, -1000, -1000, -1000, -1000, + 365, 37, -165, 9107, 461, 365, 8921, -1000, -1000, 234, + -1000, -1000, 530, 316, -1000, 8921, 138, 456, -1000, 650, + -156, -168, 449, -1000, -1000, -1000, -162, -1000, -16, 670, + -1000, 644, -1000, -1000, -1000, -19, -163, -24, -166, 500, + -169, 5749, -1000, 1764, 365, -1000, -1000, } var yyPgo = [...]int{ - 0, 1007, 35, 501, 1006, 1005, 1004, 1003, 1001, 998, - 997, 994, 993, 992, 990, 989, 988, 987, 986, 985, - 982, 978, 977, 976, 98, 975, 974, 973, 47, 972, - 60, 966, 965, 29, 448, 32, 41, 771, 964, 18, - 87, 106, 963, 34, 960, 959, 957, 955, 63, 954, - 951, 1339, 950, 949, 13, 27, 948, 945, 944, 941, - 51, 383, 937, 936, 934, 921, 912, 911, 40, 3, - 5, 8, 14, 909, 222, 6, 904, 39, 903, 902, - 886, 885, 26, 883, 43, 882, 21, 42, 881, 9, - 50, 25, 20, 4, 58, 880, 28, 44, 878, 248, - 877, 133, 234, 875, 873, 871, 870, 54, 175, 504, - 528, 53, 854, 12, 853, 1299, 55, 45, 19, 849, - 46, 244, 33, 848, 847, 31, 846, 843, 841, 831, - 827, 826, 824, 57, 822, 821, 820, 16, 24, 817, - 816, 52, 23, 813, 812, 810, 30, 49, 809, 38, - 808, 806, 803, 22, 15, 790, 10, 788, 787, 7, - 785, 17, 784, 11, 783, 2, 37, 782, 780, 0, - 661, 779, 777, 59, + 0, 991, 10, 482, 990, 989, 988, 987, 986, 984, + 983, 982, 981, 980, 979, 978, 974, 972, 969, 968, + 967, 966, 965, 964, 101, 963, 958, 957, 52, 952, + 60, 950, 949, 31, 165, 35, 34, 976, 947, 22, + 64, 51, 946, 40, 945, 944, 61, 943, 54, 940, + 936, 1313, 935, 920, 14, 24, 914, 913, 911, 906, + 55, 175, 904, 900, 899, 898, 897, 894, 41, 5, + 9, 15, 17, 893, 80, 6, 892, 43, 891, 890, + 889, 888, 42, 887, 45, 878, 21, 44, 877, 8, + 47, 29, 27, 4, 63, 876, 26, 50, 875, 303, + 869, 123, 328, 868, 867, 866, 865, 32, 176, 506, + 429, 57, 864, 12, 859, 1287, 59, 53, 18, 858, + 28, 344, 30, 857, 856, 33, 854, 853, 850, 849, + 848, 843, 842, 258, 833, 828, 826, 25, 13, 822, + 820, 46, 38, 819, 818, 815, 37, 49, 814, 39, + 812, 811, 808, 23, 20, 805, 16, 802, 799, 7, + 794, 19, 793, 3, 778, 2, 36, 777, 776, 0, + 583, 773, 764, 102, } var yyR1 = [...]int{ 0, 167, 168, 168, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 6, 3, 4, 4, 5, - 5, 7, 7, 27, 27, 8, 9, 9, 171, 171, - 46, 46, 90, 90, 10, 10, 123, 123, 11, 11, - 11, 11, 11, 11, 11, 165, 165, 164, 163, 163, - 162, 162, 161, 16, 150, 151, 151, 151, 147, 126, - 126, 126, 126, 129, 129, 127, 127, 127, 127, 127, - 127, 127, 128, 128, 128, 128, 128, 130, 130, 130, - 130, 130, 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 132, 132, 132, - 132, 132, 132, 132, 132, 146, 146, 133, 133, 141, - 141, 142, 142, 142, 139, 139, 140, 140, 143, 143, - 143, 134, 134, 134, 134, 134, 134, 134, 136, 136, - 144, 144, 137, 137, 137, 138, 138, 145, 145, 145, - 145, 145, 135, 135, 148, 155, 155, 155, 155, 155, - 149, 149, 157, 157, 156, 152, 152, 152, 153, 153, - 153, 154, 154, 154, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 166, 166, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 160, 158, 158, 159, 159, 13, - 14, 14, 14, 14, 14, 15, 15, 17, 18, 18, + 5, 7, 7, 27, 27, 8, 9, 9, 9, 171, + 171, 46, 46, 90, 90, 10, 10, 123, 123, 11, + 11, 11, 11, 11, 11, 11, 165, 165, 164, 163, + 163, 162, 162, 161, 16, 150, 151, 151, 151, 147, + 126, 126, 126, 126, 129, 129, 127, 127, 127, 127, + 127, 127, 127, 128, 128, 128, 128, 128, 130, 130, + 130, 130, 130, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 132, 132, + 132, 132, 132, 132, 132, 132, 146, 146, 133, 133, + 141, 141, 142, 142, 142, 139, 139, 140, 140, 143, + 143, 143, 134, 134, 134, 134, 134, 134, 134, 136, + 136, 144, 144, 137, 137, 137, 138, 138, 145, 145, + 145, 145, 145, 135, 135, 148, 155, 155, 155, 155, + 155, 149, 149, 157, 157, 156, 152, 152, 152, 153, + 153, 153, 154, 154, 154, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 166, 166, 166, 166, 166, 166, + 166, 166, 166, 166, 166, 160, 158, 158, 159, 159, + 13, 14, 14, 14, 14, 14, 15, 15, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 124, 124, 124, 19, 19, 21, 21, 22, 23, - 20, 20, 20, 20, 20, 172, 24, 25, 25, 26, - 26, 26, 30, 30, 30, 28, 28, 29, 29, 35, - 35, 34, 34, 36, 36, 36, 36, 112, 112, 112, - 111, 111, 38, 38, 39, 39, 40, 40, 41, 41, - 41, 53, 53, 89, 89, 91, 91, 42, 42, 42, - 42, 43, 43, 44, 44, 45, 45, 119, 119, 118, - 118, 118, 117, 117, 47, 47, 47, 49, 48, 48, - 48, 48, 50, 50, 52, 52, 51, 51, 54, 54, - 54, 54, 55, 55, 37, 37, 37, 37, 37, 37, - 37, 100, 100, 57, 57, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 56, 67, 67, 67, 67, 67, - 67, 58, 58, 58, 58, 58, 58, 58, 33, 33, - 68, 68, 68, 74, 69, 69, 61, 61, 61, 61, + 18, 18, 124, 124, 124, 19, 19, 21, 21, 22, + 23, 20, 20, 20, 20, 20, 172, 24, 25, 25, + 26, 26, 26, 30, 30, 30, 28, 28, 29, 29, + 35, 35, 34, 34, 36, 36, 36, 36, 112, 112, + 112, 111, 111, 38, 38, 39, 39, 40, 40, 41, + 41, 41, 53, 53, 89, 89, 91, 91, 42, 42, + 42, 42, 43, 43, 44, 44, 45, 45, 119, 119, + 118, 118, 118, 117, 117, 47, 47, 47, 49, 48, + 48, 48, 48, 50, 50, 52, 52, 51, 51, 54, + 54, 54, 54, 55, 55, 37, 37, 37, 37, 37, + 37, 37, 100, 100, 57, 57, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 67, 67, 67, 67, + 67, 67, 58, 58, 58, 58, 58, 58, 58, 33, + 33, 68, 68, 68, 74, 69, 69, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 61, 61, 61, 61, 61, 65, 65, 65, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, - 64, 64, 64, 173, 173, 66, 66, 66, 66, 31, - 31, 31, 31, 31, 122, 122, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 125, 125, 78, - 78, 32, 32, 76, 76, 77, 79, 79, 75, 75, - 75, 60, 60, 60, 60, 60, 60, 60, 60, 62, - 62, 62, 80, 80, 81, 81, 82, 82, 83, 83, - 84, 85, 85, 85, 86, 86, 86, 86, 87, 87, - 87, 59, 59, 59, 59, 59, 59, 88, 88, 88, - 88, 92, 92, 70, 70, 72, 72, 71, 73, 93, - 93, 96, 94, 94, 97, 97, 95, 95, 95, 114, - 114, 114, 98, 98, 101, 101, 102, 102, 99, 99, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 104, 104, 104, 105, 105, 106, 106, 106, 113, 113, - 109, 109, 110, 110, 115, 115, 116, 116, 107, 107, + 61, 61, 61, 61, 61, 61, 61, 61, 65, 65, + 65, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, + 64, 64, 64, 64, 173, 173, 66, 66, 66, 66, + 31, 31, 31, 31, 31, 122, 122, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 78, 78, 32, 32, 76, 76, 77, 79, 79, 75, + 75, 75, 60, 60, 60, 60, 60, 60, 60, 60, + 62, 62, 62, 80, 80, 81, 81, 82, 82, 83, + 83, 84, 85, 85, 85, 86, 86, 86, 86, 87, + 87, 87, 59, 59, 59, 59, 59, 59, 88, 88, + 88, 88, 92, 92, 70, 70, 72, 72, 71, 73, + 93, 93, 96, 94, 94, 97, 97, 95, 95, 95, + 114, 114, 114, 98, 98, 101, 101, 102, 102, 99, + 99, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 104, 104, 104, 105, 105, 106, 106, 106, 113, + 113, 109, 109, 110, 110, 115, 115, 116, 116, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, @@ -1780,6 +1783,7 @@ var yyR1 = [...]int{ 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, @@ -1787,68 +1791,67 @@ var yyR1 = [...]int{ 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 169, 170, - 120, 121, 121, 121, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 169, + 170, 120, 121, 121, 121, } var yyR2 = [...]int{ 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 7, 5, 10, 1, 3, 1, - 3, 7, 8, 1, 1, 8, 8, 6, 1, 1, - 1, 3, 0, 4, 3, 4, 1, 1, 2, 8, - 4, 6, 5, 5, 5, 0, 2, 1, 0, 2, - 1, 3, 3, 4, 4, 1, 3, 3, 8, 3, - 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, - 2, 1, 4, 4, 2, 2, 3, 3, 3, 3, - 1, 1, 1, 1, 1, 6, 6, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 0, 3, 0, - 5, 0, 3, 5, 0, 1, 0, 1, 0, 1, - 2, 0, 2, 2, 2, 2, 2, 2, 0, 3, - 0, 1, 0, 3, 3, 0, 2, 0, 2, 1, - 2, 1, 0, 2, 5, 2, 3, 3, 2, 2, - 1, 1, 1, 3, 2, 0, 1, 3, 1, 2, - 3, 1, 1, 1, 6, 7, 7, 12, 7, 7, - 7, 4, 5, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 7, 1, 3, 8, 8, 5, - 4, 6, 5, 4, 4, 3, 2, 3, 4, 4, - 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, - 4, 3, 3, 4, 2, 4, 2, 2, 2, 2, - 3, 0, 1, 1, 2, 1, 1, 2, 1, 1, - 2, 2, 2, 2, 2, 0, 2, 0, 2, 1, - 2, 2, 0, 1, 1, 0, 1, 0, 1, 0, - 1, 1, 3, 1, 2, 3, 5, 0, 1, 2, - 1, 1, 0, 2, 1, 3, 1, 1, 1, 3, - 3, 3, 7, 1, 3, 1, 3, 4, 4, 4, - 3, 2, 4, 0, 1, 0, 2, 0, 1, 0, - 1, 2, 1, 1, 1, 2, 2, 1, 2, 3, - 2, 3, 2, 2, 2, 1, 1, 3, 0, 5, - 5, 5, 0, 2, 1, 3, 3, 2, 3, 1, - 2, 0, 3, 1, 1, 3, 3, 4, 4, 5, - 3, 4, 5, 6, 2, 1, 2, 1, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, - 2, 2, 3, 1, 1, 1, 1, 4, 5, 6, - 4, 4, 6, 6, 6, 6, 8, 8, 6, 8, - 8, 9, 7, 5, 4, 2, 2, 2, 2, 2, - 2, 2, 2, 0, 2, 4, 4, 4, 4, 0, - 3, 4, 7, 3, 1, 1, 2, 3, 3, 1, - 2, 2, 1, 2, 1, 2, 2, 1, 2, 0, - 1, 0, 2, 1, 2, 4, 0, 2, 1, 3, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 0, 3, 0, 2, 0, 3, 1, 3, - 2, 0, 1, 1, 0, 2, 4, 4, 0, 2, - 4, 2, 1, 3, 5, 4, 6, 1, 3, 3, - 5, 0, 5, 1, 3, 1, 2, 3, 1, 1, - 3, 3, 1, 3, 3, 3, 1, 2, 1, 1, - 1, 1, 1, 1, 0, 2, 0, 3, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 1, 1, 1, 1, 0, 1, 1, 0, 2, + 3, 7, 8, 1, 1, 8, 8, 7, 6, 1, + 1, 1, 3, 0, 4, 3, 4, 1, 1, 2, + 8, 4, 6, 5, 5, 5, 0, 2, 1, 0, + 2, 1, 3, 3, 4, 4, 1, 3, 3, 8, + 3, 1, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, + 2, 2, 1, 4, 4, 2, 2, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 6, 6, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 0, 3, + 0, 5, 0, 3, 5, 0, 1, 0, 1, 0, + 1, 2, 0, 2, 2, 2, 2, 2, 2, 0, + 3, 0, 1, 0, 3, 3, 0, 2, 0, 2, + 1, 2, 1, 0, 2, 5, 2, 3, 3, 2, + 2, 1, 1, 1, 3, 2, 0, 1, 3, 1, + 2, 3, 1, 1, 1, 6, 7, 7, 12, 7, + 7, 7, 4, 5, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 7, 1, 3, 8, 8, + 5, 4, 6, 5, 4, 4, 3, 2, 3, 4, + 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, + 3, 4, 3, 3, 4, 2, 4, 2, 2, 2, + 2, 3, 0, 1, 1, 2, 1, 1, 2, 1, + 1, 2, 2, 2, 2, 2, 0, 2, 0, 2, + 1, 2, 2, 0, 1, 1, 0, 1, 0, 1, + 0, 1, 1, 3, 1, 2, 3, 5, 0, 1, + 2, 1, 1, 0, 2, 1, 3, 1, 1, 1, + 3, 3, 3, 7, 1, 3, 1, 3, 4, 4, + 4, 3, 2, 4, 0, 1, 0, 2, 0, 1, + 0, 1, 2, 1, 1, 1, 2, 2, 1, 2, + 3, 2, 3, 2, 2, 2, 1, 1, 3, 0, + 5, 5, 5, 0, 2, 1, 3, 3, 2, 3, + 1, 2, 0, 3, 1, 1, 3, 3, 4, 4, + 5, 3, 4, 5, 6, 2, 1, 2, 1, 2, + 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, + 2, 1, 1, 1, 3, 1, 3, 1, 1, 1, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, + 2, 2, 2, 3, 1, 1, 1, 1, 4, 5, + 6, 4, 4, 6, 6, 6, 6, 8, 8, 6, + 8, 8, 9, 7, 5, 4, 2, 2, 2, 2, + 2, 2, 2, 2, 0, 2, 4, 4, 4, 4, + 0, 3, 4, 7, 3, 1, 1, 2, 3, 3, + 1, 2, 2, 1, 2, 1, 2, 2, 1, 2, + 0, 1, 0, 2, 1, 2, 4, 0, 2, 1, + 3, 5, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 0, 3, 0, 2, 0, 3, 1, + 3, 2, 0, 1, 1, 0, 2, 4, 4, 0, + 2, 4, 2, 1, 3, 5, 4, 6, 1, 3, + 3, 5, 0, 5, 1, 3, 1, 2, 3, 1, + 1, 3, 3, 1, 3, 3, 3, 1, 2, 1, + 1, 1, 1, 1, 1, 0, 2, 0, 3, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -1867,7 +1870,7 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 1, 1, + 1, 0, 0, 1, 1, } var yyChk = [...]int{ @@ -1927,201 +1930,201 @@ var yyChk = [...]int{ -173, -173, -169, -169, -169, -169, -52, 26, -51, 30, 54, -47, -49, -48, -50, 41, 45, 47, 42, 43, 44, 48, -119, 22, -39, -169, -118, 141, -117, 22, - -115, 58, -51, -171, 54, 11, 52, 54, -94, 80, - -114, -109, 58, 29, 30, 55, 54, -126, -129, -131, - -130, -132, -127, -128, 173, 174, 106, 177, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 30, 135, - 169, 170, 171, 172, 189, 190, 191, 192, 193, 194, - 195, 196, 156, 157, 158, 159, 160, 161, 162, 164, - 165, 166, 167, 168, 56, -121, 121, -165, 52, 56, - 72, 56, -51, -51, -121, 122, -51, 23, 51, -51, - 56, 56, -116, -115, -107, -121, -121, -121, -121, -121, - -121, -121, -121, -121, -121, -51, 9, 90, 54, 18, - 109, 54, -85, 24, 25, -86, -170, -30, -62, -109, - 59, 62, -29, 42, -51, -37, -37, -67, 67, 72, - 68, 69, -111, 97, -116, -110, -107, -61, -68, -71, - -74, 63, 90, 88, 89, 74, -61, -61, -61, -61, + -115, 58, -51, -46, -171, 54, 11, 52, 54, -94, + 80, -114, -109, 58, 29, 30, 55, 54, -126, -129, + -131, -130, -132, -127, -128, 173, 174, 106, 177, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 30, + 135, 169, 170, 171, 172, 189, 190, 191, 192, 193, + 194, 195, 196, 156, 157, 158, 159, 160, 161, 162, + 164, 165, 166, 167, 168, 56, -121, 121, -165, 52, + 56, 72, 56, -51, -51, -121, 122, -51, 23, 51, + -51, 56, 56, -116, -115, -107, -121, -121, -121, -121, + -121, -121, -121, -121, -121, -121, -51, 9, 90, 54, + 18, 109, 54, -85, 24, 25, -86, -170, -30, -62, + -109, 59, 62, -29, 42, -51, -37, -37, -67, 67, + 72, 68, 69, -111, 97, -116, -110, -107, -61, -68, + -71, -74, 63, 90, 88, 89, 74, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, -61, - -61, -122, 56, 58, 56, -60, -60, -109, -35, 21, - -34, -36, -170, 54, -170, -2, -34, -34, -37, -37, - -75, -109, -115, -75, -34, -28, -76, -77, 76, -109, - -170, -34, -35, -34, -34, -90, 141, -51, -93, -96, - -75, -40, -41, -41, -40, -41, 41, 41, 41, 46, - 41, 46, 41, -48, -115, -170, -54, 49, 123, 50, - -169, -117, -90, -39, -51, -97, -37, -138, 105, -152, - -153, -154, -110, 58, 59, -147, -148, -155, 126, 129, - 125, -149, 120, 28, -143, 67, 72, -139, 201, -133, - 53, -133, -133, -133, -133, -137, 176, -137, -137, -137, - 53, 53, -133, -133, -133, -141, 53, -141, -141, -142, - 53, -142, -113, 52, -51, -163, 233, -164, 56, -121, - 23, -121, -103, 117, 114, 115, -160, 113, 198, 176, - 65, 29, 15, 223, 141, 236, 56, 142, -51, -51, - -121, 37, -37, -37, -116, -84, -87, -98, 19, 11, - 33, 33, -34, 67, 68, 69, 109, -169, -68, -61, - -61, -61, -33, 136, 71, -170, -170, -34, 54, -37, - -170, -170, -170, 54, 52, 22, 54, 11, 109, 54, - 11, -170, -34, -79, -77, 78, -37, -170, -170, -170, - -170, -170, -59, 30, 33, -2, -169, -169, -55, 54, - 12, 80, -44, -43, 51, 52, -45, 51, -43, 41, - 41, 120, 120, 120, -91, -109, -55, -55, 56, 54, - -154, 80, 53, 28, -149, -149, 56, 56, -134, 29, - 67, -140, 202, 59, -137, -137, -138, 30, -138, -138, - -138, -146, 58, -146, 59, 59, 51, -109, -121, -162, - -161, -110, -120, -166, 147, 127, 128, 131, 130, 56, - 120, 28, 126, 129, 141, 125, -166, 147, -104, -105, - 122, 22, 120, 28, 141, -121, 38, 109, -51, -38, - 11, 97, -110, -35, -33, 71, -61, -61, -170, -36, - -125, 106, 173, 135, 171, 167, 187, 178, 200, 169, - 201, -122, -125, -61, -61, -110, -61, -61, 230, -82, - 79, -37, 77, -92, 51, -93, -70, -72, -71, -169, - -2, -88, -109, -91, -82, -96, -37, -37, -37, 53, - -37, -169, -169, -169, -170, 54, -82, -153, -154, -157, - -156, -109, 56, 56, -136, 51, 58, 59, 60, 67, - 213, 66, 55, -138, -138, 56, 106, 55, 54, 55, - 54, 55, 54, -51, 54, 80, -120, -109, -120, -109, - -51, -120, -109, -55, -39, -170, -61, -170, -133, -133, - -133, -142, -133, 161, -133, 161, -170, -170, -170, 54, - 19, -170, 54, 19, -169, -32, 228, -37, 27, -92, - 54, -170, -170, -170, 54, 109, -170, -86, -89, -109, - -89, -89, -89, -118, -109, -86, 55, 54, -133, -144, - 198, 9, -137, 58, -137, 59, 59, -121, -161, -154, - 53, 26, -80, 13, -137, 56, -61, -61, -61, -61, - -61, -170, 58, 28, -72, 33, -2, -169, -109, -109, - 54, 55, -170, -170, -170, -54, -113, -156, -145, 126, - 28, 125, 213, -138, -138, 55, 55, -89, -169, -81, - 14, 16, -170, -170, -170, -170, -31, 90, 233, 9, - -70, -2, 109, -109, -135, 65, 28, 28, 55, -158, - -159, 141, -37, -69, -170, 231, 48, 234, -93, -170, - -109, 58, -165, -170, 54, -109, 38, 232, 235, -163, - -159, 33, 38, 143, 233, 144, 234, -169, 235, -61, - 140, -170, -170, + -61, -61, -122, 56, 58, 56, -60, -60, -109, -35, + 21, -34, -36, -170, 54, -170, -2, -34, -34, -37, + -37, -75, -109, -115, -75, -34, -28, -76, -77, 76, + -109, -170, -34, -35, -34, -34, -90, 141, -51, -93, + -96, -75, -40, -41, -41, -40, -41, 41, 41, 41, + 46, 41, 46, 41, -48, -115, -170, -54, 49, 123, + 50, -169, -117, -90, 52, -39, -51, -97, -37, -138, + 105, -152, -153, -154, -110, 58, 59, -147, -148, -155, + 126, 129, 125, -149, 120, 28, -143, 67, 72, -139, + 201, -133, 53, -133, -133, -133, -133, -137, 176, -137, + -137, -137, 53, 53, -133, -133, -133, -141, 53, -141, + -141, -142, 53, -142, -113, 52, -51, -163, 233, -164, + 56, -121, 23, -121, -103, 117, 114, 115, -160, 113, + 198, 176, 65, 29, 15, 223, 141, 236, 56, 142, + -51, -51, -121, 37, -37, -37, -116, -84, -87, -98, + 19, 11, 33, 33, -34, 67, 68, 69, 109, -169, + -68, -61, -61, -61, -33, 136, 71, -170, -170, -34, + 54, -37, -170, -170, -170, 54, 52, 22, 54, 11, + 109, 54, 11, -170, -34, -79, -77, 78, -37, -170, + -170, -170, -170, -170, -59, 30, 33, -2, -169, -169, + -55, 54, 12, 80, -44, -43, 51, 52, -45, 51, + -43, 41, 41, 120, 120, 120, -91, -109, -55, -39, + -55, 56, 54, -154, 80, 53, 28, -149, -149, 56, + 56, -134, 29, 67, -140, 202, 59, -137, -137, -138, + 30, -138, -138, -138, -146, 58, -146, 59, 59, 51, + -109, -121, -162, -161, -110, -120, -166, 147, 127, 128, + 131, 130, 56, 120, 28, 126, 129, 141, 125, -166, + 147, -104, -105, 122, 22, 120, 28, 141, -121, 38, + 109, -51, -38, 11, 97, -110, -35, -33, 71, -61, + -61, -170, -36, -125, 106, 173, 135, 171, 167, 187, + 178, 200, 169, 201, -122, -125, -61, -61, -110, -61, + -61, 230, -82, 79, -37, 77, -92, 51, -93, -70, + -72, -71, -169, -2, -88, -109, -91, -82, -96, -37, + -37, -37, 53, -37, -169, -169, -169, -170, 54, -82, + -55, -153, -154, -157, -156, -109, 56, 56, -136, 51, + 58, 59, 60, 67, 213, 66, 55, -138, -138, 56, + 106, 55, 54, 55, 54, 55, 54, -51, 54, 80, + -120, -109, -120, -109, -51, -120, -109, -55, -39, -170, + -61, -170, -133, -133, -133, -142, -133, 161, -133, 161, + -170, -170, -170, 54, 19, -170, 54, 19, -169, -32, + 228, -37, 27, -92, 54, -170, -170, -170, 54, 109, + -170, -86, -89, -109, -89, -89, -89, -118, -109, -86, + 55, 54, -133, -144, 198, 9, -137, 58, -137, 59, + 59, -121, -161, -154, 53, 26, -80, 13, -137, 56, + -61, -61, -61, -61, -61, -170, 58, 28, -72, 33, + -2, -169, -109, -109, 54, 55, -170, -170, -170, -54, + -113, -156, -145, 126, 28, 125, 213, -138, -138, 55, + 55, -89, -169, -81, 14, 16, -170, -170, -170, -170, + -31, 90, 233, 9, -70, -2, 109, -109, -135, 65, + 28, 28, 55, -158, -159, 141, -37, -69, -170, 231, + 48, 234, -93, -170, -109, 58, -165, -170, 54, -109, + 38, 232, 235, -163, -159, 33, 38, 143, 233, 144, + 234, -169, 235, -61, 140, -170, -170, } var yyDef = [...]int{ 0, -2, 2, -2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 476, 0, 245, 245, 245, 245, 245, 245, 0, - 545, 528, 0, 0, 0, 0, 231, 235, 236, 0, - 238, 239, 740, 740, 740, 740, 740, 0, 33, 34, - 738, 1, 3, 484, 0, 0, 249, 252, 247, 0, - 528, 0, 0, 0, 48, 0, 0, 728, 0, 729, - 526, 526, 526, 546, 547, 550, 551, 650, 651, 652, - 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, - 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, - 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, - 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, - 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, - 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, - 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, - 723, 724, 725, 726, 727, 730, 731, 732, 733, 734, - 735, 736, 737, 0, 0, 529, 0, 524, 0, 524, - 524, 524, 0, 206, 316, 554, 555, 728, 729, 0, - 0, 0, 0, 741, 741, 741, 741, 0, 741, 741, - 224, 226, 227, 228, 229, 741, 232, 233, 234, 237, - 240, 241, 242, 243, 244, 27, 488, 0, 0, 476, - 29, 0, 245, 250, 251, 255, 253, 254, 246, 0, - 263, 267, 0, 324, 0, 329, 331, -2, -2, 0, - 366, 367, 368, 369, 370, 0, 0, 0, 0, 0, - 0, 0, 393, 394, 395, 396, 461, 462, 463, 464, - 465, 466, 467, 468, 333, 334, 458, 508, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 449, 0, 423, - 423, 423, 423, 423, 423, 423, 423, 0, 0, 0, - 0, 0, 0, 274, 276, 277, 278, 297, 0, 299, - 0, 0, 40, 44, 0, 512, -2, -2, 0, 0, - 552, 553, -2, 657, -2, 558, 559, 560, 561, 562, - 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, - 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, - 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, - 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, - 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, - 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, - 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, - 643, 644, 645, 646, 647, 648, 649, 0, 65, 0, - 0, 741, 0, 55, 0, 0, 0, 0, 0, 741, - 0, 0, 0, 0, 0, 0, 0, 205, 0, 207, - 741, 741, 741, 741, 741, 741, 741, 741, 216, 742, - 743, 217, 218, 219, 741, 741, 221, 222, 0, 230, - 28, 739, 22, 0, 0, 485, 0, 477, 478, 481, - 484, 27, 252, 0, 257, 256, 248, 0, 264, 0, - 0, 0, 268, 0, 270, 271, 0, 327, 0, 0, + 21, 477, 0, 246, 246, 246, 246, 246, 246, 0, + 546, 529, 0, 0, 0, 0, 232, 236, 237, 0, + 239, 240, 741, 741, 741, 741, 741, 0, 33, 34, + 739, 1, 3, 485, 0, 0, 250, 253, 248, 0, + 529, 0, 0, 0, 49, 0, 0, 729, 0, 730, + 527, 527, 527, 547, 548, 551, 552, 651, 652, 653, + 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, + 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, + 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, + 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, + 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, + 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, + 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, + 724, 725, 726, 727, 728, 731, 732, 733, 734, 735, + 736, 737, 738, 0, 0, 530, 0, 525, 0, 525, + 525, 525, 0, 207, 317, 555, 556, 729, 730, 0, + 0, 0, 0, 742, 742, 742, 742, 0, 742, 742, + 225, 227, 228, 229, 230, 742, 233, 234, 235, 238, + 241, 242, 243, 244, 245, 27, 489, 0, 0, 477, + 29, 0, 246, 251, 252, 256, 254, 255, 247, 0, + 264, 268, 0, 325, 0, 330, 332, -2, -2, 0, + 367, 368, 369, 370, 371, 0, 0, 0, 0, 0, + 0, 0, 394, 395, 396, 397, 462, 463, 464, 465, + 466, 467, 468, 469, 334, 335, 459, 509, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 450, 0, 424, + 424, 424, 424, 424, 424, 424, 424, 0, 0, 0, + 0, 0, 0, 275, 277, 278, 279, 298, 0, 300, + 0, 0, 41, 45, 0, 513, -2, -2, 0, 0, + 553, 554, -2, 658, -2, 559, 560, 561, 562, 563, + 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, + 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, + 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, + 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, + 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, + 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, + 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, + 644, 645, 646, 647, 648, 649, 650, 0, 66, 0, + 0, 742, 0, 56, 0, 0, 0, 0, 0, 742, + 0, 0, 0, 0, 0, 0, 0, 206, 0, 208, + 742, 742, 742, 742, 742, 742, 742, 742, 217, 743, + 744, 218, 219, 220, 742, 742, 222, 223, 0, 231, + 28, 740, 22, 0, 0, 486, 0, 478, 479, 482, + 485, 27, 253, 0, 258, 257, 249, 0, 265, 0, + 0, 0, 269, 0, 271, 272, 0, 328, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 351, 352, 353, - 354, 355, 356, 357, 330, 0, 344, 0, 0, 0, - 386, 387, 388, 389, 390, 391, 0, 259, 27, 0, - 364, 0, 0, 0, 0, 0, 0, 0, 0, 255, - 0, 450, 0, 415, 0, 416, 417, 418, 419, 420, - 421, 422, 0, 259, 0, 0, 42, 0, 315, 0, - 0, 0, 0, 0, 0, 304, 0, 0, 307, 0, - 0, 0, 0, 298, 0, 0, 318, 696, 300, 0, - 302, 303, 42, 0, 0, 38, 39, 0, 45, 0, - 145, 519, 520, 521, 517, 165, 0, 128, 124, 70, - 71, 72, 117, 74, 117, 117, 117, 117, 142, 142, - 142, 142, 100, 101, 102, 103, 104, 0, 0, 87, - 117, 117, 117, 91, 107, 108, 109, 110, 111, 112, - 113, 114, 75, 76, 77, 78, 79, 80, 81, 119, - 119, 119, 121, 121, 548, 50, 0, 58, 0, 741, - 0, 741, 63, 0, 181, 0, 200, 525, 0, 741, - 203, 204, 317, 556, 557, 208, 209, 210, 211, 212, - 213, 214, 215, 220, 223, 225, 489, 0, 0, 0, - 0, 0, 480, 482, 483, 488, 30, 255, 0, 469, - 0, 0, 0, 258, 25, 325, 326, 328, 345, 0, - 347, 349, 269, 265, 0, 459, -2, 335, 336, 360, - 361, 362, 0, 0, 0, 0, 358, 340, 0, 371, + 0, 0, 0, 0, 0, 0, 0, 352, 353, 354, + 355, 356, 357, 358, 331, 0, 345, 0, 0, 0, + 387, 388, 389, 390, 391, 392, 0, 260, 27, 0, + 365, 0, 0, 0, 0, 0, 0, 0, 0, 256, + 0, 451, 0, 416, 0, 417, 418, 419, 420, 421, + 422, 423, 0, 260, 0, 0, 43, 0, 316, 0, + 0, 0, 0, 0, 0, 305, 0, 0, 308, 0, + 0, 0, 0, 299, 0, 0, 319, 697, 301, 0, + 303, 304, -2, 0, 0, 0, 39, 40, 0, 46, + 0, 146, 520, 521, 522, 518, 166, 0, 129, 125, + 71, 72, 73, 118, 75, 118, 118, 118, 118, 143, + 143, 143, 143, 101, 102, 103, 104, 105, 0, 0, + 88, 118, 118, 118, 92, 108, 109, 110, 111, 112, + 113, 114, 115, 76, 77, 78, 79, 80, 81, 82, + 120, 120, 120, 122, 122, 549, 51, 0, 59, 0, + 742, 0, 742, 64, 0, 182, 0, 201, 526, 0, + 742, 204, 205, 318, 557, 558, 209, 210, 211, 212, + 213, 214, 215, 216, 221, 224, 226, 490, 0, 0, + 0, 0, 0, 481, 483, 484, 489, 30, 256, 0, + 470, 0, 0, 0, 259, 25, 326, 327, 329, 346, + 0, 348, 350, 270, 266, 0, 460, -2, 336, 337, + 361, 362, 363, 0, 0, 0, 0, 359, 341, 0, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 385, 434, 435, 0, 383, 384, 392, 0, 0, - 260, 261, 363, 0, 507, 27, 0, 0, 0, 0, - 0, 458, 0, 0, 0, 0, 456, 453, 0, 0, - 424, 0, 0, 0, 0, 0, 0, 314, 322, 509, - 0, 275, 293, 295, 0, 290, 305, 306, 308, 0, - 310, 0, 312, 313, 279, 280, 281, 0, 0, 0, - 0, 301, 322, 322, 41, 513, 514, 515, 0, 64, - 166, 168, 171, 172, 173, 66, 67, 0, 0, 0, - 0, 0, 160, 161, 131, 129, 0, 126, 125, 73, - 0, 142, 142, 94, 95, 145, 0, 145, 145, 145, - 0, 0, 88, 89, 90, 82, 0, 83, 84, 85, - 0, 86, 0, 0, 741, 52, 0, 56, 57, 53, - 527, 54, 740, 0, 0, 540, 182, 530, 531, 532, - 533, 534, 535, 536, 537, 538, 539, 0, 199, 741, - 202, 0, 486, 487, 0, 479, 23, 0, 522, 523, - 470, 471, 272, 346, 348, 350, 0, 259, 337, 358, - 341, 0, 338, 0, 0, 332, 397, 0, 0, 365, - -2, 400, 401, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 476, 0, 454, 0, 0, 414, 425, 426, - 427, 428, 501, 0, 0, -2, 0, 0, 476, 0, - 0, 0, 287, 294, 0, 0, 288, 0, 289, 309, - 311, 0, 0, 0, 0, 285, 476, 37, 146, 0, - 169, 0, 0, 155, 0, 0, 158, 159, 138, 0, - 130, 69, 127, 0, 145, 145, 96, 0, 97, 98, - 99, 0, 115, 0, 0, 0, 0, 549, 51, 59, - 60, 0, 174, 740, 0, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 740, 0, 0, 740, - 541, 542, 543, 544, 0, 201, 490, 0, 24, 322, - 0, 266, 460, 0, 339, 0, 359, 342, 398, 262, - 0, 117, 117, 439, 117, 121, 442, 117, 444, 117, - 447, 0, 0, 0, 0, 459, 0, 0, 0, 451, - 413, 457, 0, 31, 0, 501, 491, 503, 505, 0, - 27, 0, 497, 0, 484, 510, 323, 511, 291, 0, - 296, 0, 0, 0, 299, 0, 484, 167, 170, 0, - 162, 117, 156, 157, 140, 0, 132, 133, 134, 135, - 136, 137, 118, 92, 93, 143, 144, 142, 0, 142, - 0, 122, 0, 741, 0, 0, 175, 0, 176, 178, - 179, 180, 0, 472, 273, 399, 343, 402, 436, 142, - 440, 441, 443, 445, 446, 448, 404, 403, 405, 0, - 0, 408, 0, 0, 0, 0, 0, 455, 0, 32, - 0, 506, -2, 0, 0, 0, 43, 35, 0, 283, - 0, 0, 0, 318, 286, 36, 548, 0, 164, 147, - 141, 0, 145, 116, 145, 0, 0, 49, 61, 62, - 0, 0, 474, 0, 437, 438, 0, 0, 0, 0, - 429, 412, 452, 0, 504, 0, -2, 0, 499, 498, - 0, 292, 319, 320, 321, 282, 154, 163, 152, 0, - 149, 151, 139, 105, 106, 120, 123, 0, 0, 26, - 0, 0, 406, 407, 409, 410, 0, 0, 0, 0, - 494, 27, 0, 284, 68, 0, 148, 150, 55, 0, - 195, 0, 475, 473, 411, 0, 0, 0, 502, -2, - 500, 153, 58, 194, 0, 0, 430, 0, 433, 177, - 196, 0, 431, 0, 0, 0, 0, 0, 432, 0, - 0, 197, 198, + 382, 383, 386, 435, 436, 0, 384, 385, 393, 0, + 0, 261, 262, 364, 0, 508, 27, 0, 0, 0, + 0, 0, 459, 0, 0, 0, 0, 457, 454, 0, + 0, 425, 0, 0, 0, 0, 0, 0, 315, 323, + 510, 0, 276, 294, 296, 0, 291, 306, 307, 309, + 0, 311, 0, 313, 314, 280, 281, 282, 0, 0, + 0, 0, 302, 323, 0, 323, 42, 514, 515, 516, + 0, 65, 167, 169, 172, 173, 174, 67, 68, 0, + 0, 0, 0, 0, 161, 162, 132, 130, 0, 127, + 126, 74, 0, 143, 143, 95, 96, 146, 0, 146, + 146, 146, 0, 0, 89, 90, 91, 83, 0, 84, + 85, 86, 0, 87, 0, 0, 742, 53, 0, 57, + 58, 54, 528, 55, 741, 0, 0, 541, 183, 531, + 532, 533, 534, 535, 536, 537, 538, 539, 540, 0, + 200, 742, 203, 0, 487, 488, 0, 480, 23, 0, + 523, 524, 471, 472, 273, 347, 349, 351, 0, 260, + 338, 359, 342, 0, 339, 0, 0, 333, 398, 0, + 0, 366, -2, 401, 402, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 477, 0, 455, 0, 0, 415, + 426, 427, 428, 429, 502, 0, 0, -2, 0, 0, + 477, 0, 0, 0, 288, 295, 0, 0, 289, 0, + 290, 310, 312, 0, 0, 0, 0, 286, 477, 323, + 38, 147, 0, 170, 0, 0, 156, 0, 0, 159, + 160, 139, 0, 131, 70, 128, 0, 146, 146, 97, + 0, 98, 99, 100, 0, 116, 0, 0, 0, 0, + 550, 52, 60, 61, 0, 175, 741, 0, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 741, + 0, 0, 741, 542, 543, 544, 545, 0, 202, 491, + 0, 24, 323, 0, 267, 461, 0, 340, 0, 360, + 343, 399, 263, 0, 118, 118, 440, 118, 122, 443, + 118, 445, 118, 448, 0, 0, 0, 0, 460, 0, + 0, 0, 452, 414, 458, 0, 31, 0, 502, 492, + 504, 506, 0, 27, 0, 498, 0, 485, 511, 324, + 512, 292, 0, 297, 0, 0, 0, 300, 0, 485, + 37, 168, 171, 0, 163, 118, 157, 158, 141, 0, + 133, 134, 135, 136, 137, 138, 119, 93, 94, 144, + 145, 143, 0, 143, 0, 123, 0, 742, 0, 0, + 176, 0, 177, 179, 180, 181, 0, 473, 274, 400, + 344, 403, 437, 143, 441, 442, 444, 446, 447, 449, + 405, 404, 406, 0, 0, 409, 0, 0, 0, 0, + 0, 456, 0, 32, 0, 507, -2, 0, 0, 0, + 44, 35, 0, 284, 0, 0, 0, 319, 287, 36, + 549, 0, 165, 148, 142, 0, 146, 117, 146, 0, + 0, 50, 62, 63, 0, 0, 475, 0, 438, 439, + 0, 0, 0, 0, 430, 413, 453, 0, 505, 0, + -2, 0, 500, 499, 0, 293, 320, 321, 322, 283, + 155, 164, 153, 0, 150, 152, 140, 106, 107, 121, + 124, 0, 0, 26, 0, 0, 407, 408, 410, 411, + 0, 0, 0, 0, 495, 27, 0, 285, 69, 0, + 149, 151, 56, 0, 196, 0, 476, 474, 412, 0, + 0, 0, 503, -2, 501, 154, 59, 195, 0, 0, + 431, 0, 434, 178, 197, 0, 432, 0, 0, 0, + 0, 0, 433, 0, 0, 198, 199, } var yyTok1 = [...]int{ @@ -2636,98 +2639,104 @@ yydefault: yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), TableExprs: TableExprs{&AliasedTableExpr{Expr: yyDollar[4].tableName}}, Partitions: yyDollar[5].partitions, Where: NewWhere(WhereStr, yyDollar[6].expr), OrderBy: yyDollar[7].orderBy, Limit: yyDollar[8].limit} } case 37: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] //line sql.y:423 { - yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[3].tableNames, TableExprs: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr)} + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[4].tableNames, TableExprs: yyDollar[6].tableExprs, Where: NewWhere(WhereStr, yyDollar[7].expr)} } case 38: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:428 + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:427 { + yyVAL.statement = &Delete{Comments: Comments(yyDollar[2].bytes2), Targets: yyDollar[3].tableNames, TableExprs: yyDollar[5].tableExprs, Where: NewWhere(WhereStr, yyDollar[6].expr)} } case 39: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:429 + //line sql.y:432 { } case 40: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:433 { - yyVAL.tableNames = TableNames{yyDollar[1].tableName} } case 41: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:437 { - yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) + yyVAL.tableNames = TableNames{yyDollar[1].tableName} } case 42: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:441 + { + yyVAL.tableNames = append(yyVAL.tableNames, yyDollar[3].tableName) + } + case 43: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:442 + //line sql.y:446 { yyVAL.partitions = nil } - case 43: + case 44: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:446 + //line sql.y:450 { yyVAL.partitions = yyDollar[3].partitions } - case 44: + case 45: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:452 + //line sql.y:456 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Exprs: yyDollar[3].setExprs} } - case 45: + case 46: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:456 + //line sql.y:460 { yyVAL.statement = &Set{Comments: Comments(yyDollar[2].bytes2), Scope: yyDollar[3].str, Exprs: yyDollar[4].setExprs} } - case 46: + case 47: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:462 + //line sql.y:466 { yyVAL.str = SessionStr } - case 47: + case 48: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:466 + //line sql.y:470 { yyVAL.str = GlobalStr } - case 48: + case 49: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:472 + //line sql.y:476 { yyDollar[1].ddl.TableSpec = yyDollar[2].TableSpec yyVAL.statement = yyDollar[1].ddl } - case 49: + case 50: yyDollar = yyS[yypt-8 : yypt+1] - //line sql.y:477 + //line sql.y:481 { // Change this to an alter statement yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[7].tableName, NewName: yyDollar[7].tableName} } - case 50: + case 51: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:482 + //line sql.y:486 { yyVAL.statement = &DDL{Action: CreateStr, NewName: yyDollar[3].tableName.ToViewName()} } - case 51: + case 52: yyDollar = yyS[yypt-6 : yypt+1] - //line sql.y:486 + //line sql.y:490 { yyVAL.statement = &DDL{Action: CreateStr, NewName: yyDollar[5].tableName.ToViewName()} } - case 52: + case 53: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:490 + //line sql.y:494 { yyVAL.statement = &DDL{Action: CreateVindexStr, VindexSpec: &VindexSpec{ Name: yyDollar[3].colIdent, @@ -2735,104 +2744,104 @@ yydefault: Params: yyDollar[5].vindexParams, }} } - case 53: + case 54: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:498 + //line sql.y:502 { yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} } - case 54: + case 55: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:502 + //line sql.y:506 { yyVAL.statement = &DBDDL{Action: CreateStr, DBName: string(yyDollar[4].bytes)} } - case 55: + case 56: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:507 + //line sql.y:511 { yyVAL.colIdent = NewColIdent("") } - case 56: + case 57: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:511 + //line sql.y:515 { yyVAL.colIdent = yyDollar[2].colIdent } - case 57: + case 58: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:517 + //line sql.y:521 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 58: + case 59: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:522 + //line sql.y:526 { var v []VindexParam yyVAL.vindexParams = v } - case 59: + case 60: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:527 + //line sql.y:531 { yyVAL.vindexParams = yyDollar[2].vindexParams } - case 60: + case 61: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:533 + //line sql.y:537 { yyVAL.vindexParams = make([]VindexParam, 0, 4) yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[1].vindexParam) } - case 61: + case 62: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:538 + //line sql.y:542 { yyVAL.vindexParams = append(yyVAL.vindexParams, yyDollar[3].vindexParam) } - case 62: + case 63: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:544 + //line sql.y:548 { yyVAL.vindexParam = VindexParam{Key: yyDollar[1].colIdent, Val: yyDollar[3].str} } - case 63: + case 64: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:550 + //line sql.y:554 { yyVAL.ddl = &DDL{Action: CreateStr, NewName: yyDollar[4].tableName} setDDL(yylex, yyVAL.ddl) } - case 64: + case 65: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:557 + //line sql.y:561 { yyVAL.TableSpec = yyDollar[2].TableSpec yyVAL.TableSpec.Options = yyDollar[4].str } - case 65: + case 66: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:564 + //line sql.y:568 { yyVAL.TableSpec = &TableSpec{} yyVAL.TableSpec.AddColumn(yyDollar[1].columnDefinition) } - case 66: + case 67: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:569 + //line sql.y:573 { yyVAL.TableSpec.AddColumn(yyDollar[3].columnDefinition) } - case 67: + case 68: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:573 + //line sql.y:577 { yyVAL.TableSpec.AddIndex(yyDollar[3].indexDefinition) } - case 68: + case 69: yyDollar = yyS[yypt-8 : yypt+1] - //line sql.y:579 + //line sql.y:583 { yyDollar[2].columnType.NotNull = yyDollar[3].boolVal yyDollar[2].columnType.Default = yyDollar[4].optVal @@ -2842,32 +2851,26 @@ yydefault: yyDollar[2].columnType.Comment = yyDollar[8].optVal yyVAL.columnDefinition = &ColumnDefinition{Name: NewColIdent(string(yyDollar[1].bytes)), Type: yyDollar[2].columnType} } - case 69: + case 70: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:590 + //line sql.y:594 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Unsigned = yyDollar[2].boolVal yyVAL.columnType.Zerofill = yyDollar[3].boolVal } - case 73: + case 74: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:601 + //line sql.y:605 { yyVAL.columnType = yyDollar[1].columnType yyVAL.columnType.Length = yyDollar[2].optVal } - case 74: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:606 - { - yyVAL.columnType = yyDollar[1].columnType - } case 75: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:612 + //line sql.y:610 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType = yyDollar[1].columnType } case 76: yyDollar = yyS[yypt-1 : yypt+1] @@ -2906,16 +2909,14 @@ yydefault: yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 82: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:642 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:640 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} - yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 83: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:648 + //line sql.y:646 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -2923,7 +2924,7 @@ yydefault: } case 84: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:654 + //line sql.y:652 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -2931,7 +2932,7 @@ yydefault: } case 85: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:660 + //line sql.y:658 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length @@ -2939,23 +2940,25 @@ yydefault: } case 86: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:666 + //line sql.y:664 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 87: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:674 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:670 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.columnType.Scale = yyDollar[2].LengthScaleOption.Scale } case 88: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:678 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 89: yyDollar = yyS[yypt-2 : yypt+1] @@ -2970,16 +2973,16 @@ yydefault: yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 91: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:690 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 92: - yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:696 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:694 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 93: yyDollar = yyS[yypt-4 : yypt+1] @@ -2988,10 +2991,10 @@ yydefault: yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} } case 94: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:704 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Collate: yyDollar[4].str} } case 95: yyDollar = yyS[yypt-2 : yypt+1] @@ -3000,10 +3003,10 @@ yydefault: yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 96: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:712 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 97: yyDollar = yyS[yypt-3 : yypt+1] @@ -3024,10 +3027,10 @@ yydefault: yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 100: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:728 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), Charset: yyDollar[2].str, Collate: yyDollar[3].str} } case 101: yyDollar = yyS[yypt-1 : yypt+1] @@ -3054,22 +3057,22 @@ yydefault: yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 105: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:748 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} } case 106: yyDollar = yyS[yypt-6 : yypt+1] - //line sql.y:753 + //line sql.y:752 { yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} } case 107: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:759 + yyDollar = yyS[yypt-6 : yypt+1] + //line sql.y:757 { - yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes), EnumValues: yyDollar[3].strs, Charset: yyDollar[5].str, Collate: yyDollar[6].str} } case 108: yyDollar = yyS[yypt-1 : yypt+1] @@ -3115,138 +3118,138 @@ yydefault: } case 115: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:793 + //line sql.y:791 + { + yyVAL.columnType = ColumnType{Type: string(yyDollar[1].bytes)} + } + case 116: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:797 { yyVAL.strs = make([]string, 0, 4) yyVAL.strs = append(yyVAL.strs, "'"+string(yyDollar[1].bytes)+"'") } - case 116: + case 117: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:798 + //line sql.y:802 { yyVAL.strs = append(yyDollar[1].strs, "'"+string(yyDollar[3].bytes)+"'") } - case 117: + case 118: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:803 + //line sql.y:807 { yyVAL.optVal = nil } - case 118: + case 119: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:807 + //line sql.y:811 { yyVAL.optVal = NewIntVal(yyDollar[2].bytes) } - case 119: + case 120: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:812 + //line sql.y:816 { yyVAL.LengthScaleOption = LengthScaleOption{} } - case 120: + case 121: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:816 + //line sql.y:820 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), Scale: NewIntVal(yyDollar[4].bytes), } } - case 121: + case 122: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:824 + //line sql.y:828 { yyVAL.LengthScaleOption = LengthScaleOption{} } - case 122: + case 123: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:828 + //line sql.y:832 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), } } - case 123: + case 124: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:834 + //line sql.y:838 { yyVAL.LengthScaleOption = LengthScaleOption{ Length: NewIntVal(yyDollar[2].bytes), Scale: NewIntVal(yyDollar[4].bytes), } } - case 124: + case 125: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:842 + //line sql.y:846 { yyVAL.boolVal = BoolVal(false) } - case 125: + case 126: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:846 + //line sql.y:850 { yyVAL.boolVal = BoolVal(true) } - case 126: + case 127: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:851 + //line sql.y:855 { yyVAL.boolVal = BoolVal(false) } - case 127: + case 128: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:855 + //line sql.y:859 { yyVAL.boolVal = BoolVal(true) } - case 128: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:861 - { - yyVAL.boolVal = BoolVal(false) - } case 129: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:865 { yyVAL.boolVal = BoolVal(false) } case 130: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:869 { - yyVAL.boolVal = BoolVal(true) + yyVAL.boolVal = BoolVal(false) } case 131: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:874 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:873 { - yyVAL.optVal = nil + yyVAL.boolVal = BoolVal(true) } case 132: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:878 { - yyVAL.optVal = NewStrVal(yyDollar[2].bytes) + yyVAL.optVal = nil } case 133: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:882 { - yyVAL.optVal = NewIntVal(yyDollar[2].bytes) + yyVAL.optVal = NewStrVal(yyDollar[2].bytes) } case 134: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:886 { - yyVAL.optVal = NewFloatVal(yyDollar[2].bytes) + yyVAL.optVal = NewIntVal(yyDollar[2].bytes) } case 135: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:890 { - yyVAL.optVal = NewValArg(yyDollar[2].bytes) + yyVAL.optVal = NewFloatVal(yyDollar[2].bytes) } case 136: yyDollar = yyS[yypt-2 : yypt+1] @@ -3258,145 +3261,145 @@ yydefault: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:898 { - yyVAL.optVal = NewBitVal(yyDollar[2].bytes) + yyVAL.optVal = NewValArg(yyDollar[2].bytes) } case 138: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:902 + { + yyVAL.optVal = NewBitVal(yyDollar[2].bytes) + } + case 139: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:903 + //line sql.y:907 { yyVAL.optVal = nil } - case 139: + case 140: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:907 + //line sql.y:911 { yyVAL.optVal = NewValArg(yyDollar[3].bytes) } - case 140: + case 141: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:912 + //line sql.y:916 { yyVAL.boolVal = BoolVal(false) } - case 141: + case 142: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:916 + //line sql.y:920 { yyVAL.boolVal = BoolVal(true) } - case 142: + case 143: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:921 + //line sql.y:925 { yyVAL.str = "" } - case 143: + case 144: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:925 + //line sql.y:929 { yyVAL.str = string(yyDollar[3].bytes) } - case 144: + case 145: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:929 + //line sql.y:933 { yyVAL.str = string(yyDollar[3].bytes) } - case 145: + case 146: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:934 + //line sql.y:938 { yyVAL.str = "" } - case 146: + case 147: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:938 + //line sql.y:942 { yyVAL.str = string(yyDollar[2].bytes) } - case 147: + case 148: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:943 + //line sql.y:947 { yyVAL.colKeyOpt = colKeyNone } - case 148: + case 149: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:947 + //line sql.y:951 { yyVAL.colKeyOpt = colKeyPrimary } - case 149: + case 150: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:951 + //line sql.y:955 { yyVAL.colKeyOpt = colKey } - case 150: + case 151: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:955 + //line sql.y:959 { yyVAL.colKeyOpt = colKeyUniqueKey } - case 151: + case 152: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:959 + //line sql.y:963 { yyVAL.colKeyOpt = colKeyUnique } - case 152: + case 153: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:964 + //line sql.y:968 { yyVAL.optVal = nil } - case 153: + case 154: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:968 + //line sql.y:972 { yyVAL.optVal = NewStrVal(yyDollar[2].bytes) } - case 154: + case 155: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:974 + //line sql.y:978 { yyVAL.indexDefinition = &IndexDefinition{Info: yyDollar[1].indexInfo, Columns: yyDollar[3].indexColumns, Using: yyDollar[5].colIdent} } - case 155: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:980 - { - yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} - } case 156: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:984 { - yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Spatial: true, Unique: false} + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].bytes), Name: NewColIdent("PRIMARY"), Primary: true, Unique: true} } case 157: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:988 { - yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Unique: true} + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Spatial: true, Unique: false} } case 158: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:992 { - yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: true} + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes) + " " + string(yyDollar[2].str), Name: NewColIdent(string(yyDollar[3].bytes)), Unique: true} } case 159: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:996 { - yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: false} + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].bytes), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: true} } case 160: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1002 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1000 { - yyVAL.str = string(yyDollar[1].bytes) + yyVAL.indexInfo = &IndexInfo{Type: string(yyDollar[1].str), Name: NewColIdent(string(yyDollar[2].bytes)), Unique: false} } case 161: yyDollar = yyS[yypt-1 : yypt+1] @@ -3406,84 +3409,84 @@ yydefault: } case 162: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1012 + //line sql.y:1010 { - yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn} + yyVAL.str = string(yyDollar[1].bytes) } case 163: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1016 { - yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn) + yyVAL.indexColumns = []*IndexColumn{yyDollar[1].indexColumn} } case 164: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1020 + { + yyVAL.indexColumns = append(yyVAL.indexColumns, yyDollar[3].indexColumn) + } + case 165: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1022 + //line sql.y:1026 { yyVAL.indexColumn = &IndexColumn{Column: yyDollar[1].colIdent, Length: yyDollar[2].optVal} } - case 165: + case 166: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1027 + //line sql.y:1031 { yyVAL.str = "" } - case 166: + case 167: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1031 + //line sql.y:1035 { yyVAL.str = " " + string(yyDollar[1].str) } - case 167: + case 168: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1035 + //line sql.y:1039 { yyVAL.str = string(yyDollar[1].str) + ", " + string(yyDollar[3].str) } - case 168: + case 169: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1043 + //line sql.y:1047 { yyVAL.str = yyDollar[1].str } - case 169: + case 170: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1047 + //line sql.y:1051 { yyVAL.str = yyDollar[1].str + " " + yyDollar[2].str } - case 170: + case 171: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1051 + //line sql.y:1055 { yyVAL.str = yyDollar[1].str + "=" + yyDollar[3].str } - case 171: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1057 - { - yyVAL.str = yyDollar[1].colIdent.String() - } case 172: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1061 { - yyVAL.str = "'" + string(yyDollar[1].bytes) + "'" + yyVAL.str = yyDollar[1].colIdent.String() } case 173: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1065 { - yyVAL.str = string(yyDollar[1].bytes) + yyVAL.str = "'" + string(yyDollar[1].bytes) + "'" } case 174: - yyDollar = yyS[yypt-6 : yypt+1] - //line sql.y:1071 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1069 { - yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + yyVAL.str = string(yyDollar[1].bytes) } case 175: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] //line sql.y:1075 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} @@ -3495,8 +3498,14 @@ yydefault: yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} } case 177: - yyDollar = yyS[yypt-12 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] //line sql.y:1083 + { + yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} + } + case 178: + yyDollar = yyS[yypt-12 : yypt+1] + //line sql.y:1087 { yyVAL.statement = &DDL{ Action: AddColVindexStr, @@ -3509,9 +3518,9 @@ yydefault: VindexCols: yyDollar[9].columns, } } - case 178: + case 179: yyDollar = yyS[yypt-7 : yypt+1] - //line sql.y:1096 + //line sql.y:1100 { yyVAL.statement = &DDL{ Action: DropColVindexStr, @@ -3521,71 +3530,71 @@ yydefault: }, } } - case 179: + case 180: yyDollar = yyS[yypt-7 : yypt+1] - //line sql.y:1106 + //line sql.y:1110 { // Change this to a rename statement yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[4].tableName, NewName: yyDollar[7].tableName} } - case 180: + case 181: yyDollar = yyS[yypt-7 : yypt+1] - //line sql.y:1111 + //line sql.y:1115 { // Rename an index can just be an alter yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, NewName: yyDollar[4].tableName} } - case 181: + case 182: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1116 + //line sql.y:1120 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName.ToViewName(), NewName: yyDollar[3].tableName.ToViewName()} } - case 182: + case 183: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1120 + //line sql.y:1124 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[4].tableName, PartitionSpec: yyDollar[5].partSpec} } - case 194: + case 195: yyDollar = yyS[yypt-7 : yypt+1] - //line sql.y:1139 + //line sql.y:1143 { yyVAL.partSpec = &PartitionSpec{Action: ReorganizeStr, Name: yyDollar[3].colIdent, Definitions: yyDollar[6].partDefs} } - case 195: + case 196: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1145 + //line sql.y:1149 { yyVAL.partDefs = []*PartitionDefinition{yyDollar[1].partDef} } - case 196: + case 197: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1149 + //line sql.y:1153 { yyVAL.partDefs = append(yyDollar[1].partDefs, yyDollar[3].partDef) } - case 197: + case 198: yyDollar = yyS[yypt-8 : yypt+1] - //line sql.y:1155 + //line sql.y:1159 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].expr} } - case 198: + case 199: yyDollar = yyS[yypt-8 : yypt+1] - //line sql.y:1159 + //line sql.y:1163 { yyVAL.partDef = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} } - case 199: + case 200: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1165 + //line sql.y:1169 { yyVAL.statement = &DDL{Action: RenameStr, Table: yyDollar[3].tableName, NewName: yyDollar[5].tableName} } - case 200: + case 201: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1171 + //line sql.y:1175 { var exists bool if yyDollar[3].byt != 0 { @@ -3593,16 +3602,16 @@ yydefault: } yyVAL.statement = &DDL{Action: DropStr, Table: yyDollar[4].tableName, IfExists: exists} } - case 201: + case 202: yyDollar = yyS[yypt-6 : yypt+1] - //line sql.y:1179 + //line sql.y:1183 { // Change this to an alter statement yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[5].tableName, NewName: yyDollar[5].tableName} } - case 202: + case 203: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1184 + //line sql.y:1188 { var exists bool if yyDollar[3].byt != 0 { @@ -3610,42 +3619,36 @@ yydefault: } yyVAL.statement = &DDL{Action: DropStr, Table: yyDollar[4].tableName.ToViewName(), IfExists: exists} } - case 203: + case 204: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1192 + //line sql.y:1196 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } - case 204: + case 205: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1196 + //line sql.y:1200 { yyVAL.statement = &DBDDL{Action: DropStr, DBName: string(yyDollar[4].bytes)} } - case 205: + case 206: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1202 + //line sql.y:1206 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[3].tableName} } - case 206: + case 207: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1206 + //line sql.y:1210 { yyVAL.statement = &DDL{Action: TruncateStr, Table: yyDollar[2].tableName} } - case 207: + case 208: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1211 + //line sql.y:1215 { yyVAL.statement = &DDL{Action: AlterStr, Table: yyDollar[3].tableName, NewName: yyDollar[3].tableName} } - case 208: - yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1217 - { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} - } case 209: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1221 @@ -3660,7 +3663,7 @@ yydefault: } case 211: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1230 + //line sql.y:1229 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } @@ -3689,10 +3692,10 @@ yydefault: yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 216: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1250 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes) + " " + string(yyDollar[3].bytes)} } case 217: yyDollar = yyS[yypt-3 : yypt+1] @@ -3713,16 +3716,16 @@ yydefault: yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 220: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1266 { - yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 221: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1270 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } case 222: yyDollar = yyS[yypt-3 : yypt+1] @@ -3731,28 +3734,28 @@ yydefault: yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 223: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1278 { - yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 224: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1282 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + yyVAL.statement = &Show{Scope: yyDollar[2].str, Type: string(yyDollar[3].bytes)} } case 225: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1286 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), OnTable: yyDollar[4].tableName} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 226: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1290 { - yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes), OnTable: yyDollar[4].tableName} } case 227: yyDollar = yyS[yypt-2 : yypt+1] @@ -3773,70 +3776,70 @@ yydefault: yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 230: - yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1312 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1306 { yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 231: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1318 + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1316 { - yyVAL.str = "" + yyVAL.statement = &Show{Type: string(yyDollar[2].bytes)} } case 232: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:1322 { - yyVAL.str = SessionStr + yyVAL.str = "" } case 233: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1326 { - yyVAL.str = GlobalStr + yyVAL.str = SessionStr } case 234: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1332 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1330 { - yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} + yyVAL.str = GlobalStr } case 235: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1336 { - yyVAL.statement = &Use{DBName: TableIdent{v: ""}} + yyVAL.statement = &Use{DBName: yyDollar[2].tableIdent} } case 236: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1342 + //line sql.y:1340 { - yyVAL.statement = &Begin{} + yyVAL.statement = &Use{DBName: TableIdent{v: ""}} } case 237: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1346 { yyVAL.statement = &Begin{} } case 238: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1352 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1350 { - yyVAL.statement = &Commit{} + yyVAL.statement = &Begin{} } case 239: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1358 + //line sql.y:1356 { - yyVAL.statement = &Rollback{} + yyVAL.statement = &Commit{} } case 240: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1364 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1362 { - yyVAL.statement = &OtherRead{} + yyVAL.statement = &Rollback{} } case 241: yyDollar = yyS[yypt-2 : yypt+1] @@ -3854,7 +3857,7 @@ yydefault: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1376 { - yyVAL.statement = &OtherAdmin{} + yyVAL.statement = &OtherRead{} } case 244: yyDollar = yyS[yypt-2 : yypt+1] @@ -3863,246 +3866,246 @@ yydefault: yyVAL.statement = &OtherAdmin{} } case 245: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1384 + { + yyVAL.statement = &OtherAdmin{} + } + case 246: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1385 + //line sql.y:1389 { setAllowComments(yylex, true) } - case 246: + case 247: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1389 + //line sql.y:1393 { yyVAL.bytes2 = yyDollar[2].bytes2 setAllowComments(yylex, false) } - case 247: + case 248: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1395 + //line sql.y:1399 { yyVAL.bytes2 = nil } - case 248: + case 249: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1399 + //line sql.y:1403 { yyVAL.bytes2 = append(yyDollar[1].bytes2, yyDollar[2].bytes) } - case 249: + case 250: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1405 + //line sql.y:1409 { yyVAL.str = UnionStr } - case 250: + case 251: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1409 + //line sql.y:1413 { yyVAL.str = UnionAllStr } - case 251: + case 252: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1413 + //line sql.y:1417 { yyVAL.str = UnionDistinctStr } - case 252: + case 253: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1418 + //line sql.y:1422 { yyVAL.str = "" } - case 253: + case 254: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1422 + //line sql.y:1426 { yyVAL.str = SQLNoCacheStr } - case 254: + case 255: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1426 + //line sql.y:1430 { yyVAL.str = SQLCacheStr } - case 255: + case 256: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1431 + //line sql.y:1435 { yyVAL.str = "" } - case 256: + case 257: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1435 + //line sql.y:1439 { yyVAL.str = DistinctStr } - case 257: + case 258: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1440 + //line sql.y:1444 { yyVAL.str = "" } - case 258: + case 259: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1444 + //line sql.y:1448 { yyVAL.str = StraightJoinHint } - case 259: + case 260: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1449 + //line sql.y:1453 { yyVAL.selectExprs = nil } - case 260: + case 261: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1453 + //line sql.y:1457 { yyVAL.selectExprs = yyDollar[1].selectExprs } - case 261: + case 262: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1459 + //line sql.y:1463 { yyVAL.selectExprs = SelectExprs{yyDollar[1].selectExpr} } - case 262: + case 263: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1463 + //line sql.y:1467 { yyVAL.selectExprs = append(yyVAL.selectExprs, yyDollar[3].selectExpr) } - case 263: + case 264: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1469 + //line sql.y:1473 { yyVAL.selectExpr = &StarExpr{} } - case 264: + case 265: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1473 + //line sql.y:1477 { yyVAL.selectExpr = &AliasedExpr{Expr: yyDollar[1].expr, As: yyDollar[2].colIdent} } - case 265: + case 266: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1477 + //line sql.y:1481 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} } - case 266: + case 267: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1481 + //line sql.y:1485 { yyVAL.selectExpr = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} } - case 267: + case 268: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1486 + //line sql.y:1490 { yyVAL.colIdent = ColIdent{} } - case 268: + case 269: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1490 + //line sql.y:1494 { yyVAL.colIdent = yyDollar[1].colIdent } - case 269: + case 270: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1494 + //line sql.y:1498 { yyVAL.colIdent = yyDollar[2].colIdent } - case 271: + case 272: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1501 + //line sql.y:1505 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 272: + case 273: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1506 + //line sql.y:1510 { yyVAL.tableExprs = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} } - case 273: + case 274: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1510 + //line sql.y:1514 { yyVAL.tableExprs = yyDollar[2].tableExprs } - case 274: + case 275: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1516 + //line sql.y:1520 { yyVAL.tableExprs = TableExprs{yyDollar[1].tableExpr} } - case 275: + case 276: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1520 + //line sql.y:1524 { yyVAL.tableExprs = append(yyVAL.tableExprs, yyDollar[3].tableExpr) } - case 278: + case 279: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1530 + //line sql.y:1534 { yyVAL.tableExpr = yyDollar[1].aliasedTableName } - case 279: + case 280: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1534 + //line sql.y:1538 { yyVAL.tableExpr = &AliasedTableExpr{Expr: yyDollar[1].subquery, As: yyDollar[3].tableIdent} } - case 280: + case 281: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1538 + //line sql.y:1542 { yyVAL.tableExpr = &ParenTableExpr{Exprs: yyDollar[2].tableExprs} } - case 281: + case 282: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1544 + //line sql.y:1548 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHints} } - case 282: + case 283: yyDollar = yyS[yypt-7 : yypt+1] - //line sql.y:1548 + //line sql.y:1552 { yyVAL.aliasedTableName = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitions, As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHints} } - case 283: + case 284: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1554 + //line sql.y:1558 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 284: + case 285: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1558 + //line sql.y:1562 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 285: + case 286: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1564 + //line sql.y:1568 { yyVAL.partitions = Partitions{yyDollar[1].colIdent} } - case 286: + case 287: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1568 + //line sql.y:1572 { yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) } - case 287: - yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1581 - { - yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} - } case 288: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1585 @@ -4116,91 +4119,91 @@ yydefault: yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 290: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1593 { - yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } case 291: + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1597 + { + yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].str, RightExpr: yyDollar[3].tableExpr} + } + case 292: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1599 + //line sql.y:1603 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 292: + case 293: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:1601 + //line sql.y:1605 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} } - case 293: + case 294: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1605 + //line sql.y:1609 { yyVAL.joinCondition = JoinCondition{} } - case 294: + case 295: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1607 + //line sql.y:1611 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 295: + case 296: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1611 + //line sql.y:1615 { yyVAL.joinCondition = JoinCondition{} } - case 296: + case 297: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1613 + //line sql.y:1617 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 297: + case 298: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1616 + //line sql.y:1620 { yyVAL.empty = struct{}{} } - case 298: + case 299: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1618 + //line sql.y:1622 { yyVAL.empty = struct{}{} } - case 299: + case 300: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1621 + //line sql.y:1625 { yyVAL.tableIdent = NewTableIdent("") } - case 300: + case 301: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1625 + //line sql.y:1629 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 301: + case 302: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1629 + //line sql.y:1633 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 303: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1636 - { - yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) - } case 304: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1642 + //line sql.y:1640 { - yyVAL.str = JoinStr + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } case 305: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1646 { yyVAL.str = JoinStr @@ -4212,44 +4215,50 @@ yydefault: yyVAL.str = JoinStr } case 307: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1656 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1654 { - yyVAL.str = StraightJoinStr + yyVAL.str = JoinStr } case 308: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1662 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1660 { - yyVAL.str = LeftJoinStr + yyVAL.str = StraightJoinStr } case 309: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1666 { yyVAL.str = LeftJoinStr } case 310: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1670 { - yyVAL.str = RightJoinStr + yyVAL.str = LeftJoinStr } case 311: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1674 { yyVAL.str = RightJoinStr } case 312: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1680 + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:1678 { - yyVAL.str = NaturalJoinStr + yyVAL.str = RightJoinStr } case 313: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1684 + { + yyVAL.str = NaturalJoinStr + } + case 314: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1688 { if yyDollar[2].str == LeftJoinStr { yyVAL.str = NaturalLeftJoinStr @@ -4257,401 +4266,395 @@ yydefault: yyVAL.str = NaturalRightJoinStr } } - case 314: + case 315: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1694 + //line sql.y:1698 { yyVAL.tableName = yyDollar[2].tableName } - case 315: + case 316: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1698 + //line sql.y:1702 { yyVAL.tableName = yyDollar[1].tableName } - case 316: + case 317: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1704 + //line sql.y:1708 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 317: + case 318: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1708 + //line sql.y:1712 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } - case 318: + case 319: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1713 + //line sql.y:1717 { yyVAL.indexHints = nil } - case 319: + case 320: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1717 + //line sql.y:1721 { yyVAL.indexHints = &IndexHints{Type: UseStr, Indexes: yyDollar[4].columns} } - case 320: + case 321: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1721 + //line sql.y:1725 { yyVAL.indexHints = &IndexHints{Type: IgnoreStr, Indexes: yyDollar[4].columns} } - case 321: + case 322: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:1725 + //line sql.y:1729 { yyVAL.indexHints = &IndexHints{Type: ForceStr, Indexes: yyDollar[4].columns} } - case 322: + case 323: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1730 + //line sql.y:1734 { yyVAL.expr = nil } - case 323: + case 324: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1734 + //line sql.y:1738 { yyVAL.expr = yyDollar[2].expr } - case 324: + case 325: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1740 + //line sql.y:1744 { yyVAL.expr = yyDollar[1].expr } - case 325: + case 326: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1744 + //line sql.y:1748 { yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 326: + case 327: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1748 + //line sql.y:1752 { yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 327: + case 328: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1752 + //line sql.y:1756 { yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} } - case 328: + case 329: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1756 + //line sql.y:1760 { yyVAL.expr = &IsExpr{Operator: yyDollar[3].str, Expr: yyDollar[1].expr} } - case 329: + case 330: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1760 + //line sql.y:1764 { yyVAL.expr = yyDollar[1].expr } - case 330: + case 331: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1764 + //line sql.y:1768 { yyVAL.expr = &Default{ColName: yyDollar[2].str} } - case 331: + case 332: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1770 + //line sql.y:1774 { yyVAL.str = "" } - case 332: + case 333: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1774 + //line sql.y:1778 { yyVAL.str = string(yyDollar[2].bytes) } - case 333: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1780 - { - yyVAL.boolVal = BoolVal(true) - } case 334: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1784 { - yyVAL.boolVal = BoolVal(false) + yyVAL.boolVal = BoolVal(true) } case 335: - yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1790 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1788 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} + yyVAL.boolVal = BoolVal(false) } case 336: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1794 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].str, Right: yyDollar[3].expr} } case 337: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1798 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InStr, Right: yyDollar[3].colTuple} } case 338: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1802 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInStr, Right: yyDollar[4].colTuple} } case 339: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1806 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeStr, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} } case 340: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] //line sql.y:1810 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeStr, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} } case 341: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1814 { - yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpStr, Right: yyDollar[3].expr} } case 342: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:1818 { - yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} + yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpStr, Right: yyDollar[4].expr} } case 343: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] //line sql.y:1822 { - yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} + yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenStr, From: yyDollar[3].expr, To: yyDollar[5].expr} } case 344: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] //line sql.y:1826 { - yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} + yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenStr, From: yyDollar[4].expr, To: yyDollar[6].expr} } case 345: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1832 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1830 { - yyVAL.str = IsNullStr + yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} } case 346: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1836 { - yyVAL.str = IsNotNullStr + yyVAL.str = IsNullStr } case 347: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1840 { - yyVAL.str = IsTrueStr + yyVAL.str = IsNotNullStr } case 348: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1844 { - yyVAL.str = IsNotTrueStr + yyVAL.str = IsTrueStr } case 349: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1848 { - yyVAL.str = IsFalseStr + yyVAL.str = IsNotTrueStr } case 350: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1852 { - yyVAL.str = IsNotFalseStr + yyVAL.str = IsFalseStr } case 351: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1858 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:1856 { - yyVAL.str = EqualStr + yyVAL.str = IsNotFalseStr } case 352: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1862 { - yyVAL.str = LessThanStr + yyVAL.str = EqualStr } case 353: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1866 { - yyVAL.str = GreaterThanStr + yyVAL.str = LessThanStr } case 354: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1870 { - yyVAL.str = LessEqualStr + yyVAL.str = GreaterThanStr } case 355: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1874 { - yyVAL.str = GreaterEqualStr + yyVAL.str = LessEqualStr } case 356: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1878 { - yyVAL.str = NotEqualStr + yyVAL.str = GreaterEqualStr } case 357: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1882 { - yyVAL.str = NullSafeEqualStr + yyVAL.str = NotEqualStr } case 358: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:1886 + { + yyVAL.str = NullSafeEqualStr + } + case 359: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:1887 + //line sql.y:1891 { yyVAL.expr = nil } - case 359: + case 360: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:1891 + //line sql.y:1895 { yyVAL.expr = yyDollar[2].expr } - case 360: + case 361: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1897 + //line sql.y:1901 { yyVAL.colTuple = yyDollar[1].valTuple } - case 361: + case 362: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1901 + //line sql.y:1905 { yyVAL.colTuple = yyDollar[1].subquery } - case 362: + case 363: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1905 + //line sql.y:1909 { yyVAL.colTuple = ListArg(yyDollar[1].bytes) } - case 363: + case 364: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1911 + //line sql.y:1915 { yyVAL.subquery = &Subquery{yyDollar[2].selStmt} } - case 364: + case 365: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1917 + //line sql.y:1921 { yyVAL.exprs = Exprs{yyDollar[1].expr} } - case 365: + case 366: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:1921 + //line sql.y:1925 { yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) } - case 366: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:1927 - { - yyVAL.expr = yyDollar[1].expr - } case 367: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1931 { - yyVAL.expr = yyDollar[1].boolVal + yyVAL.expr = yyDollar[1].expr } case 368: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1935 { - yyVAL.expr = yyDollar[1].colName + yyVAL.expr = yyDollar[1].boolVal } case 369: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1939 { - yyVAL.expr = yyDollar[1].expr + yyVAL.expr = yyDollar[1].colName } case 370: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1943 { - yyVAL.expr = yyDollar[1].subquery + yyVAL.expr = yyDollar[1].expr } case 371: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1947 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} + yyVAL.expr = yyDollar[1].subquery } case 372: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1951 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndStr, Right: yyDollar[3].expr} } case 373: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1955 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrStr, Right: yyDollar[3].expr} } case 374: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1959 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorStr, Right: yyDollar[3].expr} } case 375: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1963 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusStr, Right: yyDollar[3].expr} } case 376: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1967 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusStr, Right: yyDollar[3].expr} } case 377: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1971 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultStr, Right: yyDollar[3].expr} } case 378: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1975 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivStr, Right: yyDollar[3].expr} } case 379: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1979 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivStr, Right: yyDollar[3].expr} } case 380: yyDollar = yyS[yypt-3 : yypt+1] @@ -4663,47 +4666,53 @@ yydefault: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1987 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModStr, Right: yyDollar[3].expr} } case 382: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1991 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftStr, Right: yyDollar[3].expr} } case 383: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1995 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightStr, Right: yyDollar[3].expr} } case 384: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:1999 { - yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} } case 385: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2003 { - yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} + yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} } case 386: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2007 { - yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} + yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} } case 387: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2011 { - yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} + yyVAL.expr = &UnaryExpr{Operator: BinaryStr, Expr: yyDollar[2].expr} } case 388: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2015 + { + yyVAL.expr = &UnaryExpr{Operator: UBinaryStr, Expr: yyDollar[2].expr} + } + case 389: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2019 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { yyVAL.expr = num @@ -4711,9 +4720,9 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UPlusStr, Expr: yyDollar[2].expr} } } - case 389: + case 390: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2023 + //line sql.y:2027 { if num, ok := yyDollar[2].expr.(*SQLVal); ok && num.Type == IntVal { // Handle double negative @@ -4727,21 +4736,21 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UMinusStr, Expr: yyDollar[2].expr} } } - case 390: + case 391: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2037 + //line sql.y:2041 { yyVAL.expr = &UnaryExpr{Operator: TildaStr, Expr: yyDollar[2].expr} } - case 391: + case 392: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2041 + //line sql.y:2045 { yyVAL.expr = &UnaryExpr{Operator: BangStr, Expr: yyDollar[2].expr} } - case 392: + case 393: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2045 + //line sql.y:2049 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -4749,41 +4758,35 @@ yydefault: // will be non-trivial because of grammar conflicts. yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()} } - case 397: + case 398: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2063 + //line sql.y:2067 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} } - case 398: + case 399: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:2067 + //line sql.y:2071 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } - case 399: + case 400: yyDollar = yyS[yypt-6 : yypt+1] - //line sql.y:2071 + //line sql.y:2075 { yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} } - case 400: - yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2081 - { - yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} - } case 401: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:2085 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} } case 402: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:2089 { - yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} + yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} } case 403: yyDollar = yyS[yypt-6 : yypt+1] @@ -4795,19 +4798,19 @@ yydefault: yyDollar = yyS[yypt-6 : yypt+1] //line sql.y:2097 { - yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} + yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } case 405: yyDollar = yyS[yypt-6 : yypt+1] //line sql.y:2101 { - yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} + yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} } case 406: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] //line sql.y:2105 { - yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} } case 407: yyDollar = yyS[yypt-8 : yypt+1] @@ -4816,16 +4819,16 @@ yydefault: yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 408: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] //line sql.y:2113 { - yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 409: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] //line sql.y:2117 { - yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: nil} } case 410: yyDollar = yyS[yypt-8 : yypt+1] @@ -4834,136 +4837,136 @@ yydefault: yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 411: - yyDollar = yyS[yypt-9 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] //line sql.y:2125 { - yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} + yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } case 412: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] //line sql.y:2129 { - yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} + yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].str} } case 413: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] //line sql.y:2133 { - yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} + yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].str, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str} } case 414: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] //line sql.y:2137 { - yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colIdent} + yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} } case 415: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2147 + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2141 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} + yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colIdent} } case 416: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2151 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } case 417: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2155 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } case 418: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2159 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } case 419: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2164 + //line sql.y:2163 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } case 420: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2169 + //line sql.y:2168 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } case 421: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2174 + //line sql.y:2173 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } case 422: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2179 + //line sql.y:2178 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } - case 425: - yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2193 + case 423: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2183 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } case 426: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:2197 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } case 427: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:2201 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } case 428: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:2205 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } case 429: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2211 + yyDollar = yyS[yypt-4 : yypt+1] + //line sql.y:2209 { - yyVAL.str = "" + yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } case 430: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:2215 { - yyVAL.str = BooleanModeStr + yyVAL.str = "" } case 431: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2219 { - yyVAL.str = NaturalLanguageModeStr + yyVAL.str = BooleanModeStr } case 432: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:2223 { - yyVAL.str = NaturalLanguageModeWithQueryExpansionStr + yyVAL.str = NaturalLanguageModeStr } case 433: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] //line sql.y:2227 { - yyVAL.str = QueryExpansionStr + yyVAL.str = NaturalLanguageModeWithQueryExpansionStr } case 434: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2233 + yyDollar = yyS[yypt-3 : yypt+1] + //line sql.y:2231 { - yyVAL.str = string(yyDollar[1].bytes) + yyVAL.str = QueryExpansionStr } case 435: yyDollar = yyS[yypt-1 : yypt+1] @@ -4972,63 +4975,63 @@ yydefault: yyVAL.str = string(yyDollar[1].bytes) } case 436: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2243 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2241 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + yyVAL.str = string(yyDollar[1].bytes) } case 437: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2247 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 438: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2251 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: string(yyDollar[3].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: yyDollar[3].str, Operator: CharacterSetStr} } case 439: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2255 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal, Charset: string(yyDollar[3].bytes)} } case 440: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2259 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 441: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2263 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} - yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 442: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2269 + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2267 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale } case 443: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2273 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 444: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2277 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 445: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2281 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} @@ -5037,143 +5040,149 @@ yydefault: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2285 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 447: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2289 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].optVal} } case 448: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2293 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 449: + yyDollar = yyS[yypt-2 : yypt+1] + //line sql.y:2297 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 450: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2298 + //line sql.y:2302 { yyVAL.expr = nil } - case 450: + case 451: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2302 + //line sql.y:2306 { yyVAL.expr = yyDollar[1].expr } - case 451: + case 452: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2307 + //line sql.y:2311 { yyVAL.str = string("") } - case 452: + case 453: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2311 + //line sql.y:2315 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } - case 453: + case 454: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2317 + //line sql.y:2321 { yyVAL.whens = []*When{yyDollar[1].when} } - case 454: + case 455: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2321 + //line sql.y:2325 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } - case 455: + case 456: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2327 + //line sql.y:2331 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } - case 456: + case 457: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2332 + //line sql.y:2336 { yyVAL.expr = nil } - case 457: + case 458: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2336 + //line sql.y:2340 { yyVAL.expr = yyDollar[2].expr } - case 458: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2342 - { - yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} - } case 459: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2346 { - yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} + yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } case 460: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:2350 { - yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} + yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } case 461: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2356 + yyDollar = yyS[yypt-5 : yypt+1] + //line sql.y:2354 { - yyVAL.expr = NewStrVal(yyDollar[1].bytes) + yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } case 462: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2360 { - yyVAL.expr = NewHexVal(yyDollar[1].bytes) + yyVAL.expr = NewStrVal(yyDollar[1].bytes) } case 463: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2364 { - yyVAL.expr = NewBitVal(yyDollar[1].bytes) + yyVAL.expr = NewHexVal(yyDollar[1].bytes) } case 464: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2368 { - yyVAL.expr = NewIntVal(yyDollar[1].bytes) + yyVAL.expr = NewBitVal(yyDollar[1].bytes) } case 465: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2372 { - yyVAL.expr = NewFloatVal(yyDollar[1].bytes) + yyVAL.expr = NewIntVal(yyDollar[1].bytes) } case 466: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2376 { - yyVAL.expr = NewHexNum(yyDollar[1].bytes) + yyVAL.expr = NewFloatVal(yyDollar[1].bytes) } case 467: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2380 { - yyVAL.expr = NewValArg(yyDollar[1].bytes) + yyVAL.expr = NewHexNum(yyDollar[1].bytes) } case 468: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2384 { - yyVAL.expr = &NullVal{} + yyVAL.expr = NewValArg(yyDollar[1].bytes) } case 469: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2390 + //line sql.y:2388 + { + yyVAL.expr = &NullVal{} + } + case 470: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2394 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -5182,239 +5191,239 @@ yydefault: } yyVAL.expr = NewIntVal([]byte("1")) } - case 470: + case 471: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2399 + //line sql.y:2403 { yyVAL.expr = NewIntVal(yyDollar[1].bytes) } - case 471: + case 472: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2403 + //line sql.y:2407 { yyVAL.expr = NewValArg(yyDollar[1].bytes) } - case 472: + case 473: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2408 + //line sql.y:2412 { yyVAL.exprs = nil } - case 473: + case 474: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2412 + //line sql.y:2416 { yyVAL.exprs = yyDollar[3].exprs } - case 474: + case 475: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2417 + //line sql.y:2421 { yyVAL.expr = nil } - case 475: + case 476: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2421 + //line sql.y:2425 { yyVAL.expr = yyDollar[2].expr } - case 476: + case 477: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2426 + //line sql.y:2430 { yyVAL.orderBy = nil } - case 477: + case 478: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2430 + //line sql.y:2434 { yyVAL.orderBy = yyDollar[3].orderBy } - case 478: + case 479: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2436 + //line sql.y:2440 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } - case 479: + case 480: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2440 + //line sql.y:2444 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } - case 480: + case 481: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2446 + //line sql.y:2450 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].str} } - case 481: + case 482: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2451 + //line sql.y:2455 { yyVAL.str = AscScr } - case 482: + case 483: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2455 + //line sql.y:2459 { yyVAL.str = AscScr } - case 483: + case 484: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2459 + //line sql.y:2463 { yyVAL.str = DescScr } - case 484: + case 485: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2464 + //line sql.y:2468 { yyVAL.limit = nil } - case 485: + case 486: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2468 + //line sql.y:2472 { yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } - case 486: + case 487: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2472 + //line sql.y:2476 { yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } - case 487: + case 488: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2476 + //line sql.y:2480 { yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } - case 488: + case 489: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2481 + //line sql.y:2485 { yyVAL.str = "" } - case 489: + case 490: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2485 + //line sql.y:2489 { yyVAL.str = ForUpdateStr } - case 490: + case 491: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2489 + //line sql.y:2493 { yyVAL.str = ShareModeStr } - case 491: + case 492: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2502 + //line sql.y:2506 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } - case 492: + case 493: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2506 + //line sql.y:2510 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } - case 493: + case 494: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2510 + //line sql.y:2514 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Rows: yyDollar[2].selStmt} } - case 494: + case 495: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:2515 + //line sql.y:2519 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } - case 495: + case 496: yyDollar = yyS[yypt-4 : yypt+1] - //line sql.y:2519 + //line sql.y:2523 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } - case 496: + case 497: yyDollar = yyS[yypt-6 : yypt+1] - //line sql.y:2523 + //line sql.y:2527 { // Drop the redundant parenthesis. yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].selStmt} } - case 497: + case 498: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2530 + //line sql.y:2534 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 498: + case 499: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2534 + //line sql.y:2538 { yyVAL.columns = Columns{yyDollar[3].colIdent} } - case 499: + case 500: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2538 + //line sql.y:2542 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 500: + case 501: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:2542 + //line sql.y:2546 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } - case 501: + case 502: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2547 + //line sql.y:2551 { yyVAL.updateExprs = nil } - case 502: + case 503: yyDollar = yyS[yypt-5 : yypt+1] - //line sql.y:2551 + //line sql.y:2555 { yyVAL.updateExprs = yyDollar[5].updateExprs } - case 503: + case 504: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2557 + //line sql.y:2561 { yyVAL.values = Values{yyDollar[1].valTuple} } - case 504: + case 505: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2561 + //line sql.y:2565 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } - case 505: + case 506: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2567 + //line sql.y:2571 { yyVAL.valTuple = yyDollar[1].valTuple } - case 506: + case 507: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2571 + //line sql.y:2575 { yyVAL.valTuple = ValTuple{} } - case 507: + case 508: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2577 + //line sql.y:2581 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } - case 508: + case 509: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2583 + //line sql.y:2587 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = &ParenExpr{yyDollar[1].valTuple[0]} @@ -5422,183 +5431,177 @@ yydefault: yyVAL.expr = yyDollar[1].valTuple } } - case 509: + case 510: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2593 + //line sql.y:2597 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } - case 510: + case 511: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2597 + //line sql.y:2601 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } - case 511: + case 512: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2603 + //line sql.y:2607 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } - case 512: + case 513: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2609 + //line sql.y:2613 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } - case 513: + case 514: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2613 + //line sql.y:2617 { yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } - case 514: + case 515: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2619 + //line sql.y:2623 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Expr: yyDollar[3].expr} } - case 515: + case 516: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2623 + //line sql.y:2627 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Expr: yyDollar[2].expr} } - case 517: + case 518: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2630 + //line sql.y:2634 { yyVAL.bytes = []byte("charset") } - case 519: + case 520: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2637 + //line sql.y:2641 { yyVAL.expr = NewStrVal([]byte(yyDollar[1].colIdent.String())) } - case 520: + case 521: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2641 + //line sql.y:2645 { yyVAL.expr = NewStrVal(yyDollar[1].bytes) } - case 521: + case 522: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2645 + //line sql.y:2649 { yyVAL.expr = &Default{} } - case 524: + case 525: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2654 + //line sql.y:2658 { yyVAL.byt = 0 } - case 525: + case 526: yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2656 + //line sql.y:2660 { yyVAL.byt = 1 } - case 526: + case 527: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2659 + //line sql.y:2663 { yyVAL.empty = struct{}{} } - case 527: + case 528: yyDollar = yyS[yypt-3 : yypt+1] - //line sql.y:2661 + //line sql.y:2665 { yyVAL.empty = struct{}{} } - case 528: + case 529: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2664 + //line sql.y:2668 { yyVAL.str = "" } - case 529: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2666 - { - yyVAL.str = IgnoreStr - } case 530: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2670 { - yyVAL.empty = struct{}{} + yyVAL.str = IgnoreStr } case 531: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2672 + //line sql.y:2674 { yyVAL.empty = struct{}{} } case 532: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2674 + //line sql.y:2676 { yyVAL.empty = struct{}{} } case 533: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2676 + //line sql.y:2678 { yyVAL.empty = struct{}{} } case 534: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2678 + //line sql.y:2680 { yyVAL.empty = struct{}{} } case 535: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2680 + //line sql.y:2682 { yyVAL.empty = struct{}{} } case 536: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2682 + //line sql.y:2684 { yyVAL.empty = struct{}{} } case 537: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2684 + //line sql.y:2686 { yyVAL.empty = struct{}{} } case 538: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2686 + //line sql.y:2688 { yyVAL.empty = struct{}{} } case 539: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2688 + //line sql.y:2690 { yyVAL.empty = struct{}{} } case 540: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2691 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2692 { yyVAL.empty = struct{}{} } case 541: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2693 + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2695 { yyVAL.empty = struct{}{} } case 542: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2695 + //line sql.y:2697 { yyVAL.empty = struct{}{} } @@ -5610,45 +5613,45 @@ yydefault: } case 544: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2701 + //line sql.y:2703 { yyVAL.empty = struct{}{} } case 545: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2704 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2705 { yyVAL.empty = struct{}{} } case 546: - yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2706 + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2708 { yyVAL.empty = struct{}{} } case 547: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2708 + //line sql.y:2710 { yyVAL.empty = struct{}{} } case 548: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2711 + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2712 { - yyVAL.colIdent = ColIdent{} + yyVAL.empty = struct{}{} } case 549: - yyDollar = yyS[yypt-2 : yypt+1] - //line sql.y:2713 + yyDollar = yyS[yypt-0 : yypt+1] + //line sql.y:2715 { - yyVAL.colIdent = yyDollar[2].colIdent + yyVAL.colIdent = ColIdent{} } case 550: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2717 { - yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) + yyVAL.colIdent = yyDollar[2].colIdent } case 551: yyDollar = yyS[yypt-1 : yypt+1] @@ -5656,17 +5659,17 @@ yydefault: { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 553: + case 552: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2728 + //line sql.y:2725 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 554: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2734 + //line sql.y:2732 { - yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } case 555: yyDollar = yyS[yypt-1 : yypt+1] @@ -5674,41 +5677,41 @@ yydefault: { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 557: + case 556: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2742 + { + yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) + } + case 558: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2745 + //line sql.y:2749 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 738: + case 739: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2951 + //line sql.y:2955 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 739: + case 740: yyDollar = yyS[yypt-1 : yypt+1] - //line sql.y:2960 + //line sql.y:2964 { decNesting(yylex) } - case 740: - yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2965 - { - forceEOF(yylex) - } case 741: yyDollar = yyS[yypt-0 : yypt+1] - //line sql.y:2970 + //line sql.y:2969 { forceEOF(yylex) } case 742: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:2974 { forceEOF(yylex) @@ -5719,6 +5722,12 @@ yydefault: { forceEOF(yylex) } + case 744: + yyDollar = yyS[yypt-1 : yypt+1] + //line sql.y:2982 + { + forceEOF(yylex) + } } goto yystack /* stack new state and value */ } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index eb6f7d78cf0..40e4ddcfd16 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -419,6 +419,10 @@ delete_statement: { $$ = &Delete{Comments: Comments($2), TableExprs: TableExprs{&AliasedTableExpr{Expr:$4}}, Partitions: $5, Where: NewWhere(WhereStr, $6), OrderBy: $7, Limit: $8} } +| DELETE comment_opt FROM table_name_list USING table_references where_expression_opt + { + $$ = &Delete{Comments: Comments($2), Targets: $4, TableExprs: $6, Where: NewWhere(WhereStr, $7)} + } | DELETE comment_opt table_name_list from_or_using table_references where_expression_opt { $$ = &Delete{Comments: Comments($2), Targets: $3, TableExprs: $5, Where: NewWhere(WhereStr, $6)} diff --git a/go/vt/srvtopo/resilient_server.go b/go/vt/srvtopo/resilient_server.go index 44f23f7e720..cbee330b069 100644 --- a/go/vt/srvtopo/resilient_server.go +++ b/go/vt/srvtopo/resilient_server.go @@ -120,7 +120,7 @@ type ResilientServer struct { topoServer *topo.Server cacheTTL time.Duration cacheRefresh time.Duration - counts *stats.CountersWithLabels + counts *stats.CountersWithSingleLabel // mutex protects the cache map itself, not the individual // values in the cache. @@ -215,7 +215,7 @@ func NewResilientServer(base *topo.Server, counterPrefix string) *ResilientServe topoServer: base, cacheTTL: *srvTopoCacheTTL, cacheRefresh: *srvTopoCacheRefresh, - counts: stats.NewCountersWithLabels(counterPrefix+"Counts", "Resilient srvtopo server operations", "type"), + counts: stats.NewCountersWithSingleLabel(counterPrefix+"Counts", "Resilient srvtopo server operations", "type"), srvKeyspaceNamesCache: make(map[string]*srvKeyspaceNamesEntry), srvKeyspaceCache: make(map[string]*srvKeyspaceEntry), diff --git a/go/cmd/vtcombo/tablet_map.go b/go/vt/vtcombo/tablet_map.go similarity index 98% rename from go/cmd/vtcombo/tablet_map.go rename to go/vt/vtcombo/tablet_map.go index 3f2250c15fc..9fc9cfa36b4 100644 --- a/go/cmd/vtcombo/tablet_map.go +++ b/go/vt/vtcombo/tablet_map.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package main +package vtcombo import ( "flag" @@ -71,9 +71,9 @@ type tablet struct { // tabletMap maps the tablet uid to the tablet record var tabletMap map[uint32]*tablet -// createTablet creates an individual tablet, with its agent, and adds +// CreateTablet creates an individual tablet, with its agent, and adds // it to the map. If it's a master tablet, it also issues a TER. -func createTablet(ctx context.Context, ts *topo.Server, cell string, uid uint32, keyspace, shard, dbname string, tabletType topodatapb.TabletType, mysqld mysqlctl.MysqlDaemon, dbcfgs dbconfigs.DBConfigs) error { +func CreateTablet(ctx context.Context, ts *topo.Server, cell string, uid uint32, keyspace, shard, dbname string, tabletType topodatapb.TabletType, mysqld mysqlctl.MysqlDaemon, dbcfgs dbconfigs.DBConfigs) error { alias := &topodatapb.TabletAlias{ Cell: cell, Uid: uid, @@ -104,9 +104,9 @@ func createTablet(ctx context.Context, ts *topo.Server, cell string, uid uint32, return nil } -// initTabletMap creates the action agents and associated data structures +// InitTabletMap creates the action agents and associated data structures // for all tablets, based on the vttest proto parameter. -func initTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlctl.MysqlDaemon, dbcfgs dbconfigs.DBConfigs, schemaDir string, mycnf *mysqlctl.Mycnf) error { +func InitTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlctl.MysqlDaemon, dbcfgs dbconfigs.DBConfigs, schemaDir string, mycnf *mysqlctl.Mycnf) error { tabletMap = make(map[uint32]*tablet) ctx := context.Background() @@ -183,7 +183,7 @@ func initTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct replicas-- // create the master - if err := createTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_MASTER, mysqld, dbcfgs); err != nil { + if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_MASTER, mysqld, dbcfgs); err != nil { return err } uid++ @@ -191,7 +191,7 @@ func initTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct for i := 0; i < replicas; i++ { // create a replica slave - if err := createTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_REPLICA, mysqld, dbcfgs); err != nil { + if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_REPLICA, mysqld, dbcfgs); err != nil { return err } uid++ @@ -199,7 +199,7 @@ func initTabletMap(ts *topo.Server, tpb *vttestpb.VTTestTopology, mysqld mysqlct for i := 0; i < rdonlys; i++ { // create a rdonly slave - if err := createTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_RDONLY, mysqld, dbcfgs); err != nil { + if err := CreateTablet(ctx, ts, cell, uid, keyspace, shard, dbname, topodatapb.TabletType_RDONLY, mysqld, dbcfgs); err != nil { return err } uid++ diff --git a/go/vt/vtgate/engine/delete.go b/go/vt/vtgate/engine/delete.go index f682ded7be0..0cf3075b72d 100644 --- a/go/vt/vtgate/engine/delete.go +++ b/go/vt/vtgate/engine/delete.go @@ -76,21 +76,23 @@ func (del *Delete) MarshalJSON() ([]byte, error) { vindexName = del.Vindex.String() } marshalDelete := struct { - Opcode DeleteOpcode - Keyspace *vindexes.Keyspace `json:",omitempty"` - Query string `json:",omitempty"` - Vindex string `json:",omitempty"` - Values []sqltypes.PlanValue `json:",omitempty"` - Table string `json:",omitempty"` - OwnedVindexQuery string `json:",omitempty"` + Opcode DeleteOpcode + Keyspace *vindexes.Keyspace `json:",omitempty"` + Query string `json:",omitempty"` + Vindex string `json:",omitempty"` + Values []sqltypes.PlanValue `json:",omitempty"` + Table string `json:",omitempty"` + OwnedVindexQuery string `json:",omitempty"` + MultiShardAutocommit bool `json:",omitempty"` }{ - Opcode: del.Opcode, - Keyspace: del.Keyspace, - Query: del.Query, - Vindex: vindexName, - Values: del.Values, - Table: tname, - OwnedVindexQuery: del.OwnedVindexQuery, + Opcode: del.Opcode, + Keyspace: del.Keyspace, + Query: del.Query, + Vindex: vindexName, + Values: del.Values, + Table: tname, + OwnedVindexQuery: del.OwnedVindexQuery, + MultiShardAutocommit: del.MultiShardAutocommit, } return jsonutil.MarshalNoEscape(marshalDelete) } diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 2ad78c1a9c7..6a6e2d4f014 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -86,25 +86,27 @@ func (ins *Insert) MarshalJSON() ([]byte, error) { tname = ins.Table.Name.String() } marshalInsert := struct { - Opcode InsertOpcode - Keyspace *vindexes.Keyspace `json:",omitempty"` - Query string `json:",omitempty"` - Values []sqltypes.PlanValue `json:",omitempty"` - Table string `json:",omitempty"` - Generate *Generate `json:",omitempty"` - Prefix string `json:",omitempty"` - Mid []string `json:",omitempty"` - Suffix string `json:",omitempty"` + Opcode InsertOpcode + Keyspace *vindexes.Keyspace `json:",omitempty"` + Query string `json:",omitempty"` + Values []sqltypes.PlanValue `json:",omitempty"` + Table string `json:",omitempty"` + Generate *Generate `json:",omitempty"` + Prefix string `json:",omitempty"` + Mid []string `json:",omitempty"` + Suffix string `json:",omitempty"` + MultiShardAutocommit bool `json:",omitempty"` }{ - Opcode: ins.Opcode, - Keyspace: ins.Keyspace, - Query: ins.Query, - Values: ins.VindexValues, - Table: tname, - Generate: ins.Generate, - Prefix: ins.Prefix, - Mid: ins.Mid, - Suffix: ins.Suffix, + Opcode: ins.Opcode, + Keyspace: ins.Keyspace, + Query: ins.Query, + Values: ins.VindexValues, + Table: tname, + Generate: ins.Generate, + Prefix: ins.Prefix, + Mid: ins.Mid, + Suffix: ins.Suffix, + MultiShardAutocommit: ins.MultiShardAutocommit, } return jsonutil.MarshalNoEscape(marshalInsert) } diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 543dae4782e..c4990da4214 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -104,10 +104,10 @@ func NewExecutor(ctx context.Context, serv srvtopo.Server, cell, statsName strin e.vm.watchSrvVSchema(ctx, cell) executorOnce.Do(func() { - stats.NewGaugeFunc("QueryPlanCacheLength", "Query plan cache length", stats.IntFunc(e.plans.Length)) - stats.NewGaugeFunc("QueryPlanCacheSize", "Query plan cache size", stats.IntFunc(e.plans.Size)) - stats.NewGaugeFunc("QueryPlanCacheCapacity", "Query plan cache capacity", stats.IntFunc(e.plans.Capacity)) - stats.NewCounterFunc("QueryPlanCacheEvictions", "Query plan cache evictions", stats.IntFunc(e.plans.Evictions)) + stats.NewGaugeFunc("QueryPlanCacheLength", "Query plan cache length", e.plans.Length) + stats.NewGaugeFunc("QueryPlanCacheSize", "Query plan cache size", e.plans.Size) + stats.NewGaugeFunc("QueryPlanCacheCapacity", "Query plan cache capacity", e.plans.Capacity) + stats.NewCounterFunc("QueryPlanCacheEvictions", "Query plan cache evictions", e.plans.Evictions) stats.Publish("QueryPlanCacheOldest", stats.StringFunc(func() string { return fmt.Sprintf("%v", e.plans.Oldest()) })) diff --git a/go/vt/vtgate/gateway/hybridgateway.go b/go/vt/vtgate/gateway/hybridgateway.go index 985f15bc9df..8f908565bc5 100644 --- a/go/vt/vtgate/gateway/hybridgateway.go +++ b/go/vt/vtgate/gateway/hybridgateway.go @@ -92,8 +92,8 @@ func (h *HybridGateway) WaitForTablets(ctx context.Context, tabletTypesToWait [] func (h *HybridGateway) RegisterStats() { stats.NewCountersFuncWithMultiLabels( "L2VtgateConnections", + "number of l2vtgate connection", []string{"Keyspace", "ShardName", "TabletType"}, - "The l2vtgate connection counts", h.servingConnStats) } diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index d8571f50126..52194ecd81a 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -89,7 +89,7 @@ var ( qpsByKeyspace *stats.Rates qpsByDbType *stats.Rates - vschemaCounters *stats.CountersWithLabels + vschemaCounters *stats.CountersWithSingleLabel errorsByOperation *stats.Rates errorsByKeyspace *stats.Rates @@ -99,7 +99,7 @@ var ( // Error counters should be global so they can be set from anywhere errorCounts *stats.CountersWithMultiLabels - warnings *stats.CountersWithLabels + warnings *stats.CountersWithSingleLabel ) // VTGate is the rpc interface to vtgate. Only one instance @@ -156,7 +156,7 @@ func Init(ctx context.Context, hc discovery.HealthCheck, serv srvtopo.Server, ce // vschemaCounters needs to be initialized before planner to // catch the initial load stats. - vschemaCounters = stats.NewCountersWithLabels("VtgateVSchemaCounts", "Vtgate vschema counts", "changes") + vschemaCounters = stats.NewCountersWithSingleLabel("VtgateVSchemaCounts", "Vtgate vschema counts", "changes") // Build objects from low to high level. // Start with the gateway. If we can't reach the topology service, @@ -239,7 +239,7 @@ func Init(ctx context.Context, hc discovery.HealthCheck, serv srvtopo.Server, ce errorsByDbType = stats.NewRates("ErrorsByDbType", stats.CounterForDimension(errorCounts, "DbType"), 15, 1*time.Minute) errorsByCode = stats.NewRates("ErrorsByCode", stats.CounterForDimension(errorCounts, "Code"), 15, 1*time.Minute) - warnings = stats.NewCountersWithLabels("VtGateWarnings", "Vtgate warnings", "type", "IgnoredSet") + warnings = stats.NewCountersWithSingleLabel("VtGateWarnings", "Vtgate warnings", "type", "IgnoredSet") servenv.OnRun(func() { for _, f := range RegisterVTGates { diff --git a/go/vt/vttablet/heartbeat/writer.go b/go/vt/vttablet/heartbeat/writer.go index a007e40809b..bb7b3f2a2ca 100644 --- a/go/vt/vttablet/heartbeat/writer.go +++ b/go/vt/vttablet/heartbeat/writer.go @@ -155,7 +155,7 @@ func (w *Writer) Close() { // and we also execute them with an isolated connection that turns off the binlog and // is closed at the end. func (w *Writer) initializeTables(cp *mysql.ConnParams) error { - conn, err := dbconnpool.NewDBConnection(cp, stats.NewTimings("", "")) + conn, err := dbconnpool.NewDBConnection(cp, stats.NewTimings("", "", "")) if err != nil { return fmt.Errorf("Failed to create connection for heartbeat: %v", err) } diff --git a/go/vt/vttablet/tabletmanager/binlog_players.go b/go/vt/vttablet/tabletmanager/binlog_players.go index 436e2b0297f..2baa2e69163 100644 --- a/go/vt/vttablet/tabletmanager/binlog_players.go +++ b/go/vt/vttablet/tabletmanager/binlog_players.go @@ -421,29 +421,35 @@ func NewBinlogPlayerMap(ts *topo.Server, mysqld mysqlctl.MysqlDaemon, vtClientFa // RegisterBinlogPlayerMap registers the varz for the players. func RegisterBinlogPlayerMap(blm *BinlogPlayerMap) { - stats.NewGaugeFunc("BinlogPlayerMapSize", "Binlog player map size", stats.IntFunc(func() int64 { + stats.NewGaugeFunc("BinlogPlayerMapSize", "Binlog player map size", func() int64 { blm.mu.Lock() defer blm.mu.Unlock() return int64(len(blm.players)) - })) + }) stats.NewGaugeFunc( "BinlogPlayerSecondsBehindMaster", "Binlog player seconds behind master", - stats.IntFunc(func() int64 { + func() int64 { blm.mu.Lock() defer blm.mu.Unlock() return blm.maxSecondsBehindMasterUNGUARDED() - })) - stats.Publish("BinlogPlayerSecondsBehindMasterMap", stats.CountersFunc(func() map[string]int64 { - blm.mu.Lock() - result := make(map[string]int64, len(blm.players)) - for i, bpc := range blm.players { - sbm := bpc.binlogPlayerStats.SecondsBehindMaster.Get() - result[fmt.Sprintf("%v", i)] = sbm - } - blm.mu.Unlock() - return result - })) + }) + stats.NewCountersFuncWithMultiLabels( + "BinlogPlayerSecondsBehindMasterMap", + "Binlog player seconds behind master per player", + // CAUTION: Always keep this label as "counts" because the Google + // internal monitoring may depend on this specific value. + []string{"counts"}, + func() map[string]int64 { + blm.mu.Lock() + result := make(map[string]int64, len(blm.players)) + for i, bpc := range blm.players { + sbm := bpc.binlogPlayerStats.SecondsBehindMaster.Get() + result[fmt.Sprintf("%v", i)] = sbm + } + blm.mu.Unlock() + return result + }) stats.Publish("BinlogPlayerSourceShardNameMap", stats.StringMapFunc(func() map[string]string { blm.mu.Lock() result := make(map[string]string, len(blm.players)) diff --git a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go index 02f9b4dc256..63b36602aa1 100644 --- a/go/vt/vttablet/tabletmanager/rpc_external_reparent.go +++ b/go/vt/vttablet/tabletmanager/rpc_external_reparent.go @@ -39,7 +39,7 @@ import ( var ( finalizeReparentTimeout = flag.Duration("finalize_external_reparent_timeout", 30*time.Second, "Timeout for the finalize stage of a fast external reparent reconciliation.") - externalReparentStats = stats.NewTimings("ExternalReparents", "Stats from external reparentings", "NewMasterVisible", "FullRebuild") + externalReparentStats = stats.NewTimings("ExternalReparents", "External reparenting time", "stage", "NewMasterVisible", "FullRebuild") ) // SetReparentFlags changes flag values. It should only be used in tests. diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 3aa8c010694..be798730360 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -287,6 +287,17 @@ func (agent *ActionAgent) DemoteMaster(ctx context.Context) (string, error) { } defer agent.unlock() + // Tell Orchestrator we're stopped on purpose the demotion. + // This is a best effort task, so run it in a goroutine. + go func() { + if agent.orc == nil { + return + } + if err := agent.orc.BeginMaintenance(agent.Tablet(), "vttablet has been told to DemoteMaster"); err != nil { + log.Warningf("Orchestrator BeginMaintenance failed: %v", err) + } + }() + // Set the server read-only. Note all active connections are not // affected. if err := agent.MysqlDaemon.SetReadOnly(true); err != nil { @@ -399,6 +410,21 @@ func (agent *ActionAgent) setMasterLocked(ctx context.Context, parentAlias *topo return err } + // If this tablet used to be a master, end orchestrator maintenance after we are connected to the new master. + // This is a best effort operation, so it should happen in a goroutine + if agent.Tablet().Type == topodatapb.TabletType_MASTER { + defer func() { + go func() { + if agent.orc == nil { + return + } + if err := agent.orc.EndMaintenance(agent.Tablet()); err != nil { + log.Warningf("Orchestrator EndMaintenance failed: %v", err) + } + }() + }() + } + // See if we were replicating at all, and should be replicating wasReplicating := false shouldbeReplicating := false diff --git a/go/vt/vttablet/tabletserver/connpool/dbconn.go b/go/vt/vttablet/tabletserver/connpool/dbconn.go index e36b0fce386..5228289ffcc 100644 --- a/go/vt/vttablet/tabletserver/connpool/dbconn.go +++ b/go/vt/vttablet/tabletserver/connpool/dbconn.go @@ -304,7 +304,7 @@ func (dbc *DBConn) Recycle() { // Kill will also not kill a query more than once. func (dbc *DBConn) Kill(reason string, elapsed time.Duration) error { tabletenv.KillStats.Add("Queries", 1) - log.Infof("Due to %s, elapsed time: %v, killing query %s", reason, elapsed, dbc.Current()) + log.Infof("Due to %s, elapsed time: %v, killing query ID %v %s", reason, elapsed, dbc.conn.ID(), dbc.Current()) killConn, err := dbc.dbaPool.Get(context.TODO()) if err != nil { log.Warningf("Failed to get conn from dba pool: %v", err) @@ -314,7 +314,7 @@ func (dbc *DBConn) Kill(reason string, elapsed time.Duration) error { sql := fmt.Sprintf("kill %d", dbc.conn.ID()) _, err = killConn.ExecuteFetch(sql, 10000, false) if err != nil { - log.Errorf("Could not kill query %s: %v", dbc.Current(), err) + log.Errorf("Could not kill query ID %v %s: %v", dbc.conn.ID(), dbc.Current(), err) return err } return nil diff --git a/go/vt/vttablet/tabletserver/connpool/pool.go b/go/vt/vttablet/tabletserver/connpool/pool.go index a36e4f29863..7c96b1dd642 100644 --- a/go/vt/vttablet/tabletserver/connpool/pool.go +++ b/go/vt/vttablet/tabletserver/connpool/pool.go @@ -82,15 +82,15 @@ func New( return cp } usedNames[name] = true - stats.NewGaugeFunc(name+"Capacity", "Tablet server conn pool capacity", stats.IntFunc(cp.Capacity)) - stats.NewGaugeFunc(name+"Available", "Tablet server conn pool available", stats.IntFunc(cp.Available)) - stats.NewGaugeFunc(name+"Active", "Tablet server conn pool active", stats.IntFunc(cp.Active)) - stats.NewGaugeFunc(name+"InUse", "Tablet server conn pool in use", stats.IntFunc(cp.InUse)) - stats.NewGaugeFunc(name+"MaxCap", "Tablet server conn pool max cap", stats.IntFunc(cp.MaxCap)) - stats.NewCounterFunc(name+"WaitCount", "Tablet server conn pool wait count", stats.IntFunc(cp.WaitCount)) - stats.NewCounterFunc(name+"WaitTime", "Tablet server wait time", stats.DurationFunc(cp.WaitTime)) - stats.NewCounterFunc(name+"IdleTimeout", "Tablet server idle timeout", stats.DurationFunc(cp.IdleTimeout)) - stats.NewCounterFunc(name+"IdleClosed", "Tablet server conn pool idle closed", stats.IntFunc(cp.IdleClosed)) + stats.NewGaugeFunc(name+"Capacity", "Tablet server conn pool capacity", cp.Capacity) + stats.NewGaugeFunc(name+"Available", "Tablet server conn pool available", cp.Available) + stats.NewGaugeFunc(name+"Active", "Tablet server conn pool active", cp.Active) + stats.NewGaugeFunc(name+"InUse", "Tablet server conn pool in use", cp.InUse) + stats.NewGaugeFunc(name+"MaxCap", "Tablet server conn pool max cap", cp.MaxCap) + stats.NewCounterFunc(name+"WaitCount", "Tablet server conn pool wait count", cp.WaitCount) + stats.NewCounterDurationFunc(name+"WaitTime", "Tablet server wait time", cp.WaitTime) + stats.NewGaugeDurationFunc(name+"IdleTimeout", "Tablet server idle timeout", cp.IdleTimeout) + stats.NewCounterFunc(name+"IdleClosed", "Tablet server conn pool idle closed", cp.IdleClosed) return cp } diff --git a/go/vt/vttablet/tabletserver/query_engine.go b/go/vt/vttablet/tabletserver/query_engine.go index 72fd512c0c4..79e92d07e17 100644 --- a/go/vt/vttablet/tabletserver/query_engine.go +++ b/go/vt/vttablet/tabletserver/query_engine.go @@ -234,24 +234,24 @@ func NewQueryEngine(checker connpool.MySQLChecker, se *schema.Engine, config tab qe.accessCheckerLogger = logutil.NewThrottledLogger("accessChecker", 1*time.Second) qeOnce.Do(func() { - stats.NewGaugeFunc("MaxResultSize", "Query engine max result size", stats.IntFunc(qe.maxResultSize.Get)) - stats.NewGaugeFunc("WarnResultSize", "Query engine warn result size", stats.IntFunc(qe.warnResultSize.Get)) - stats.NewGaugeFunc("MaxDMLRows", "Query engine max DML rows", stats.IntFunc(qe.maxDMLRows.Get)) - stats.NewGaugeFunc("StreamBufferSize", "Query engine stream buffer size", stats.IntFunc(qe.streamBufferSize.Get)) - stats.NewCounterFunc("TableACLExemptCount", "Query engine table ACL exempt count", stats.IntFunc(qe.tableaclExemptCount.Get)) - stats.NewGaugeFunc("QueryPoolWaiters", "Query engine query pool waiters", stats.IntFunc(qe.queryPoolWaiters.Get)) - - stats.NewGaugeFunc("QueryCacheLength", "Query engine query cache length", stats.IntFunc(qe.plans.Length)) - stats.NewGaugeFunc("QueryCacheSize", "Query engine query cache size", stats.IntFunc(qe.plans.Size)) - stats.NewGaugeFunc("QueryCacheCapacity", "Query engine query cache capacity", stats.IntFunc(qe.plans.Capacity)) - stats.NewCounterFunc("QueryCacheEvictions", "Query engine query cache evictions", stats.IntFunc(qe.plans.Evictions)) + stats.NewGaugeFunc("MaxResultSize", "Query engine max result size", qe.maxResultSize.Get) + stats.NewGaugeFunc("WarnResultSize", "Query engine warn result size", qe.warnResultSize.Get) + stats.NewGaugeFunc("MaxDMLRows", "Query engine max DML rows", qe.maxDMLRows.Get) + stats.NewGaugeFunc("StreamBufferSize", "Query engine stream buffer size", qe.streamBufferSize.Get) + stats.NewCounterFunc("TableACLExemptCount", "Query engine table ACL exempt count", qe.tableaclExemptCount.Get) + stats.NewGaugeFunc("QueryPoolWaiters", "Query engine query pool waiters", qe.queryPoolWaiters.Get) + + stats.NewGaugeFunc("QueryCacheLength", "Query engine query cache length", qe.plans.Length) + stats.NewGaugeFunc("QueryCacheSize", "Query engine query cache size", qe.plans.Size) + stats.NewGaugeFunc("QueryCacheCapacity", "Query engine query cache capacity", qe.plans.Capacity) + stats.NewCounterFunc("QueryCacheEvictions", "Query engine query cache evictions", qe.plans.Evictions) stats.Publish("QueryCacheOldest", stats.StringFunc(func() string { return fmt.Sprintf("%v", qe.plans.Oldest()) })) - _ = stats.NewCountersFuncWithMultiLabels("QueryCounts", []string{"Table", "Plan"}, "query counts", qe.getQueryCount) - _ = stats.NewCountersFuncWithMultiLabels("QueryTimesNs", []string{"Table", "Plan"}, "query times in ns", qe.getQueryTime) - _ = stats.NewCountersFuncWithMultiLabels("QueryRowCounts", []string{"Table", "Plan"}, "query row counts", qe.getQueryRowCount) - _ = stats.NewCountersFuncWithMultiLabels("QueryErrorCounts", []string{"Table", "Plan"}, "query error counts", qe.getQueryErrorCount) + _ = stats.NewCountersFuncWithMultiLabels("QueryCounts", "query counts", []string{"Table", "Plan"}, qe.getQueryCount) + _ = stats.NewCountersFuncWithMultiLabels("QueryTimesNs", "query times in ns", []string{"Table", "Plan"}, qe.getQueryTime) + _ = stats.NewCountersFuncWithMultiLabels("QueryRowCounts", "query row counts", []string{"Table", "Plan"}, qe.getQueryRowCount) + _ = stats.NewCountersFuncWithMultiLabels("QueryErrorCounts", "query error counts", []string{"Table", "Plan"}, qe.getQueryErrorCount) http.Handle("/debug/hotrows", qe.txSerializer) diff --git a/go/vt/vttablet/tabletserver/replication_watcher.go b/go/vt/vttablet/tabletserver/replication_watcher.go index ba9459b4961..3c2e6986959 100644 --- a/go/vt/vttablet/tabletserver/replication_watcher.go +++ b/go/vt/vttablet/tabletserver/replication_watcher.go @@ -71,12 +71,12 @@ func NewReplicationWatcher(se *schema.Engine, config tabletenv.TabletConfig) *Re stats.NewGaugeFunc( "EventTokenTimestamp", "Replication watcher event token timestamp", - stats.IntFunc(func() int64 { + func() int64 { if e := rpw.EventToken(); e != nil { return e.Timestamp } return 0 - })) + }) }) return rpw } diff --git a/go/vt/vttablet/tabletserver/schema/engine.go b/go/vt/vttablet/tabletserver/schema/engine.go index 4389f1613b7..944e640227e 100644 --- a/go/vt/vttablet/tabletserver/schema/engine.go +++ b/go/vt/vttablet/tabletserver/schema/engine.go @@ -77,12 +77,12 @@ func NewEngine(checker connpool.MySQLChecker, config tabletenv.TabletConfig) *En reloadTime: reloadTime, } schemaOnce.Do(func() { - _ = stats.NewGaugeFunc("SchemaReloadTime", "vttablet keeps table schemas in its own memory and periodically refreshes it from MySQL. This config controls the reload time.", stats.DurationFunc(se.ticks.Interval)) - _ = stats.NewGaugesFuncWithMultiLabels("TableRows", []string{"Table"}, "table rows created in tabletserver", se.getTableRows) - _ = stats.NewGaugesFuncWithMultiLabels("DataLength", []string{"Table"}, "data length in tabletserver", se.getDataLength) - _ = stats.NewGaugesFuncWithMultiLabels("IndexLength", []string{"Table"}, "index length in tabletserver", se.getIndexLength) - _ = stats.NewGaugesFuncWithMultiLabels("DataFree", []string{"Table"}, "data free in tabletserver", se.getDataFree) - _ = stats.NewGaugesFuncWithMultiLabels("MaxDataLength", []string{"Table"}, "max data length in tabletserver", se.getMaxDataLength) + _ = stats.NewGaugeDurationFunc("SchemaReloadTime", "vttablet keeps table schemas in its own memory and periodically refreshes it from MySQL. This config controls the reload time.", se.ticks.Interval) + _ = stats.NewGaugesFuncWithMultiLabels("TableRows", "table rows created in tabletserver", []string{"Table"}, se.getTableRows) + _ = stats.NewGaugesFuncWithMultiLabels("DataLength", "data length in tabletserver", []string{"Table"}, se.getDataLength) + _ = stats.NewGaugesFuncWithMultiLabels("IndexLength", "index length in tabletserver", []string{"Table"}, se.getIndexLength) + _ = stats.NewGaugesFuncWithMultiLabels("DataFree", "data free in tabletserver", []string{"Table"}, se.getDataFree) + _ = stats.NewGaugesFuncWithMultiLabels("MaxDataLength", "max data length in tabletserver", []string{"Table"}, se.getMaxDataLength) http.Handle("/debug/schema", se) http.HandleFunc("/schemaz", func(w http.ResponseWriter, r *http.Request) { diff --git a/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go b/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go index 1af3bd76f38..0fd1dfc774b 100644 --- a/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go +++ b/go/vt/vttablet/tabletserver/tabletenv/tabletenv.go @@ -34,17 +34,17 @@ import ( var ( // MySQLStats shows the time histogram for operations spent on mysql side. - MySQLStats = stats.NewTimings("Mysql", "MySQl query time") + MySQLStats = stats.NewTimings("Mysql", "MySQl query time", "operation") // QueryStats shows the time histogram for each type of queries. - QueryStats = stats.NewTimings("Queries", "MySQL query timings") + QueryStats = stats.NewTimings("Queries", "MySQL query timings", "plan_type") // QPSRates shows the qps of QueryStats. Sample every 5 seconds and keep samples for up to 15 mins. QPSRates = stats.NewRates("QPS", QueryStats, 15*60/5, 5*time.Second) // WaitStats shows the time histogram for wait operations - WaitStats = stats.NewTimings("Waits", "Wait operations") + WaitStats = stats.NewTimings("Waits", "Wait operations", "type") // KillStats shows number of connections being killed. - KillStats = stats.NewCountersWithLabels("Kills", "Number of connections being killed", "query_type", "Transactions", "Queries") + KillStats = stats.NewCountersWithSingleLabel("Kills", "Number of connections being killed", "query_type", "Transactions", "Queries") // ErrorStats shows number of critial errors happened. - ErrorStats = stats.NewCountersWithLabels( + ErrorStats = stats.NewCountersWithSingleLabel( "Errors", "Critical errors", "error_code", @@ -67,11 +67,11 @@ var ( vtrpcpb.Code_DATA_LOSS.String(), ) // InternalErrors shows number of errors from internal components. - InternalErrors = stats.NewCountersWithLabels("InternalErrors", "Internal component errors", "type", "Task", "StrayTransactions", "Panic", "HungQuery", "Schema", "TwopcCommit", "TwopcResurrection", "WatchdogFail", "Messages") + InternalErrors = stats.NewCountersWithSingleLabel("InternalErrors", "Internal component errors", "type", "Task", "StrayTransactions", "Panic", "HungQuery", "Schema", "TwopcCommit", "TwopcResurrection", "WatchdogFail", "Messages") // Warnings shows number of warnings - Warnings = stats.NewCountersWithLabels("Warnings", "Warnings", "type", "ResultsExceeded") + Warnings = stats.NewCountersWithSingleLabel("Warnings", "Warnings", "type", "ResultsExceeded") // Unresolved tracks unresolved items. For now it's just Prepares. - Unresolved = stats.NewGaugesWithLabels("Unresolved", "Unresolved items", "item_type", "Prepares") + Unresolved = stats.NewGaugesWithSingleLabel("Unresolved", "Unresolved items", "item_type", "Prepares") // UserTableQueryCount shows number of queries received for each CallerID/table combination. UserTableQueryCount = stats.NewCountersWithMultiLabels( "UserTableQueryCount", @@ -93,7 +93,9 @@ var ( "Total transaction latency for each CallerID", []string{"CallerID", "Conclusion"}) // ResultStats shows the histogram of number of rows returned. - ResultStats = stats.NewHistogram("Results", []int64{0, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000}) + ResultStats = stats.NewHistogram("Results", + "Distribution of rows returned", + []int64{0, 1, 5, 10, 50, 100, 500, 1000, 5000, 10000}) // TableaclAllowed tracks the number allows. TableaclAllowed = stats.NewCountersWithMultiLabels( "TableACLAllowed", diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index 539a1957444..e91c003c1be 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -238,15 +238,15 @@ func NewTabletServer(config tabletenv.TabletConfig, topoServer *topo.Server, ali // So that vtcombo doesn't even call it once, on the first tablet. // And we can remove the tsOnce variable. tsOnce.Do(func() { - stats.NewGaugeFunc("TabletState", "Tablet server state", stats.IntFunc(func() int64 { + stats.NewGaugeFunc("TabletState", "Tablet server state", func() int64 { tsv.mu.Lock() state := tsv.state tsv.mu.Unlock() return state - })) - stats.NewGaugeFunc("QueryTimeout", "Tablet server query timeout", stats.DurationFunc(tsv.QueryTimeout.Get)) - stats.NewGaugeFunc("QueryPoolTimeout", "Tablet server timeout to get a connection from the query pool", stats.DurationFunc(tsv.qe.connTimeout.Get)) - stats.NewGaugeFunc("BeginTimeout", "Tablet server begin timeout", stats.DurationFunc(tsv.BeginTimeout.Get)) + }) + stats.NewGaugeDurationFunc("QueryTimeout", "Tablet server query timeout", tsv.QueryTimeout.Get) + stats.NewGaugeDurationFunc("QueryPoolTimeout", "Tablet server timeout to get a connection from the query pool", tsv.qe.connTimeout.Get) + stats.NewGaugeDurationFunc("BeginTimeout", "Tablet server begin timeout", tsv.BeginTimeout.Get) stats.Publish("TabletStateName", stats.StringFunc(tsv.GetState)) }) return tsv diff --git a/go/vt/vttablet/tabletserver/twopc.go b/go/vt/vttablet/tabletserver/twopc.go index b9cb2bfb10c..f1d67496e8d 100644 --- a/go/vt/vttablet/tabletserver/twopc.go +++ b/go/vt/vttablet/tabletserver/twopc.go @@ -130,7 +130,7 @@ func NewTwoPC(readPool *connpool.Pool) *TwoPC { // are not present, they are created. func (tpc *TwoPC) Init(sidecarDBName string, dbaparams *mysql.ConnParams) error { dbname := sqlescape.EscapeID(sidecarDBName) - conn, err := dbconnpool.NewDBConnection(dbaparams, stats.NewTimings("", "")) + conn, err := dbconnpool.NewDBConnection(dbaparams, stats.NewTimings("", "", "")) if err != nil { return err } diff --git a/go/vt/vttablet/tabletserver/tx_pool.go b/go/vt/vttablet/tabletserver/tx_pool.go index 956cf477b33..8d610becb6d 100644 --- a/go/vt/vttablet/tabletserver/tx_pool.go +++ b/go/vt/vttablet/tabletserver/tx_pool.go @@ -56,7 +56,7 @@ const txLogInterval = time.Duration(1 * time.Minute) var ( txOnce sync.Once - txStats = stats.NewTimings("Transactions", "Transaction stats") + txStats = stats.NewTimings("Transactions", "Transaction stats", "operation") txIsolations = map[querypb.ExecuteOptions_TransactionIsolation]string{ querypb.ExecuteOptions_REPEATABLE_READ: "set transaction isolation level REPEATABLE READ", @@ -119,8 +119,8 @@ func NewTxPool( txOnce.Do(func() { // Careful: conns also exports name+"xxx" vars, // but we know it doesn't export Timeout. - stats.NewGaugeFunc(prefix+"TransactionPoolTimeout", "Transaction pool timeout", stats.DurationFunc(axp.timeout.Get)) - stats.NewGaugeFunc(prefix+"TransactionPoolWaiters", "Transaction pool waiters", stats.IntFunc(axp.waiters.Get)) + stats.NewGaugeDurationFunc(prefix+"TransactionPoolTimeout", "Transaction pool timeout", axp.timeout.Get) + stats.NewGaugeFunc(prefix+"TransactionPoolWaiters", "Transaction pool waiters", axp.waiters.Get) }) return axp } diff --git a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go index 0a9ec503040..f68d01e7bce 100644 --- a/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go +++ b/go/vt/vttablet/tabletserver/txlimiter/tx_limiter.go @@ -31,8 +31,8 @@ import ( const unknown string = "unknown" var ( - rejections = stats.NewCountersWithLabels("TxLimiterRejections", "rejections from TxLimiter", "user") - rejectionsDryRun = stats.NewCountersWithLabels("TxLimiterRejectionsDryRun", "rejections from TxLimiter in dry run", "user") + rejections = stats.NewCountersWithSingleLabel("TxLimiterRejections", "rejections from TxLimiter", "user") + rejectionsDryRun = stats.NewCountersWithSingleLabel("TxLimiterRejectionsDryRun", "rejections from TxLimiter in dry run", "user") ) // TxLimiter is the transaction limiter interface. diff --git a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go index 15bc1a63258..c4a1768adc3 100644 --- a/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go +++ b/go/vt/vttablet/tabletserver/txserializer/tx_serializer.go @@ -40,27 +40,27 @@ var ( // waits stores how many times a transaction was queued because another // transaction was already in flight for the same row (range). // The key of the map is the table name of the query. - waits = stats.NewCountersWithLabels( + waits = stats.NewCountersWithSingleLabel( "TxSerializerWaits", "Number of times a transaction was queued because another transaction was already in flight for the same row range", "table_name") // waitsDryRun is similar as "waits": In dry-run mode it records how many // transactions would have been queued. // The key of the map is the table name of the query. - waitsDryRun = stats.NewCountersWithLabels( + waitsDryRun = stats.NewCountersWithSingleLabel( "TxSerializerWaitsDryRun", "Dry run number of transactions that would've been queued", "table_name") // queueExceeded counts per table how many transactions were rejected because // the max queue size per row (range) was exceeded. - queueExceeded = stats.NewCountersWithLabels( + queueExceeded = stats.NewCountersWithSingleLabel( "TxSerializerQueueExceeded", "Number of transactions that were rejected because the max queue size per row range was exceeded", "table_name") // queueExceededDryRun counts in dry-run mode how many transactions would have // been rejected due to exceeding the max queue size per row (range). - queueExceededDryRun = stats.NewCountersWithLabels( + queueExceededDryRun = stats.NewCountersWithSingleLabel( "TxSerializerQueueExceededDryRun", "Dry-run Number of transactions that were rejcted because the max queue size was exceeded", "table_name") diff --git a/go/vt/worker/row_aggregator.go b/go/vt/worker/row_aggregator.go index 97726208ddf..9ccd803e4bb 100644 --- a/go/vt/worker/row_aggregator.go +++ b/go/vt/worker/row_aggregator.go @@ -48,9 +48,7 @@ type RowAggregator struct { td *tabletmanagerdatapb.TableDefinition diffType DiffType builder QueryBuilder - // statsCounters has a "diffType" specific stats.CountersWithLabels object to track how - // many rows were changed per table. - statsCounters *stats.CountersWithLabels + statsCounters *stats.CountersWithSingleLabel buffer bytes.Buffer bufferedRows int @@ -60,7 +58,7 @@ type RowAggregator struct { // The index of the elements in statCounters must match the elements // in "DiffTypes" i.e. the first counter is for inserts, second for updates // and the third for deletes. -func NewRowAggregator(ctx context.Context, maxRows, maxSize int, insertChannel chan string, dbName string, td *tabletmanagerdatapb.TableDefinition, diffType DiffType, statsCounters *stats.CountersWithLabels) *RowAggregator { +func NewRowAggregator(ctx context.Context, maxRows, maxSize int, insertChannel chan string, dbName string, td *tabletmanagerdatapb.TableDefinition, diffType DiffType, statsCounters *stats.CountersWithSingleLabel) *RowAggregator { // Construct head and tail base commands for the reconciliation statement. var builder QueryBuilder switch diffType { diff --git a/go/vt/worker/row_differ.go b/go/vt/worker/row_differ.go index 6f1e50b196f..a6be54c2f4f 100644 --- a/go/vt/worker/row_differ.go +++ b/go/vt/worker/row_differ.go @@ -74,7 +74,7 @@ type RowDiffer2 struct { // aggregators are keyed by destination shard and DiffType. aggregators [][]*RowAggregator // equalRowsStatsCounters tracks per table how many rows are equal. - equalRowsStatsCounters *stats.CountersWithLabels + equalRowsStatsCounters *stats.CountersWithSingleLabel // tableName is required to update "equalRowsStatsCounters". tableName string } @@ -89,7 +89,7 @@ func NewRowDiffer2(ctx context.Context, left, right ResultReader, td *tabletmana // Parameters required by RowRouter. destinationShards []*topo.ShardInfo, keyResolver keyspaceIDResolver, // Parameters required by RowAggregator. - insertChannels []chan string, abort <-chan struct{}, dbNames []string, writeQueryMaxRows, writeQueryMaxSize int, statsCounters []*stats.CountersWithLabels) (*RowDiffer2, error) { + insertChannels []chan string, abort <-chan struct{}, dbNames []string, writeQueryMaxRows, writeQueryMaxSize int, statsCounters []*stats.CountersWithSingleLabel) (*RowDiffer2, error) { if len(statsCounters) != len(DiffTypes) { panic(fmt.Sprintf("statsCounter has the wrong number of elements. got = %v, want = %v", len(statsCounters), len(DiffTypes))) diff --git a/go/vt/worker/split_clone.go b/go/vt/worker/split_clone.go index 3dcc884c079..096298a4c92 100644 --- a/go/vt/worker/split_clone.go +++ b/go/vt/worker/split_clone.go @@ -826,14 +826,14 @@ func (scw *SplitCloneWorker) clone(ctx context.Context, state StatusWorkerState) } firstSourceTablet = tablets[0].Tablet } - var statsCounters []*stats.CountersWithLabels + var statsCounters []*stats.CountersWithSingleLabel var tableStatusList *tableStatusList switch state { case WorkerStateCloneOnline: - statsCounters = []*stats.CountersWithLabels{statsOnlineInsertsCounters, statsOnlineUpdatesCounters, statsOnlineDeletesCounters, statsOnlineEqualRowsCounters} + statsCounters = []*stats.CountersWithSingleLabel{statsOnlineInsertsCounters, statsOnlineUpdatesCounters, statsOnlineDeletesCounters, statsOnlineEqualRowsCounters} tableStatusList = scw.tableStatusListOnline case WorkerStateCloneOffline: - statsCounters = []*stats.CountersWithLabels{statsOfflineInsertsCounters, statsOfflineUpdatesCounters, statsOfflineDeletesCounters, statsOfflineEqualRowsCounters} + statsCounters = []*stats.CountersWithSingleLabel{statsOfflineInsertsCounters, statsOfflineUpdatesCounters, statsOfflineDeletesCounters, statsOfflineEqualRowsCounters} tableStatusList = scw.tableStatusListOffline } diff --git a/go/vt/worker/split_diff.go b/go/vt/worker/split_diff.go index 47c46a25901..e7b51256146 100644 --- a/go/vt/worker/split_diff.go +++ b/go/vt/worker/split_diff.go @@ -19,6 +19,7 @@ package worker import ( "fmt" "html/template" + "sort" "sync" "golang.org/x/net/context" @@ -34,7 +35,6 @@ import ( tabletmanagerdatapb "vitess.io/vitess/go/vt/proto/tabletmanagerdata" topodatapb "vitess.io/vitess/go/vt/proto/topodata" - "sort" ) // SplitDiffWorker executes a diff between a destination shard and its @@ -219,7 +219,7 @@ func (sdw *SplitDiffWorker) findTargets(ctx context.Context) error { // find an appropriate tablet in destination shard var err error - sdw.destinationAlias, err = FindWorkerTablet(ctx, sdw.wr, sdw.cleaner, nil /* tsc */ , sdw.cell, sdw.keyspace, sdw.shard, sdw.minHealthyRdonlyTablets) + sdw.destinationAlias, err = FindWorkerTablet(ctx, sdw.wr, sdw.cleaner, nil /* tsc */, sdw.cell, sdw.keyspace, sdw.shard, sdw.minHealthyRdonlyTablets) if err != nil { return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", sdw.cell, sdw.keyspace, sdw.shard, err) } @@ -227,7 +227,7 @@ func (sdw *SplitDiffWorker) findTargets(ctx context.Context) error { // find an appropriate tablet in the source shard for _, ss := range sdw.shardInfo.SourceShards { if ss.Uid == sdw.sourceUID { - sdw.sourceAlias, err = FindWorkerTablet(ctx, sdw.wr, sdw.cleaner, nil /* tsc */ , sdw.cell, sdw.keyspace, ss.Shard, sdw.minHealthyRdonlyTablets) + sdw.sourceAlias, err = FindWorkerTablet(ctx, sdw.wr, sdw.cleaner, nil /* tsc */, sdw.cell, sdw.keyspace, ss.Shard, sdw.minHealthyRdonlyTablets) if err != nil { return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", sdw.cell, sdw.keyspace, ss.Shard, err) } @@ -370,7 +370,7 @@ func (sdw *SplitDiffWorker) diff(ctx context.Context) error { var err error shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) sdw.destinationSchemaDefinition, err = sdw.wr.GetSchema( - shortCtx, sdw.destinationAlias, nil /* tables */ , sdw.excludeTables, false /* includeViews */) + shortCtx, sdw.destinationAlias, nil /* tables */, sdw.excludeTables, false /* includeViews */) cancel() rec.RecordError(err) sdw.wr.Logger().Infof("Got schema from destination %v", sdw.destinationAlias) @@ -381,7 +381,7 @@ func (sdw *SplitDiffWorker) diff(ctx context.Context) error { var err error shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) sdw.sourceSchemaDefinition, err = sdw.wr.GetSchema( - shortCtx, sdw.sourceAlias, nil /* tables */ , sdw.excludeTables, false /* includeViews */) + shortCtx, sdw.sourceAlias, nil /* tables */, sdw.excludeTables, false /* includeViews */) cancel() rec.RecordError(err) sdw.wr.Logger().Infof("Got schema from source %v", sdw.sourceAlias) diff --git a/go/vt/worker/vertical_split_diff.go b/go/vt/worker/vertical_split_diff.go index a11026fb523..71616408f2f 100644 --- a/go/vt/worker/vertical_split_diff.go +++ b/go/vt/worker/vertical_split_diff.go @@ -63,11 +63,11 @@ type VerticalSplitDiffWorker struct { // NewVerticalSplitDiffWorker returns a new VerticalSplitDiffWorker object. func NewVerticalSplitDiffWorker(wr *wrangler.Wrangler, cell, keyspace, shard string, minHealthyRdonlyTablets, parallelDiffsCount int) Worker { return &VerticalSplitDiffWorker{ - StatusWorker: NewStatusWorker(), - wr: wr, - cell: cell, - keyspace: keyspace, - shard: shard, + StatusWorker: NewStatusWorker(), + wr: wr, + cell: cell, + keyspace: keyspace, + shard: shard, minHealthyRdonlyTablets: minHealthyRdonlyTablets, parallelDiffsCount: parallelDiffsCount, cleaner: &wrangler.Cleaner{}, @@ -206,13 +206,13 @@ func (vsdw *VerticalSplitDiffWorker) findTargets(ctx context.Context) error { // find an appropriate tablet in destination shard var err error - vsdw.destinationAlias, err = FindWorkerTablet(ctx, vsdw.wr, vsdw.cleaner, nil /* tsc */ , vsdw.cell, vsdw.keyspace, vsdw.shard, vsdw.minHealthyRdonlyTablets) + vsdw.destinationAlias, err = FindWorkerTablet(ctx, vsdw.wr, vsdw.cleaner, nil /* tsc */, vsdw.cell, vsdw.keyspace, vsdw.shard, vsdw.minHealthyRdonlyTablets) if err != nil { return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", vsdw.cell, vsdw.keyspace, vsdw.shard, err) } // find an appropriate tablet in the source shard - vsdw.sourceAlias, err = FindWorkerTablet(ctx, vsdw.wr, vsdw.cleaner, nil /* tsc */ , vsdw.cell, vsdw.shardInfo.SourceShards[0].Keyspace, vsdw.shardInfo.SourceShards[0].Shard, vsdw.minHealthyRdonlyTablets) + vsdw.sourceAlias, err = FindWorkerTablet(ctx, vsdw.wr, vsdw.cleaner, nil /* tsc */, vsdw.cell, vsdw.shardInfo.SourceShards[0].Keyspace, vsdw.shardInfo.SourceShards[0].Shard, vsdw.minHealthyRdonlyTablets) if err != nil { return fmt.Errorf("FindWorkerTablet() failed for %v/%v/%v: %v", vsdw.cell, vsdw.shardInfo.SourceShards[0].Keyspace, vsdw.shardInfo.SourceShards[0].Shard, err) } @@ -349,7 +349,7 @@ func (vsdw *VerticalSplitDiffWorker) diff(ctx context.Context) error { var err error shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) vsdw.destinationSchemaDefinition, err = vsdw.wr.GetSchema( - shortCtx, vsdw.destinationAlias, vsdw.shardInfo.SourceShards[0].Tables, nil /* excludeTables */ , false /* includeViews */) + shortCtx, vsdw.destinationAlias, vsdw.shardInfo.SourceShards[0].Tables, nil /* excludeTables */, false /* includeViews */) cancel() rec.RecordError(err) vsdw.wr.Logger().Infof("Got schema from destination %v", topoproto.TabletAliasString(vsdw.destinationAlias)) @@ -360,7 +360,7 @@ func (vsdw *VerticalSplitDiffWorker) diff(ctx context.Context) error { var err error shortCtx, cancel := context.WithTimeout(ctx, *remoteActionsTimeout) vsdw.sourceSchemaDefinition, err = vsdw.wr.GetSchema( - shortCtx, vsdw.sourceAlias, vsdw.shardInfo.SourceShards[0].Tables, nil /* excludeTables */ , false /* includeViews */) + shortCtx, vsdw.sourceAlias, vsdw.shardInfo.SourceShards[0].Tables, nil /* excludeTables */, false /* includeViews */) cancel() rec.RecordError(err) vsdw.wr.Logger().Infof("Got schema from source %v", topoproto.TabletAliasString(vsdw.sourceAlias)) diff --git a/go/vt/worker/worker.go b/go/vt/worker/worker.go index bec1083785a..aed603e4e10 100644 --- a/go/vt/worker/worker.go +++ b/go/vt/worker/worker.go @@ -59,57 +59,57 @@ var ( statsState = stats.NewString("WorkerState") statsRetryCount = stats.NewCounter("WorkerRetryCount", "Total number of times a query to a vttablet had to be retried") - statsRetryCounters = stats.NewCountersWithLabels("WorkerRetryCounters", "Number of retries grouped by category e.g. TimeoutError or ReadOnly", "category") + statsRetryCounters = stats.NewCountersWithSingleLabel("WorkerRetryCounters", "Number of retries grouped by category e.g. TimeoutError or ReadOnly", "category") statsThrottledCounters = stats.NewCountersWithMultiLabels( "WorkerThrottledCounters", `Number of times a write has been throttled grouped by (keyspace, shard, threadID). Mainly used for testing. If throttling is enabled this should always be non-zero for all threads`, []string{"Keyspace", "ShardName", "ThreadId"}) - statsStateDurationsNs = stats.NewGaugesWithLabels("WorkerStateDurations", "How much time was spent in each state. Mainly used for testing.", "state") + statsStateDurationsNs = stats.NewGaugesWithSingleLabel("WorkerStateDurations", "How much time was spent in each state. Mainly used for testing.", "state") - statsOnlineInsertsCounters = stats.NewCountersWithLabels( + statsOnlineInsertsCounters = stats.NewCountersWithSingleLabel( "WorkerOnlineInsertsCounters", "For every table how many rows were inserted during the online clone (reconciliation) phase", "table") - statsOnlineUpdatesCounters = stats.NewCountersWithLabels( + statsOnlineUpdatesCounters = stats.NewCountersWithSingleLabel( "WorkerOnlineUpdatesCounters", "For every table how many rows were updated", "table") - statsOnlineDeletesCounters = stats.NewCountersWithLabels( + statsOnlineDeletesCounters = stats.NewCountersWithSingleLabel( "WorkerOnlineDeletesCounters", "For every table how many rows were deleted", "table") - statsOnlineEqualRowsCounters = stats.NewCountersWithLabels( + statsOnlineEqualRowsCounters = stats.NewCountersWithSingleLabel( "WorkerOnlineEqualRowsCounters", "For every table how many rows were equal", "table") - statsOfflineInsertsCounters = stats.NewCountersWithLabels( + statsOfflineInsertsCounters = stats.NewCountersWithSingleLabel( "WorkerOfflineInsertsCounters", "For every table how many rows were inserted during the online clone (reconciliation) phase", "table") - statsOfflineUpdatesCounters = stats.NewCountersWithLabels( + statsOfflineUpdatesCounters = stats.NewCountersWithSingleLabel( "WorkerOfflineUpdatesCounters", "For every table how many rows were updated", "table") - statsOfflineDeletesCounters = stats.NewCountersWithLabels( + statsOfflineDeletesCounters = stats.NewCountersWithSingleLabel( "WorkerOfflineDeletesCounters", "For every table how many rows were deleted", "table") - statsOfflineEqualRowsCounters = stats.NewCountersWithLabels( + statsOfflineEqualRowsCounters = stats.NewCountersWithSingleLabel( "WorkerOfflineEqualRowsCounters", "For every table how many rows were equal", "table") - statsStreamingQueryCounters = stats.NewCountersWithLabels( + statsStreamingQueryCounters = stats.NewCountersWithSingleLabel( "StreamingQueryCounters", "For every tablet alias how often a streaming query was successfully established there", "tablet_alias") - statsStreamingQueryErrorsCounters = stats.NewCountersWithLabels( + statsStreamingQueryErrorsCounters = stats.NewCountersWithSingleLabel( "StreamingQueryErrorsCounters", "For every tablet alias how often a (previously successfully established) streaming query did error", "tablet_alias") - statsStreamingQueryRestartsSameTabletCounters = stats.NewCountersWithLabels( + statsStreamingQueryRestartsSameTabletCounters = stats.NewCountersWithSingleLabel( "StreamingQueryRestartsSameTabletCounters", `For every tablet alias how often we successfully restarted a streaming query on the first retry. This kind of restart is usually necessary when our streaming query is idle and MySQL aborts it after a timeout.`, diff --git a/helm/vitess/templates/_vtgate.tpl b/helm/vitess/templates/_vtgate.tpl index 7699c061f13..f0acf0644ff 100644 --- a/helm/vitess/templates/_vtgate.tpl +++ b/helm/vitess/templates/_vtgate.tpl @@ -138,7 +138,8 @@ spec: component: vtgate cell: {{ $cellClean }} -{{ if gt .maxReplicas .replicas }} +{{ $maxReplicas := .maxReplicas | default .replicas }} +{{ if gt $maxReplicas .replicas }} ################################### # optional HPA for vtgate ################################### @@ -153,7 +154,7 @@ spec: kind: Deployment name: vtgate-{{ $cellClean }} minReplicas: {{ .replicas }} - maxReplicas: {{ .maxReplicas }} + maxReplicas: {{ $maxReplicas }} metrics: - type: Resource resource: diff --git a/helm/vitess/templates/_vttablet.tpl b/helm/vitess/templates/_vttablet.tpl index 37a8d48d134..751b110b225 100644 --- a/helm/vitess/templates/_vttablet.tpl +++ b/helm/vitess/templates/_vttablet.tpl @@ -194,7 +194,7 @@ spec: fi # check for a master tablet from the GetShard call - master_alias=$(vtctlclient -server $VTCTLD_SVC GetShard {{ $keyspaceClean }}/{{ $shard.name }} | jq '.master_alias.uid') + master_alias=$(vtctlclient -server $VTCTLD_SVC GetShard {{ $keyspace.name }}/{{ $shard.name }} | jq '.master_alias.uid') if [ $master_alias != "null" ]; then echo "'$master_alias' is already the master tablet, exiting without running InitShardMaster" exit @@ -222,7 +222,7 @@ spec: tablet_id=$( echo "$shardTablets" | awk 'substr( $5,1,{{ add (len $shardName) 10 }} ) == "{{ $shardName }}-replica-0" {print $1}') # initialize the shard master - until vtctlclient -server $VTCTLD_SVC InitShardMaster -force {{ $keyspaceClean }}/{{ $shard.name }} $tablet_id; do + until vtctlclient -server $VTCTLD_SVC InitShardMaster -force {{ $keyspace.name }}/{{ $shard.name }} $tablet_id; do if (( $SECONDS > $TIMEOUT_SECONDS )); then echo "timed out waiting for InitShardMaster to succeed" exit 1 diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java index 9b0a347cbb6..2c69fa0ef32 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessPreparedStatement.java @@ -19,6 +19,7 @@ import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; +import java.math.BigInteger; import java.net.URL; import java.sql.Array; import java.sql.Blob; @@ -247,6 +248,11 @@ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException this.bindVariables.put(Constants.LITERAL_V + parameterIndex, x); } + public void setBigInteger(int parameterIndex, BigInteger x) throws SQLException { + checkOpen(); + this.bindVariables.put(Constants.LITERAL_V + parameterIndex, x); + } + public void setString(int parameterIndex, String x) throws SQLException { checkOpen(); this.bindVariables.put(Constants.LITERAL_V + parameterIndex, x); @@ -322,6 +328,8 @@ public void setObject(int parameterIndex, Object x) throws SQLException { setTimestamp(parameterIndex, (Timestamp) x); } else if (x instanceof BigDecimal) { setBigDecimal(parameterIndex, (BigDecimal) x); + } else if (x instanceof BigInteger) { + setBigInteger(parameterIndex, (BigInteger) x); } else if (x instanceof byte[]) { setBytes(parameterIndex, (byte[]) x); } else if (getConnection().getTreatUtilDateAsTimestamp() && x instanceof java.util.Date) { @@ -890,8 +898,7 @@ private void setNumericObject(int parameterIndex, Object parameterObj, int targe } setBigDecimal(parameterIndex, scaledBigDecimal); } else if (numberParam instanceof java.math.BigInteger) { - setBigDecimal(parameterIndex, - new java.math.BigDecimal((java.math.BigInteger) numberParam, scale)); + setBigInteger(parameterIndex, (BigInteger) numberParam); } else { setBigDecimal(parameterIndex, new java.math.BigDecimal(numberParam.doubleValue())); diff --git a/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java b/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java index 6825265d0a2..c2c28e19484 100644 --- a/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java +++ b/java/jdbc/src/main/java/io/vitess/jdbc/VitessResultSet.java @@ -16,13 +16,12 @@ package io.vitess.jdbc; -import com.google.common.annotations.VisibleForTesting; -import com.google.protobuf.ByteString; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.Reader; import java.io.UnsupportedEncodingException; import java.math.BigDecimal; +import java.math.BigInteger; import java.net.URL; import java.sql.Array; import java.sql.Blob; @@ -46,8 +45,12 @@ import java.util.List; import java.util.Map; import java.util.logging.Logger; + import javax.sql.rowset.serial.SerialClob; +import com.google.common.annotations.VisibleForTesting; +import com.google.protobuf.ByteString; + import io.vitess.client.cursor.Cursor; import io.vitess.client.cursor.Row; import io.vitess.client.cursor.SimpleCursor; @@ -428,6 +431,27 @@ public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException return value; } + public BigInteger getBigInteger(int columnIndex) throws SQLException { + String bigIntegerString; + BigInteger value; + + preAccessor(columnIndex); + + if (isNull(columnIndex)) { + return null; + } + + bigIntegerString = this.getString(columnIndex); + + try { + value = new BigInteger(bigIntegerString); + } catch (Exception ex) { + throw new SQLException(ex); + } + + return value; + } + public byte[] getBytes(int columnIndex) throws SQLException { String bytesString; byte[] value; @@ -528,6 +552,11 @@ public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLExcepti return getBigDecimal(columnIndex, scale); } + public BigInteger getBigInteger(String columnLabel) throws SQLException { + int columnIndex = this.findColumn(columnLabel); + return getBigInteger(columnIndex); + } + public byte[] getBytes(String columnLabel) throws SQLException { int columnIndex = this.findColumn(columnLabel); return getBytes(columnIndex); diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java index 6005dc4e665..31b7356f1f0 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessPreparedStatementTest.java @@ -16,9 +16,9 @@ package io.vitess.jdbc; -import com.google.common.collect.ImmutableMap; import java.lang.reflect.Field; import java.math.BigDecimal; +import java.math.BigInteger; import java.sql.BatchUpdateException; import java.sql.Date; import java.sql.ResultSet; @@ -32,7 +32,9 @@ import java.util.List; import java.util.Map; import java.util.TimeZone; + import javax.sql.rowset.serial.SerialClob; + import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -42,6 +44,8 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import com.google.common.collect.ImmutableMap; + import io.vitess.client.Context; import io.vitess.client.SQLFuture; import io.vitess.client.VTGateConnection; @@ -456,6 +460,7 @@ private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRun Double doubleValue = Double.MAX_VALUE; BigDecimal bigDecimalValue = new BigDecimal(3.14159265358979323846); BigDecimal expectedDecimalValue = new BigDecimal("3.14159"); + BigInteger bigIntegerValue = new BigInteger("18446744073709551615"); String stringValue = "vitess"; byte[] bytesValue = stringValue.getBytes(); Date dateValue = new Date(0); @@ -473,41 +478,43 @@ private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRun preparedStatement.setFloat(7, floatValue); preparedStatement.setDouble(8, doubleValue); preparedStatement.setBigDecimal(9, bigDecimalValue); - preparedStatement.setString(10, stringValue); - preparedStatement.setBytes(11, bytesValue); - preparedStatement.setDate(12, dateValue); - preparedStatement.setTime(13, timeValue); - preparedStatement.setTimestamp(14, timestampValue); - preparedStatement.setDate(15, dateValue, Calendar.getInstance(TimeZone.getDefault())); - preparedStatement.setTime(16, timeValue, Calendar.getInstance(TimeZone.getDefault())); + preparedStatement.setBigInteger(10, bigIntegerValue); + preparedStatement.setString(11, stringValue); + preparedStatement.setBytes(12, bytesValue); + preparedStatement.setDate(13, dateValue); + preparedStatement.setTime(14, timeValue); + preparedStatement.setTimestamp(15, timestampValue); + preparedStatement.setDate(16, dateValue, Calendar.getInstance(TimeZone.getDefault())); + preparedStatement.setTime(17, timeValue, Calendar.getInstance(TimeZone.getDefault())); preparedStatement - .setTimestamp(17, timestampValue, Calendar.getInstance(TimeZone.getDefault())); - preparedStatement.setObject(18, boolValue); - preparedStatement.setObject(19, byteValue); - preparedStatement.setObject(20, shortValue); - preparedStatement.setObject(21, intValue); - preparedStatement.setObject(22, longValue); - preparedStatement.setObject(23, floatValue); - preparedStatement.setObject(24, doubleValue); - preparedStatement.setObject(25, bigDecimalValue); - preparedStatement.setObject(26, stringValue); - preparedStatement.setObject(27, dateValue); - preparedStatement.setObject(28, timeValue); - preparedStatement.setObject(29, timestampValue); - preparedStatement.setObject(30, 'a'); - preparedStatement.setObject(31, null); - preparedStatement.setObject(32, boolValue, Types.BOOLEAN, 0); - preparedStatement.setObject(33, shortValue, Types.SMALLINT, 0); - preparedStatement.setObject(34, longValue, Types.BIGINT, 0); - preparedStatement.setObject(35, floatValue, Types.DOUBLE, 2); - preparedStatement.setObject(36, doubleValue, Types.DOUBLE, 3); - preparedStatement.setObject(37, bigDecimalValue, Types.DECIMAL, 5); - preparedStatement.setObject(38, stringValue, Types.VARCHAR, 0); - preparedStatement.setObject(39, dateValue, Types.DATE, 0); - preparedStatement.setObject(40, timeValue, Types.TIME, 0); - preparedStatement.setObject(41, timestampValue, Types.TIMESTAMP, 0); - preparedStatement.setClob(42, new SerialClob("clob".toCharArray())); - preparedStatement.setObject(43, bytesValue); + .setTimestamp(18, timestampValue, Calendar.getInstance(TimeZone.getDefault())); + preparedStatement.setObject(19, boolValue); + preparedStatement.setObject(20, byteValue); + preparedStatement.setObject(21, shortValue); + preparedStatement.setObject(22, intValue); + preparedStatement.setObject(23, longValue); + preparedStatement.setObject(24, floatValue); + preparedStatement.setObject(25, doubleValue); + preparedStatement.setObject(26, bigDecimalValue); + preparedStatement.setObject(27, bigIntegerValue); + preparedStatement.setObject(28, stringValue); + preparedStatement.setObject(29, dateValue); + preparedStatement.setObject(30, timeValue); + preparedStatement.setObject(31, timestampValue); + preparedStatement.setObject(32, 'a'); + preparedStatement.setObject(33, null); + preparedStatement.setObject(34, boolValue, Types.BOOLEAN, 0); + preparedStatement.setObject(35, shortValue, Types.SMALLINT, 0); + preparedStatement.setObject(36, longValue, Types.BIGINT, 0); + preparedStatement.setObject(37, floatValue, Types.DOUBLE, 2); + preparedStatement.setObject(38, doubleValue, Types.DOUBLE, 3); + preparedStatement.setObject(39, bigDecimalValue, Types.DECIMAL, 5); + preparedStatement.setObject(40, stringValue, Types.VARCHAR, 0); + preparedStatement.setObject(41, dateValue, Types.DATE, 0); + preparedStatement.setObject(42, timeValue, Types.TIME, 0); + preparedStatement.setObject(43, timestampValue, Types.TIMESTAMP, 0); + preparedStatement.setClob(44, new SerialClob("clob".toCharArray())); + preparedStatement.setObject(45, bytesValue); Field bindVariablesMap = preparedStatement.getClass().getDeclaredField("bindVariables"); bindVariablesMap.setAccessible(true); Map bindVariables = @@ -521,40 +528,42 @@ private void testExecute(int fetchSize, boolean simpleExecute, boolean shouldRun Assert.assertEquals(floatValue, bindVariables.get("v7")); Assert.assertEquals(doubleValue, bindVariables.get("v8")); Assert.assertEquals(bigDecimalValue, bindVariables.get("v9")); - Assert.assertEquals(stringValue, bindVariables.get("v10")); - Assert.assertEquals(bytesValue, bindVariables.get("v11")); - Assert.assertEquals(dateValue.toString(), bindVariables.get("v12")); - Assert.assertEquals(timeValue.toString(), bindVariables.get("v13")); - Assert.assertEquals(timestampValue.toString(), bindVariables.get("v14")); - Assert.assertEquals(dateValue.toString(), bindVariables.get("v15")); - Assert.assertEquals(timeValue.toString(), bindVariables.get("v16")); - Assert.assertEquals(timestampValue.toString(), bindVariables.get("v17")); - Assert.assertEquals(boolValue, bindVariables.get("v18")); - Assert.assertEquals(byteValue, bindVariables.get("v19")); - Assert.assertEquals(shortValue, bindVariables.get("v20")); - Assert.assertEquals(intValue, bindVariables.get("v21")); - Assert.assertEquals(longValue, bindVariables.get("v22")); - Assert.assertEquals(floatValue, bindVariables.get("v23")); - Assert.assertEquals(doubleValue, bindVariables.get("v24")); - Assert.assertEquals(bigDecimalValue, bindVariables.get("v25")); - Assert.assertEquals(stringValue, bindVariables.get("v26")); - Assert.assertEquals(dateValue.toString(), bindVariables.get("v27")); - Assert.assertEquals(timeValue.toString(), bindVariables.get("v28")); - Assert.assertEquals(timestampValue.toString(), bindVariables.get("v29")); - Assert.assertEquals("a", bindVariables.get("v30")); - Assert.assertEquals(null, bindVariables.get("v31")); - Assert.assertEquals(boolValue, bindVariables.get("v32")); - Assert.assertEquals(shortValue.intValue(), bindVariables.get("v33")); - Assert.assertEquals(longValue, bindVariables.get("v34")); - Assert.assertEquals((double) floatValue, (double) bindVariables.get("v35"), 0.1); - Assert.assertEquals(doubleValue, (double) bindVariables.get("v36"), 0.1); - Assert.assertEquals(expectedDecimalValue, bindVariables.get("v37")); - Assert.assertEquals(stringValue, bindVariables.get("v38")); - Assert.assertEquals(dateValue.toString(), bindVariables.get("v39")); - Assert.assertEquals(timeValue.toString(), bindVariables.get("v40")); - Assert.assertEquals(timestampValue.toString(), bindVariables.get("v41")); - Assert.assertEquals("clob", bindVariables.get("v42")); - Assert.assertArrayEquals(bytesValue, (byte[])bindVariables.get("v43")); + Assert.assertEquals(bigIntegerValue, bindVariables.get("v10")); + Assert.assertEquals(stringValue, bindVariables.get("v11")); + Assert.assertEquals(bytesValue, bindVariables.get("v12")); + Assert.assertEquals(dateValue.toString(), bindVariables.get("v13")); + Assert.assertEquals(timeValue.toString(), bindVariables.get("v14")); + Assert.assertEquals(timestampValue.toString(), bindVariables.get("v15")); + Assert.assertEquals(dateValue.toString(), bindVariables.get("v16")); + Assert.assertEquals(timeValue.toString(), bindVariables.get("v17")); + Assert.assertEquals(timestampValue.toString(), bindVariables.get("v18")); + Assert.assertEquals(boolValue, bindVariables.get("v19")); + Assert.assertEquals(byteValue, bindVariables.get("v20")); + Assert.assertEquals(shortValue, bindVariables.get("v21")); + Assert.assertEquals(intValue, bindVariables.get("v22")); + Assert.assertEquals(longValue, bindVariables.get("v23")); + Assert.assertEquals(floatValue, bindVariables.get("v24")); + Assert.assertEquals(doubleValue, bindVariables.get("v25")); + Assert.assertEquals(bigDecimalValue, bindVariables.get("v26")); + Assert.assertEquals(bigIntegerValue, bindVariables.get("v27")); + Assert.assertEquals(stringValue, bindVariables.get("v28")); + Assert.assertEquals(dateValue.toString(), bindVariables.get("v29")); + Assert.assertEquals(timeValue.toString(), bindVariables.get("v30")); + Assert.assertEquals(timestampValue.toString(), bindVariables.get("v31")); + Assert.assertEquals("a", bindVariables.get("v32")); + Assert.assertEquals(null, bindVariables.get("v33")); + Assert.assertEquals(boolValue, bindVariables.get("v34")); + Assert.assertEquals(shortValue.intValue(), bindVariables.get("v35")); + Assert.assertEquals(longValue, bindVariables.get("v36")); + Assert.assertEquals((double) floatValue, (double) bindVariables.get("v37"), 0.1); + Assert.assertEquals(doubleValue, (double) bindVariables.get("v38"), 0.1); + Assert.assertEquals(expectedDecimalValue, bindVariables.get("v39")); + Assert.assertEquals(stringValue, bindVariables.get("v40")); + Assert.assertEquals(dateValue.toString(), bindVariables.get("v41")); + Assert.assertEquals(timeValue.toString(), bindVariables.get("v42")); + Assert.assertEquals(timestampValue.toString(), bindVariables.get("v43")); + Assert.assertEquals("clob", bindVariables.get("v44")); + Assert.assertArrayEquals(bytesValue, (byte[])bindVariables.get("v45")); preparedStatement.clearParameters(); } diff --git a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java index f31de052f5a..726398de68a 100644 --- a/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java +++ b/java/jdbc/src/test/java/io/vitess/jdbc/VitessResultSetTest.java @@ -16,7 +16,6 @@ package io.vitess.jdbc; -import com.google.protobuf.ByteString; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; @@ -27,6 +26,7 @@ import java.sql.Time; import java.sql.Timestamp; import java.util.Properties; + import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,6 +36,8 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import com.google.protobuf.ByteString; + import io.vitess.client.cursor.Cursor; import io.vitess.client.cursor.SimpleCursor; import io.vitess.proto.Query; @@ -266,6 +268,14 @@ public Cursor getCursorWithRowsAsNull() { Assert.assertEquals(new BigInteger("1000"), vitessResultSet.getObject(10)); } + @Test public void getBigInteger() throws SQLException { + Cursor cursor = getCursorWithRowsAsNull(); + VitessResultSet vitessResultSet = new VitessResultSet(cursor, getVitessStatement()); + vitessResultSet.next(); + + Assert.assertEquals(new BigInteger("1000"), vitessResultSet.getBigInteger(10)); + } + @Test public void testgetBoolean() throws SQLException { Cursor cursor = getCursorWithRows(); Cursor cursorWithRowsAsNull = getCursorWithRowsAsNull(); @@ -448,6 +458,14 @@ public Cursor getCursorWithRowsAsNull() { Assert.assertEquals(-1000, vitessResultSet.getInt("col9")); } + @Test public void testBigIntegerbyColumnLabel() throws SQLException { + Cursor cursor = getCursorWithRows(); + VitessResultSet vitessResultSet = new VitessResultSet(cursor, getVitessStatement()); + vitessResultSet.next(); + Assert.assertEquals(new BigInteger("1000"), + vitessResultSet.getBigInteger("col10")); + } + @Test public void testgetFloatbyColumnLabel() throws SQLException { Cursor cursor = getCursorWithRows(); VitessResultSet vitessResultSet = new VitessResultSet(cursor, getVitessStatement()); diff --git a/vitess.io/images/users/jd.jpg b/vitess.io/images/users/jd.jpg new file mode 100644 index 00000000000..affd8ad4ec3 Binary files /dev/null and b/vitess.io/images/users/jd.jpg differ diff --git a/vitess.io/index.md b/vitess.io/index.md index 4ccbc79aae8..161d31bd208 100644 --- a/vitess.io/index.md +++ b/vitess.io/index.md @@ -60,21 +60,24 @@ Slack and Nozzle are swapped for aesthetics, because the icons don't align well Hubspot
- Slack + JD
+
+ Slack +
Pixel Federation
Quiz of Kings
+
+
Nozzle
-
-
Square