From b7400d43f5b1affedb9cf9cdb4f7f82f5f9ee670 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 26 Jan 2021 07:56:49 +0100 Subject: [PATCH 01/23] Start of making CREATE DATABASE pluggable Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/builder.go | 2 +- .../planbuilder/create_database_pluggable.go | 36 +++++++++++ .../create_database_pluggable_test.go | 59 +++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 go/vt/vtgate/planbuilder/create_database_pluggable.go create mode 100644 go/vt/vtgate/planbuilder/create_database_pluggable_test.go diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 3575425dd23..272a3079254 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -198,7 +198,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !dbDDL.IfNotExists && ksExists { return nil, vterrors.Errorf(vtrpcpb.Code_ALREADY_EXISTS, "cannot create database '%s'; database exists", ksName) } - return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database not allowed") + return databaseCreator(dbDDL, vschema) } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unreachable code path: %s", sqlparser.String(dbDDLstmt)) } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable.go b/go/vt/vtgate/planbuilder/create_database_pluggable.go new file mode 100644 index 00000000000..25c6da7bcf4 --- /dev/null +++ b/go/vt/vtgate/planbuilder/create_database_pluggable.go @@ -0,0 +1,36 @@ +/* +Copyright 2021 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 planbuilder + +import ( + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vtgate/engine" +) + +// PlanFunc is the function signature that you need to implement to add a custom CREATE DATABASE handler +type PlanFunc = func(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Primitive, error) + +var databaseCreator = defaultCreateDatabase + +//goland:noinspection GoVarAndConstTypeMayBeOmitted +var _ PlanFunc = databaseCreator + +func defaultCreateDatabase(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Primitive, error) { + return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database not allowed") +} diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go new file mode 100644 index 00000000000..83e4e68e0e0 --- /dev/null +++ b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go @@ -0,0 +1,59 @@ +/* +Copyright 2021 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 planbuilder + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/vt/sqlparser" + "vitess.io/vitess/go/vt/vtgate/engine" + + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +func TestCreateDB(t *testing.T) { + ks := &vindexes.Keyspace{Name: "main"} + vschema := &vschemaWrapper{ + v: &vindexes.VSchema{ + Keyspaces: map[string]*vindexes.KeyspaceSchema{"main": {Keyspace: ks}}, + }, + keyspace: ks, + } + + // default behaviour + _, err := TestBuilder("create database test", vschema) + require.EqualError(t, err, "create database not allowed") + + // we make sure to restore the state so we don't destabilize other tests + before := databaseCreator + defer func() { + databaseCreator = before + }() + + // setting custom behaviour for CREATE DATABASE + s := &engine.SingleRow{} + databaseCreator = func(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Primitive, error) { + return s, nil + } + + output, err := TestBuilder("create database test", vschema) + require.NoError(t, err) + assert.Same(t, s, output.Instructions) +} From f85d458062fc4643a432d55a5a7fca6958fd1b07 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 26 Jan 2021 08:14:50 +0100 Subject: [PATCH 02/23] use more restrictive type Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/create_database_pluggable.go | 4 ++-- go/vt/vtgate/planbuilder/create_database_pluggable_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable.go b/go/vt/vtgate/planbuilder/create_database_pluggable.go index 25c6da7bcf4..911bfa32ec8 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable.go +++ b/go/vt/vtgate/planbuilder/create_database_pluggable.go @@ -24,13 +24,13 @@ import ( ) // PlanFunc is the function signature that you need to implement to add a custom CREATE DATABASE handler -type PlanFunc = func(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Primitive, error) +type PlanFunc = func(stmt *sqlparser.CreateDatabase, vschema ContextVSchema) (engine.Primitive, error) var databaseCreator = defaultCreateDatabase //goland:noinspection GoVarAndConstTypeMayBeOmitted var _ PlanFunc = databaseCreator -func defaultCreateDatabase(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Primitive, error) { +func defaultCreateDatabase(_ *sqlparser.CreateDatabase, _ ContextVSchema) (engine.Primitive, error) { return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database not allowed") } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go index 83e4e68e0e0..ca740bc330c 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go +++ b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go @@ -49,7 +49,7 @@ func TestCreateDB(t *testing.T) { // setting custom behaviour for CREATE DATABASE s := &engine.SingleRow{} - databaseCreator = func(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Primitive, error) { + databaseCreator = func(stmt *sqlparser.CreateDatabase, vschema ContextVSchema) (engine.Primitive, error) { return s, nil } From 768719ef07eedc5f69c3d1b47ad68a8a7856ff37 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 26 Jan 2021 13:51:20 +0100 Subject: [PATCH 03/23] use simpler API for the CREATE DB API Signed-off-by: Andres Taylor --- go/vt/vtgate/engine/create_database.go | 81 +++++++++++++++++++ go/vt/vtgate/planbuilder/builder.go | 5 +- .../planbuilder/create_database_pluggable.go | 14 ++-- .../create_database_pluggable_test.go | 19 +++-- .../vtgate/planbuilder/testdata/ddl_cases.txt | 12 ++- 5 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 go/vt/vtgate/engine/create_database.go diff --git a/go/vt/vtgate/engine/create_database.go b/go/vt/vtgate/engine/create_database.go new file mode 100644 index 00000000000..28df7295f72 --- /dev/null +++ b/go/vt/vtgate/engine/create_database.go @@ -0,0 +1,81 @@ +/* +Copyright 2020 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 engine + +import ( + "vitess.io/vitess/go/sqltypes" + querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/vtgate/vindexes" +) + +var _ Primitive = (*CreateDatabase)(nil) + +// CreateDatabase is just a container around custom database provisioning plugins +// the default behaviour is to just return an error +type CreateDatabase struct { + Name string + DoIt func(dbName string) error + noInputs + noTxNeeded +} + +// RouteType implements the Primitive interface +func (c *CreateDatabase) RouteType() string { + return "create database" +} + +// GetKeyspaceName implements the Primitive interface +func (c *CreateDatabase) GetKeyspaceName() string { + return c.Name +} + +// GetTableName implements the Primitive interface +func (c *CreateDatabase) GetTableName() string { + return "" +} + +// Execute implements the Primitive interface +func (c *CreateDatabase) Execute(VCursor, map[string]*querypb.BindVariable, bool) (*sqltypes.Result, error) { + err := c.DoIt(c.Name) + if err != nil { + return nil, err + } + + return &sqltypes.Result{}, nil +} + +// StreamExecute implements the Primitive interface +func (c *CreateDatabase) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { + res, err := c.Execute(vcursor, bindVars, wantfields) + if err != nil { + return err + } + return callback(res) +} + +// GetFields implements the Primitive interface +func (c *CreateDatabase) GetFields(VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { + return &sqltypes.Result{}, nil +} + +// description implements the Primitive interface +func (c *CreateDatabase) description() PrimitiveDescription { + return PrimitiveDescription{ + OperatorType: "CREATE DATABASE", + Keyspace: &vindexes.Keyspace{Name: c.Name}, + } +} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index 272a3079254..8dd511edce7 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -198,7 +198,10 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !dbDDL.IfNotExists && ksExists { return nil, vterrors.Errorf(vtrpcpb.Code_ALREADY_EXISTS, "cannot create database '%s'; database exists", ksName) } - return databaseCreator(dbDDL, vschema) + return &engine.CreateDatabase{ + Name: dbDDL.DBName, + DoIt: databaseCreator, + }, nil } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unreachable code path: %s", sqlparser.String(dbDDLstmt)) } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable.go b/go/vt/vtgate/planbuilder/create_database_pluggable.go index 911bfa32ec8..5a49426ea9e 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable.go +++ b/go/vt/vtgate/planbuilder/create_database_pluggable.go @@ -18,19 +18,15 @@ package planbuilder import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vtgate/engine" ) -// PlanFunc is the function signature that you need to implement to add a custom CREATE DATABASE handler -type PlanFunc = func(stmt *sqlparser.CreateDatabase, vschema ContextVSchema) (engine.Primitive, error) - -var databaseCreator = defaultCreateDatabase +// CreateDatabasePlug is the function signature that you need to implement to add a custom CREATE DATABASE handler +type CreateDatabasePlug = func(name string) error //goland:noinspection GoVarAndConstTypeMayBeOmitted -var _ PlanFunc = databaseCreator +var databaseCreator CreateDatabasePlug = defaultCreateDatabase -func defaultCreateDatabase(_ *sqlparser.CreateDatabase, _ ContextVSchema) (engine.Primitive, error) { - return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database not allowed") +func defaultCreateDatabase(_ string) error { + return vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database not allowed") } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go index ca740bc330c..bec32bdf570 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go +++ b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go @@ -19,12 +19,8 @@ package planbuilder import ( "testing" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "vitess.io/vitess/go/vt/sqlparser" - "vitess.io/vitess/go/vt/vtgate/engine" - "vitess.io/vitess/go/vt/vtgate/vindexes" ) @@ -38,7 +34,10 @@ func TestCreateDB(t *testing.T) { } // default behaviour - _, err := TestBuilder("create database test", vschema) + plan, err := TestBuilder("create database test", vschema) + require.NoError(t, err) + + _, err = plan.Instructions.Execute(nil, nil, true) require.EqualError(t, err, "create database not allowed") // we make sure to restore the state so we don't destabilize other tests @@ -48,12 +47,12 @@ func TestCreateDB(t *testing.T) { }() // setting custom behaviour for CREATE DATABASE - s := &engine.SingleRow{} - databaseCreator = func(stmt *sqlparser.CreateDatabase, vschema ContextVSchema) (engine.Primitive, error) { - return s, nil + databaseCreator = func(name string) error { + return nil } - output, err := TestBuilder("create database test", vschema) + plan, err = TestBuilder("create database test", vschema) + require.NoError(t, err) + _, err = plan.Instructions.Execute(nil, nil, true) require.NoError(t, err) - assert.Same(t, s, output.Instructions) } diff --git a/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt b/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt index a39136a186f..59ba0ef12d2 100644 --- a/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt @@ -98,7 +98,17 @@ # create db foo "create database foo" -"create database not allowed" +{ + "QueryType": "DDL", + "Original": "create database foo", + "Instructions": { + "OperatorType": "CREATE DATABASE", + "Keyspace": { + "Name": "foo", + "Sharded": false + } + } +} # create db main "create database main" From 668b66f86c71d5d624bb5bffc954c7cffa555727 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 22 Feb 2021 09:19:01 +0100 Subject: [PATCH 04/23] make it possible to do both create and drop using a plugin Signed-off-by: Andres Taylor --- go/vt/vtgate/engine/create_database.go | 47 ++++++++++++------- go/vt/vtgate/planbuilder/builder.go | 7 +-- .../planbuilder/create_database_pluggable.go | 22 +++++++-- .../create_database_pluggable_test.go | 18 +++++-- .../vtgate/planbuilder/testdata/ddl_cases.txt | 24 +++++++++- 5 files changed, 85 insertions(+), 33 deletions(-) diff --git a/go/vt/vtgate/engine/create_database.go b/go/vt/vtgate/engine/create_database.go index 28df7295f72..a11e5d6779d 100644 --- a/go/vt/vtgate/engine/create_database.go +++ b/go/vt/vtgate/engine/create_database.go @@ -17,40 +17,51 @@ limitations under the License. package engine import ( + "strings" + "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/vtgate/vindexes" ) -var _ Primitive = (*CreateDatabase)(nil) +var _ Primitive = (*DropCreateDatabase)(nil) -// CreateDatabase is just a container around custom database provisioning plugins -// the default behaviour is to just return an error -type CreateDatabase struct { - Name string - DoIt func(dbName string) error +// DropCreateDatabase is just a container around custom database provisioning plugins +// The default behaviour is to just return an error +type DropCreateDatabase struct { + name, verb string + plugin func() error noInputs noTxNeeded } +// CreateDropCreateDatabase creates the engine primitive +func CreateDropCreateDatabase(dbName, verb string, plugin func() error) *DropCreateDatabase { + return &DropCreateDatabase{ + name: dbName, + verb: verb, + plugin: plugin, + } +} + // RouteType implements the Primitive interface -func (c *CreateDatabase) RouteType() string { - return "create database" +func (c *DropCreateDatabase) RouteType() string { + return c.verb + " database" } // GetKeyspaceName implements the Primitive interface -func (c *CreateDatabase) GetKeyspaceName() string { - return c.Name +func (c *DropCreateDatabase) GetKeyspaceName() string { + return c.name } // GetTableName implements the Primitive interface -func (c *CreateDatabase) GetTableName() string { +func (c *DropCreateDatabase) GetTableName() string { return "" } // Execute implements the Primitive interface -func (c *CreateDatabase) Execute(VCursor, map[string]*querypb.BindVariable, bool) (*sqltypes.Result, error) { - err := c.DoIt(c.Name) +func (c *DropCreateDatabase) Execute(VCursor, map[string]*querypb.BindVariable, bool) (*sqltypes.Result, error) { + err := c.plugin() if err != nil { return nil, err } @@ -59,7 +70,7 @@ func (c *CreateDatabase) Execute(VCursor, map[string]*querypb.BindVariable, bool } // StreamExecute implements the Primitive interface -func (c *CreateDatabase) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (c *DropCreateDatabase) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { res, err := c.Execute(vcursor, bindVars, wantfields) if err != nil { return err @@ -68,14 +79,14 @@ func (c *CreateDatabase) StreamExecute(vcursor VCursor, bindVars map[string]*que } // GetFields implements the Primitive interface -func (c *CreateDatabase) GetFields(VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { +func (c *DropCreateDatabase) GetFields(VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { return &sqltypes.Result{}, nil } // description implements the Primitive interface -func (c *CreateDatabase) description() PrimitiveDescription { +func (c *DropCreateDatabase) description() PrimitiveDescription { return PrimitiveDescription{ - OperatorType: "CREATE DATABASE", - Keyspace: &vindexes.Keyspace{Name: c.Name}, + OperatorType: strings.ToUpper(c.verb + " DATABASE"), + Keyspace: &vindexes.Keyspace{Name: c.name}, } } diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index b9bb37823f5..144984fd236 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -208,7 +208,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !ksExists { return nil, mysql.NewSQLError(mysql.ERDbDropExists, mysql.SSUnknownSQLState, "Can't drop database '%s'; database doesn't exists", ksName) } - return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "drop database not allowed") + return engine.CreateDropCreateDatabase(dbDDL.DBName, "drop", func() error { return databaseCreator.DropDatabase(dbDDL) }), nil case *sqlparser.AlterDatabase: if !ksExists { return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "Can't alter database '%s'; database doesn't exists", ksName) @@ -221,10 +221,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !dbDDL.IfNotExists && ksExists { return nil, mysql.NewSQLError(mysql.ERDbCreateExists, mysql.SSUnknownSQLState, "Can't create database '%s'; database exists", ksName) } - return &engine.CreateDatabase{ - Name: dbDDL.DBName, - DoIt: databaseCreator, - }, nil + return engine.CreateDropCreateDatabase(dbDDL.DBName, "create", func() error { return databaseCreator.CreateDatabase(dbDDL) }), nil } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unreachable code path: %s", sqlparser.String(dbDDLstmt)) } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable.go b/go/vt/vtgate/planbuilder/create_database_pluggable.go index 5a49426ea9e..1dd32dc0a78 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable.go +++ b/go/vt/vtgate/planbuilder/create_database_pluggable.go @@ -18,15 +18,27 @@ package planbuilder import ( vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" ) -// CreateDatabasePlug is the function signature that you need to implement to add a custom CREATE DATABASE handler -type CreateDatabasePlug = func(name string) error +// DropCreateDB is the interface that you need to implement to add a custom CREATE/DROP DATABASE handler +type DropCreateDB interface { + CreateDatabase(ast *sqlparser.CreateDatabase) error + DropDatabase(ast *sqlparser.DropDatabase) error +} -//goland:noinspection GoVarAndConstTypeMayBeOmitted -var databaseCreator CreateDatabasePlug = defaultCreateDatabase +type defaultHandler struct{} -func defaultCreateDatabase(_ string) error { +// CreateDatabase implements the DropCreateDB interface +func (defaultHandler) CreateDatabase(*sqlparser.CreateDatabase) error { return vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database not allowed") } + +// DropDatabase implements the DropCreateDB interface +func (defaultHandler) DropDatabase(*sqlparser.DropDatabase) error { + return vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "drop database not allowed") +} + +//goland:noinspection GoVarAndConstTypeMayBeOmitted +var databaseCreator DropCreateDB = defaultHandler{} diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go index bec32bdf570..50dc23e950b 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go +++ b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go @@ -19,6 +19,8 @@ package planbuilder import ( "testing" + "vitess.io/vitess/go/vt/sqlparser" + "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/vtgate/vindexes" @@ -47,12 +49,22 @@ func TestCreateDB(t *testing.T) { }() // setting custom behaviour for CREATE DATABASE - databaseCreator = func(name string) error { - return nil - } + databaseCreator = &fakePlugin{} plan, err = TestBuilder("create database test", vschema) require.NoError(t, err) _, err = plan.Instructions.Execute(nil, nil, true) require.NoError(t, err) } + +type fakePlugin struct{} + +// CreateDatabase is a fake +func (*fakePlugin) CreateDatabase(ast *sqlparser.CreateDatabase) error { + return nil +} + +// DropDatabase is a fake +func (*fakePlugin) DropDatabase(ast *sqlparser.DropDatabase) error { + return nil +} diff --git a/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt b/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt index 5bfe20f78c0..41e41b7ab17 100644 --- a/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt @@ -138,11 +138,31 @@ # drop db main "drop database main" -"drop database not allowed" +{ + "QueryType": "DDL", + "Original": "drop database main", + "Instructions": { + "OperatorType": "DROP DATABASE", + "Keyspace": { + "Name": "main", + "Sharded": false + } + } +} # drop db if exists main "drop database if exists main" -"drop database not allowed" +{ + "QueryType": "DDL", + "Original": "drop database if exists main", + "Instructions": { + "OperatorType": "DROP DATABASE", + "Keyspace": { + "Name": "main", + "Sharded": false + } + } +} # drop db if exists foo "drop schema if exists foo" From 80b184fd0b774571cca22db2e093abaaca11d655 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 2 Mar 2021 16:44:27 +0100 Subject: [PATCH 05/23] adressed PR review Signed-off-by: Andres Taylor --- go/vt/vtgate/engine/create_database.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/go/vt/vtgate/engine/create_database.go b/go/vt/vtgate/engine/create_database.go index a11e5d6779d..80d73fa9034 100644 --- a/go/vt/vtgate/engine/create_database.go +++ b/go/vt/vtgate/engine/create_database.go @@ -1,5 +1,5 @@ /* -Copyright 2020 The Vitess Authors. +Copyright 2021 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. @@ -30,13 +30,13 @@ var _ Primitive = (*DropCreateDatabase)(nil) // The default behaviour is to just return an error type DropCreateDatabase struct { name, verb string - plugin func() error + plugin func(VCursor) error noInputs noTxNeeded } // CreateDropCreateDatabase creates the engine primitive -func CreateDropCreateDatabase(dbName, verb string, plugin func() error) *DropCreateDatabase { +func CreateDropCreateDatabase(dbName, verb string, plugin func(VCursor) error) *DropCreateDatabase { return &DropCreateDatabase{ name: dbName, verb: verb, @@ -60,13 +60,15 @@ func (c *DropCreateDatabase) GetTableName() string { } // Execute implements the Primitive interface -func (c *DropCreateDatabase) Execute(VCursor, map[string]*querypb.BindVariable, bool) (*sqltypes.Result, error) { - err := c.plugin() +func (c *DropCreateDatabase) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool) (*sqltypes.Result, error) { + err := c.plugin(vcursor) if err != nil { return nil, err } - return &sqltypes.Result{}, nil + return &sqltypes.Result{ + RowsAffected: 1, + }, nil } // StreamExecute implements the Primitive interface From 7e776c87bb840be5d1f0212108b0d7dcbd3cb19d Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 3 Mar 2021 08:43:50 +0100 Subject: [PATCH 06/23] [wip] refactored lots of things Signed-off-by: Andres Taylor --- .../vtgate/createdb_plugin/main_test.go | 429 ++++++++++++++++++ go/vt/vtgate/engine/cached_size.go | 26 +- go/vt/vtgate/engine/create_database.go | 69 ++- .../create_db_default_plugins.go} | 35 +- go/vt/vtgate/engine/fake_vcursor_test.go | 8 + go/vt/vtgate/engine/primitive.go | 3 + go/vt/vtgate/planbuilder/builder.go | 4 +- .../create_database_pluggable_test.go | 70 --- go/vt/vtgate/vcursor_impl.go | 4 + go/vt/vtgate/vtgate.go | 1 + 10 files changed, 527 insertions(+), 122 deletions(-) create mode 100644 go/test/endtoend/vtgate/createdb_plugin/main_test.go rename go/vt/vtgate/{planbuilder/create_database_pluggable.go => engine/create_db_default_plugins.go} (62%) delete mode 100644 go/vt/vtgate/planbuilder/create_database_pluggable_test.go diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go new file mode 100644 index 00000000000..a66b3fcc6ef --- /dev/null +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -0,0 +1,429 @@ +/* +Copyright 2020 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 unsharded + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "vitess.io/vitess/go/vt/vtgate/engine" + + "vitess.io/vitess/go/vt/log" + + "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/endtoend/cluster" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + cell = "zone1" + hostname = "localhost" + KeyspaceName = "customer" + SchemaSQL = ` +CREATE TABLE t1 ( + c1 BIGINT NOT NULL, + c2 BIGINT NOT NULL, + c3 BIGINT, + c4 varchar(100), + PRIMARY KEY (c1), + UNIQUE KEY (c2), + UNIQUE KEY (c3), + UNIQUE KEY (c4) +) ENGINE=Innodb; + +CREATE TABLE allDefaults ( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(255) +) ENGINE=Innodb;` + VSchema = ` +{ + "sharded": false, + "tables": { + "t1": { + "columns": [ + { + "name": "c1", + "type": "INT64" + }, + { + "name": "c2", + "type": "INT64" + }, + { + "name": "c3", + "type": "INT64" + }, + { + "name": "c4", + "type": "VARCHAR" + } + ] + }, + "allDefaults": { + "columns": [ + { + "name": "id", + "type": "INT64" + }, + { + "name": "name", + "type": "VARCHAR" + } + ] + } + } +} +` + + createProcSQL = `use vt_customer; +CREATE PROCEDURE sp_insert() +BEGIN + insert into allDefaults () values (); +END; + +CREATE PROCEDURE sp_delete() +BEGIN + delete from allDefaults; +END; + +CREATE PROCEDURE sp_multi_dml() +BEGIN + insert into allDefaults () values (); + delete from allDefaults; +END; + +CREATE PROCEDURE sp_variable() +BEGIN + insert into allDefaults () values (); + SELECT min(id) INTO @myvar FROM allDefaults; + DELETE FROM allDefaults WHERE id = @myvar; +END; + +CREATE PROCEDURE sp_select() +BEGIN + SELECT * FROM allDefaults; +END; + +CREATE PROCEDURE sp_all() +BEGIN + insert into allDefaults () values (); + select * from allDefaults; + delete from allDefaults; + set autocommit = 0; +END; + +CREATE PROCEDURE in_parameter(IN val int) +BEGIN + insert into allDefaults(id) values(val); +END; + +CREATE PROCEDURE out_parameter(OUT val int) +BEGIN + insert into allDefaults(id) values (128); + select 128 into val from dual; +END; +` +) + +type testPlugin struct { + create, drop func(name string, vcursor engine.VCursor) (*sqltypes.Result, error) +} + +func (t *testPlugin) CreateDatabase(name string, vcursor engine.VCursor) (*sqltypes.Result, error) { + return t.create(name, vcursor) +} + +func (t *testPlugin) DropDatabase(name string, vcursor engine.VCursor) (*sqltypes.Result, error) { + return t.drop(name, vcursor) +} + +var _ engine.DBDDLPlugin = (*testPlugin)(nil) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + before := engine.DatabaseCreator + engine.DatabaseCreator = &testPlugin{ + create: func(name string, vcursor engine.VCursor) (*sqltypes.Result, error) { + + }, + drop: nil, + } + + exitCode := func() int { + clusterInstance = cluster.NewCluster(cell, hostname) + defer clusterInstance.Teardown() + + // Start topo server + if err := clusterInstance.StartTopo(); err != nil { + return 1 + } + + // Start keyspace + Keyspace := &cluster.Keyspace{ + Name: KeyspaceName, + SchemaSQL: SchemaSQL, + VSchema: VSchema, + } + if err := clusterInstance.StartUnshardedKeyspace(*Keyspace, 0, false); err != nil { + log.Fatal(err.Error()) + return 1 + } + + // Start vtgate + if err := clusterInstance.StartVtgate(); err != nil { + log.Fatal(err.Error()) + return 1 + } + + masterProcess := clusterInstance.Keyspaces[0].Shards[0].MasterTablet().VttabletProcess + if _, err := masterProcess.QueryTablet(createProcSQL, KeyspaceName, false); err != nil { + log.Fatal(err.Error()) + return 1 + } + + return m.Run() + }() + os.Exit(exitCode) +} + +func TestSelectIntoAndLoadFrom(t *testing.T) { + // Test is skipped because it requires secure-file-priv variable to be set to not NULL or empty. + t.Skip() + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + } + conn, err := mysql.Connect(ctx, &vtParams) + require.Nil(t, err) + defer conn.Close() + + defer exec(t, conn, `delete from t1`) + exec(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc')`) + res := exec(t, conn, `select @@secure_file_priv;`) + directory := res.Rows[0][0].ToString() + query := `select * from t1 into outfile '` + directory + `x.txt'` + exec(t, conn, query) + defer os.Remove(directory + `x.txt`) + query = `load data infile '` + directory + `x.txt' into table t1` + execAssertError(t, conn, query, "Duplicate entry '300' for key 'PRIMARY'") + exec(t, conn, `delete from t1`) + exec(t, conn, query) + assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)]]`) + query = `select * from t1 into dumpfile '` + directory + `x1.txt'` + exec(t, conn, query) + defer os.Remove(directory + `x1.txt`) + query = `select * from t1 into outfile '` + directory + `x2.txt' Fields terminated by ';' optionally enclosed by '"' escaped by '\t' lines terminated by '\n'` + exec(t, conn, query) + defer os.Remove(directory + `x2.txt`) + query = `load data infile '` + directory + `x2.txt' replace into table t1 Fields terminated by ';' optionally enclosed by '"' escaped by '\t' lines terminated by '\n'` + exec(t, conn, query) + assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)]]`) +} + +func TestEmptyStatement(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + } + conn, err := mysql.Connect(ctx, &vtParams) + require.Nil(t, err) + defer conn.Close() + defer exec(t, conn, `delete from t1`) + execAssertError(t, conn, " \t;", "Query was empty") + execMulti(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc'); ;; insert into t1(c1, c2, c3, c4) values (301,101,301,'abcd');;`) + assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) +} + +func TestTopoDownServingQuery(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + } + conn, err := mysql.Connect(ctx, &vtParams) + require.Nil(t, err) + defer conn.Close() + + defer exec(t, conn, `delete from t1`) + + execMulti(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc'); ;; insert into t1(c1, c2, c3, c4) values (301,101,301,'abcd');;`) + assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) + clusterInstance.TopoProcess.TearDown(clusterInstance.Cell, clusterInstance.OriginalVTDATAROOT, clusterInstance.CurrentVTDATAROOT, true, *clusterInstance.TopoFlavorString()) + time.Sleep(3 * time.Second) + assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) +} + +func TestInsertAllDefaults(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + } + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + exec(t, conn, `insert into allDefaults () values ()`) + assertMatches(t, conn, `select * from allDefaults`, "[[INT64(1) NULL]]") +} + +func TestDDLUnsharded(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + } + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + exec(t, conn, `create table tempt1(c1 BIGINT NOT NULL,c2 BIGINT NOT NULL,c3 BIGINT,c4 varchar(100),PRIMARY KEY (c1), UNIQUE KEY (c2),UNIQUE KEY (c3), UNIQUE KEY (c4))`) + // Test that create view works and the output is as expected + exec(t, conn, `create view v1 as select * from tempt1`) + exec(t, conn, `insert into tempt1(c1, c2, c3, c4) values (300,100,300,'abc'),(30,10,30,'ac'),(3,0,3,'a')`) + assertMatches(t, conn, "select * from v1", `[[INT64(3) INT64(0) INT64(3) VARCHAR("a")] [INT64(30) INT64(10) INT64(30) VARCHAR("ac")] [INT64(300) INT64(100) INT64(300) VARCHAR("abc")]]`) + exec(t, conn, `drop view v1`) + exec(t, conn, `drop table tempt1`) + assertMatches(t, conn, "show tables", `[[VARCHAR("allDefaults")] [VARCHAR("t1")]]`) +} + +func TestCallProcedure(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + Flags: mysql.CapabilityClientMultiResults, + DbName: "@master", + } + time.Sleep(5 * time.Second) + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + qr := exec(t, conn, `CALL sp_insert()`) + require.EqualValues(t, 1, qr.RowsAffected) + + _, err = conn.ExecuteFetch(`CALL sp_select()`, 1000, true) + require.Error(t, err) + require.Contains(t, err.Error(), "Multi-Resultset not supported in stored procedure") + + _, err = conn.ExecuteFetch(`CALL sp_all()`, 1000, true) + require.Error(t, err) + require.Contains(t, err.Error(), "Multi-Resultset not supported in stored procedure") + + qr = exec(t, conn, `CALL sp_delete()`) + require.GreaterOrEqual(t, 1, int(qr.RowsAffected)) + + qr = exec(t, conn, `CALL sp_multi_dml()`) + require.EqualValues(t, 1, qr.RowsAffected) + + qr = exec(t, conn, `CALL sp_variable()`) + require.EqualValues(t, 1, qr.RowsAffected) + + qr = exec(t, conn, `CALL in_parameter(42)`) + require.EqualValues(t, 1, qr.RowsAffected) + + _ = exec(t, conn, `SET @foo = 123`) + qr = exec(t, conn, `CALL in_parameter(@foo)`) + require.EqualValues(t, 1, qr.RowsAffected) + qr = exec(t, conn, "select * from allDefaults where id = 123") + assert.NotEmpty(t, qr.Rows) + + _, err = conn.ExecuteFetch(`CALL out_parameter(@foo)`, 100, true) + require.Error(t, err) + require.Contains(t, err.Error(), "OUT and INOUT parameters are not supported") +} + +func TestTempTable(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: "localhost", + Port: clusterInstance.VtgateMySQLPort, + } + conn1, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn1.Close() + + _ = exec(t, conn1, `create temporary table temp_t(id bigint primary key)`) + _ = exec(t, conn1, `insert into temp_t(id) values (1),(2),(3)`) + assertMatches(t, conn1, `select id from temp_t order by id`, `[[INT64(1)] [INT64(2)] [INT64(3)]]`) + assertMatches(t, conn1, `select count(table_id) from information_schema.innodb_temp_table_info`, `[[INT64(1)]]`) + + conn2, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn2.Close() + + assertMatches(t, conn2, `select count(table_id) from information_schema.innodb_temp_table_info`, `[[INT64(1)]]`) + execAssertError(t, conn2, `show create table temp_t`, `Table 'vt_customer.temp_t' doesn't exist (errno 1146) (sqlstate 42S02)`) +} + +func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { + t.Helper() + qr, err := conn.ExecuteFetch(query, 1000, true) + require.NoError(t, err) + return qr +} + +func execMulti(t *testing.T, conn *mysql.Conn, query string) []*sqltypes.Result { + t.Helper() + var res []*sqltypes.Result + qr, more, err := conn.ExecuteFetchMulti(query, 1000, true) + res = append(res, qr) + require.NoError(t, err) + for more == true { + qr, more, _, err = conn.ReadQueryResult(1000, true) + require.NoError(t, err) + res = append(res, qr) + } + return res +} + +func execAssertError(t *testing.T, conn *mysql.Conn, query string, errorString string) { + t.Helper() + _, err := conn.ExecuteFetch(query, 1000, true) + require.Error(t, err) + assert.Contains(t, err.Error(), errorString) +} + +func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { + t.Helper() + qr := exec(t, conn, query) + got := fmt.Sprintf("%v", qr.Rows) + diff := cmp.Diff(expected, got) + if diff != "" { + t.Errorf("Query: %s (-want +got):\n%s", query, diff) + } +} diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 5cd05f7ac0d..ed8431cafdd 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -72,6 +72,18 @@ func (cached *Concatenate) CachedSize(alloc bool) int64 { } return size } +func (cached *DBDDL) CachedSize(alloc bool) int64 { + if cached == nil { + return int64(0) + } + size := int64(0) + if alloc { + size += int64(17) + } + // field name string + size += int64(len(cached.name)) + return size +} func (cached *DDL) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) @@ -157,20 +169,6 @@ func (cached *Distinct) CachedSize(alloc bool) int64 { } return size } -func (cached *DropCreateDatabase) CachedSize(alloc bool) int64 { - if cached == nil { - return int64(0) - } - size := int64(0) - if alloc { - size += int64(40) - } - // field name string - size += int64(len(cached.name)) - // field verb string - size += int64(len(cached.verb)) - return size -} func (cached *Generate) CachedSize(alloc bool) int64 { if cached == nil { return int64(0) diff --git a/go/vt/vtgate/engine/create_database.go b/go/vt/vtgate/engine/create_database.go index 80d73fa9034..457cfb4becc 100644 --- a/go/vt/vtgate/engine/create_database.go +++ b/go/vt/vtgate/engine/create_database.go @@ -17,62 +17,85 @@ limitations under the License. package engine import ( + "context" "strings" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/vtgate/vindexes" ) -var _ Primitive = (*DropCreateDatabase)(nil) +var _ Primitive = (*DBDDL)(nil) + +//goland:noinspection GoVarAndConstTypeMayBeOmitted +var databaseCreatorPlugins = map[string]DBDDLPlugin{} -// DropCreateDatabase is just a container around custom database provisioning plugins +// DBDDLPlugin is the interface that you need to implement to add a custom CREATE/DROP DATABASE handler +type DBDDLPlugin interface { + CreateDatabase(ctx context.Context, name string) error + DropDatabase(ctx context.Context, name string) error +} + +// DBDDL is just a container around custom database provisioning plugins // The default behaviour is to just return an error -type DropCreateDatabase struct { - name, verb string - plugin func(VCursor) error +type DBDDL struct { + name string + create bool + noInputs noTxNeeded } // CreateDropCreateDatabase creates the engine primitive -func CreateDropCreateDatabase(dbName, verb string, plugin func(VCursor) error) *DropCreateDatabase { - return &DropCreateDatabase{ +// `create` will be true for CREATE, and false for DROP +func CreateDropCreateDatabase(dbName string, create bool) *DBDDL { + return &DBDDL{ name: dbName, - verb: verb, - plugin: plugin, + create: create, } } // RouteType implements the Primitive interface -func (c *DropCreateDatabase) RouteType() string { - return c.verb + " database" +func (c *DBDDL) RouteType() string { + if c.create { + return "create database" + } + return "drop database" } // GetKeyspaceName implements the Primitive interface -func (c *DropCreateDatabase) GetKeyspaceName() string { +func (c *DBDDL) GetKeyspaceName() string { return c.name } // GetTableName implements the Primitive interface -func (c *DropCreateDatabase) GetTableName() string { +func (c *DBDDL) GetTableName() string { return "" } // Execute implements the Primitive interface -func (c *DropCreateDatabase) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool) (*sqltypes.Result, error) { - err := c.plugin(vcursor) +func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool) (*sqltypes.Result, error) { + name := vcursor.GetDBDDLPluginName() + plugin := databaseCreatorPlugins[name] + if c.create { + err := plugin.CreateDatabase(vcursor.Context(), c.name) + if err != nil { + return nil, err + } + return &sqltypes.Result{RowsAffected: 1}, nil + } + + err := plugin.DropDatabase(vcursor.Context(), c.name) if err != nil { return nil, err } - - return &sqltypes.Result{ - RowsAffected: 1, - }, nil + return &sqltypes.Result{StatusFlags: mysql.ServerStatusDbDropped}, nil } // StreamExecute implements the Primitive interface -func (c *DropCreateDatabase) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { +func (c *DBDDL) StreamExecute(vcursor VCursor, bindVars map[string]*querypb.BindVariable, wantfields bool, callback func(*sqltypes.Result) error) error { res, err := c.Execute(vcursor, bindVars, wantfields) if err != nil { return err @@ -81,14 +104,14 @@ func (c *DropCreateDatabase) StreamExecute(vcursor VCursor, bindVars map[string] } // GetFields implements the Primitive interface -func (c *DropCreateDatabase) GetFields(VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { +func (c *DBDDL) GetFields(VCursor, map[string]*querypb.BindVariable) (*sqltypes.Result, error) { return &sqltypes.Result{}, nil } // description implements the Primitive interface -func (c *DropCreateDatabase) description() PrimitiveDescription { +func (c *DBDDL) description() PrimitiveDescription { return PrimitiveDescription{ - OperatorType: strings.ToUpper(c.verb + " DATABASE"), + OperatorType: strings.ToUpper(c.RouteType()), Keyspace: &vindexes.Keyspace{Name: c.name}, } } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable.go b/go/vt/vtgate/engine/create_db_default_plugins.go similarity index 62% rename from go/vt/vtgate/planbuilder/create_database_pluggable.go rename to go/vt/vtgate/engine/create_db_default_plugins.go index 60ed8998774..be0dad8796e 100644 --- a/go/vt/vtgate/planbuilder/create_database_pluggable.go +++ b/go/vt/vtgate/engine/create_db_default_plugins.go @@ -14,31 +14,40 @@ See the License for the specific language governing permissions and limitations under the License. */ -package planbuilder +package engine import ( + "context" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" ) -// DropCreateDB is the interface that you need to implement to add a custom CREATE/DROP DATABASE handler -type DropCreateDB interface { - CreateDatabase(ast *sqlparser.CreateDatabase) error - DropDatabase(ast *sqlparser.DropDatabase) error -} - -type defaultHandler struct{} +type failDBDDL struct{} // CreateDatabase implements the DropCreateDB interface -func (defaultHandler) CreateDatabase(*sqlparser.CreateDatabase) error { +func (failDBDDL) CreateDatabase(context.Context, string) error { return vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "create database is not supported") } // DropDatabase implements the DropCreateDB interface -func (defaultHandler) DropDatabase(*sqlparser.DropDatabase) error { +func (failDBDDL) DropDatabase(context.Context, string) error { return vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "drop database is not supported") } -//goland:noinspection GoVarAndConstTypeMayBeOmitted -var databaseCreator DropCreateDB = defaultHandler{} +type noOp struct{} + +// CreateDatabase implements the DropCreateDB interface +func (noOp) CreateDatabase(context.Context, string) error { + return nil +} + +// DropDatabase implements the DropCreateDB interface +func (noOp) DropDatabase(context.Context, string) error { + return nil +} + +func init() { + databaseCreatorPlugins["fail"] = failDBDDL{} + databaseCreatorPlugins["noop"] = noOp{} +} diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index fd60ad90325..966e45b39ff 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -235,6 +235,10 @@ func (t noopVCursor) SubmitOnlineDDL(onlineDDl *schema.OnlineDDL) error { panic("unimplemented") } +func (t noopVCursor) GetDBDDLPluginName() string { + panic("unimplemented") +} + var _ VCursor = (*loggingVCursor)(nil) var _ SessionActions = (*loggingVCursor)(nil) @@ -508,6 +512,10 @@ func (f *loggingVCursor) FindRoutedTable(tbl sqlparser.TableName) (*vindexes.Tab return f.tableRoutes.tbl, nil } +func (f *loggingVCursor) GetDBDDLPluginName() string { + panic("implement me") +} + func (f *loggingVCursor) nextResult() (*sqltypes.Result, error) { if f.results == nil || f.curResult >= len(f.results) { return &sqltypes.Result{}, f.resultErr diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index 3cb3e52fd02..f77449847d3 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -98,6 +98,9 @@ type ( LookupRowLockShardSession() vtgatepb.CommitOrder FindRoutedTable(tablename sqlparser.TableName) (*vindexes.Table, error) + + // GetDBDDLPlugin gets the configured plugin for DROP/CREATE DATABASE + GetDBDDLPluginName() string } //SessionActions gives primitives ability to interact with the session state diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index cb79882544d..e52932179f3 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -205,7 +205,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_NOT_FOUND, vterrors.DbDropExists, "Can't drop database '%s'; database doesn't exists", ksName) } - return engine.CreateDropCreateDatabase(dbDDL.DBName, "drop", func(_ engine.VCursor) error { return databaseCreator.DropDatabase(dbDDL) }), nil + return engine.CreateDropCreateDatabase(ksName, false), nil case *sqlparser.AlterDatabase: if !ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_NOT_FOUND, vterrors.BadDb, "Can't alter database '%s'; unknown database", ksName) @@ -218,7 +218,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !dbDDL.IfNotExists && ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_ALREADY_EXISTS, vterrors.DbCreateExists, "Can't create database '%s'; database exists", ksName) } - return engine.CreateDropCreateDatabase(dbDDL.DBName, "create", func(_ engine.VCursor) error { return databaseCreator.CreateDatabase(dbDDL) }), nil + return engine.CreateDropCreateDatabase(ksName, true), nil } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] database ddl not recognized: %s", sqlparser.String(dbDDLstmt)) } diff --git a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go b/go/vt/vtgate/planbuilder/create_database_pluggable_test.go deleted file mode 100644 index 50dc23e950b..00000000000 --- a/go/vt/vtgate/planbuilder/create_database_pluggable_test.go +++ /dev/null @@ -1,70 +0,0 @@ -/* -Copyright 2021 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 planbuilder - -import ( - "testing" - - "vitess.io/vitess/go/vt/sqlparser" - - "github.com/stretchr/testify/require" - - "vitess.io/vitess/go/vt/vtgate/vindexes" -) - -func TestCreateDB(t *testing.T) { - ks := &vindexes.Keyspace{Name: "main"} - vschema := &vschemaWrapper{ - v: &vindexes.VSchema{ - Keyspaces: map[string]*vindexes.KeyspaceSchema{"main": {Keyspace: ks}}, - }, - keyspace: ks, - } - - // default behaviour - plan, err := TestBuilder("create database test", vschema) - require.NoError(t, err) - - _, err = plan.Instructions.Execute(nil, nil, true) - require.EqualError(t, err, "create database not allowed") - - // we make sure to restore the state so we don't destabilize other tests - before := databaseCreator - defer func() { - databaseCreator = before - }() - - // setting custom behaviour for CREATE DATABASE - databaseCreator = &fakePlugin{} - - plan, err = TestBuilder("create database test", vschema) - require.NoError(t, err) - _, err = plan.Instructions.Execute(nil, nil, true) - require.NoError(t, err) -} - -type fakePlugin struct{} - -// CreateDatabase is a fake -func (*fakePlugin) CreateDatabase(ast *sqlparser.CreateDatabase) error { - return nil -} - -// DropDatabase is a fake -func (*fakePlugin) DropDatabase(ast *sqlparser.DropDatabase) error { - return nil -} diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 4c6f89bd51b..7b724c8c45c 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -694,6 +694,10 @@ func (vc *vcursorImpl) HasCreatedTempTable() { vc.safeSession.GetOrCreateOptions().HasCreatedTempTables = true } +func (vc *vcursorImpl) GetDBDDLPluginName() string { + return *createDropDbPlugin +} + // ParseDestinationTarget parses destination target string and sets default keyspace if possible. func parseDestinationTarget(targetString string, vschema *vindexes.VSchema) (string, topodatapb.TabletType, key.Destination, error) { destKeyspace, destTabletType, dest, err := topoprotopb.ParseDestination(targetString, defaultTabletType) diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index e57fd9423d1..f3a5a855ea4 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -64,6 +64,7 @@ var ( maxMemoryRows = flag.Int("max_memory_rows", 300000, "Maximum number of rows that will be held in memory for intermediate results as well as the final result.") warnMemoryRows = flag.Int("warn_memory_rows", 30000, "Warning threshold for in-memory results. A row count higher than this amount will cause the VtGateWarnings.ResultsExceeded counter to be incremented.") defaultDDLStrategy = flag.String("ddl_strategy", string(schema.DDLStrategyDirect), "Set default strategy for DDL statements. Override with @@ddl_strategy session variable") + createDropDbPlugin = flag.String("create-drop-db-plugin", "error", "controls how to handle CREATE/DROP DATABASE. use it if you are using your own database provisioning service") // TODO(deepthi): change these two vars to unexported and move to healthcheck.go when LegacyHealthcheck is removed From cd26ee2ff33fec3fd65e267cc86340b10b5d5774 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 3 Mar 2021 18:05:02 +0530 Subject: [PATCH 07/23] code refactor Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/{create_database.go => dbddl.go} | 7 ++++++- .../{create_db_default_plugins.go => dbddl_plugin.go} | 10 ++++++++-- go/vt/vtgate/vcursor_impl.go | 2 +- go/vt/vtgate/vtgate.go | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) rename go/vt/vtgate/engine/{create_database.go => dbddl.go} (93%) rename go/vt/vtgate/engine/{create_db_default_plugins.go => dbddl_plugin.go} (88%) diff --git a/go/vt/vtgate/engine/create_database.go b/go/vt/vtgate/engine/dbddl.go similarity index 93% rename from go/vt/vtgate/engine/create_database.go rename to go/vt/vtgate/engine/dbddl.go index 457cfb4becc..39117875592 100644 --- a/go/vt/vtgate/engine/create_database.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -19,6 +19,7 @@ package engine import ( "context" "strings" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/mysql" @@ -78,7 +79,11 @@ func (c *DBDDL) GetTableName() string { // Execute implements the Primitive interface func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ bool) (*sqltypes.Result, error) { name := vcursor.GetDBDDLPluginName() - plugin := databaseCreatorPlugins[name] + plugin, ok := databaseCreatorPlugins[name] + if !ok { + log.Errorf("'%s' database ddl plugin is not registered. Falling back to default plugin", name) + plugin = databaseCreatorPlugins[defaultDBDDLPlugin] + } if c.create { err := plugin.CreateDatabase(vcursor.Context(), c.name) if err != nil { diff --git a/go/vt/vtgate/engine/create_db_default_plugins.go b/go/vt/vtgate/engine/dbddl_plugin.go similarity index 88% rename from go/vt/vtgate/engine/create_db_default_plugins.go rename to go/vt/vtgate/engine/dbddl_plugin.go index be0dad8796e..cdac65e602d 100644 --- a/go/vt/vtgate/engine/create_db_default_plugins.go +++ b/go/vt/vtgate/engine/dbddl_plugin.go @@ -47,7 +47,13 @@ func (noOp) DropDatabase(context.Context, string) error { return nil } +const ( + faildbDDL = "fail" + noOpdbDDL = "noop" + defaultDBDDLPlugin = faildbDDL +) + func init() { - databaseCreatorPlugins["fail"] = failDBDDL{} - databaseCreatorPlugins["noop"] = noOp{} + databaseCreatorPlugins[faildbDDL] = failDBDDL{} + databaseCreatorPlugins[noOpdbDDL] = noOp{} } diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 7b724c8c45c..742b24bcd8c 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -695,7 +695,7 @@ func (vc *vcursorImpl) HasCreatedTempTable() { } func (vc *vcursorImpl) GetDBDDLPluginName() string { - return *createDropDbPlugin + return *dbDDLPlugin } // ParseDestinationTarget parses destination target string and sets default keyspace if possible. diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index f3a5a855ea4..221805ade8d 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -64,7 +64,7 @@ var ( maxMemoryRows = flag.Int("max_memory_rows", 300000, "Maximum number of rows that will be held in memory for intermediate results as well as the final result.") warnMemoryRows = flag.Int("warn_memory_rows", 30000, "Warning threshold for in-memory results. A row count higher than this amount will cause the VtGateWarnings.ResultsExceeded counter to be incremented.") defaultDDLStrategy = flag.String("ddl_strategy", string(schema.DDLStrategyDirect), "Set default strategy for DDL statements. Override with @@ddl_strategy session variable") - createDropDbPlugin = flag.String("create-drop-db-plugin", "error", "controls how to handle CREATE/DROP DATABASE. use it if you are using your own database provisioning service") + dbDDLPlugin = flag.String("dbddl_plugin", "fail", "controls how to handle CREATE/DROP DATABASE. use it if you are using your own database provisioning service") // TODO(deepthi): change these two vars to unexported and move to healthcheck.go when LegacyHealthcheck is removed From 02e49ce89c2a62fc2d3381d71cc18ad605d69a6c Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 3 Mar 2021 18:05:29 +0530 Subject: [PATCH 08/23] e2e test fir dbddl plugin Signed-off-by: Harshit Gangal --- .../vtgate/createdb_plugin/main_test.go | 346 +++--------------- 1 file changed, 43 insertions(+), 303 deletions(-) diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index a66b3fcc6ef..8eede10b521 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -22,11 +22,6 @@ import ( "fmt" "os" "testing" - "time" - - "vitess.io/vitess/go/vt/vtgate/engine" - - "vitess.io/vitess/go/vt/log" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" @@ -39,141 +34,16 @@ import ( var ( clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + keyspaceName = "ks" cell = "zone1" hostname = "localhost" - KeyspaceName = "customer" - SchemaSQL = ` -CREATE TABLE t1 ( - c1 BIGINT NOT NULL, - c2 BIGINT NOT NULL, - c3 BIGINT, - c4 varchar(100), - PRIMARY KEY (c1), - UNIQUE KEY (c2), - UNIQUE KEY (c3), - UNIQUE KEY (c4) -) ENGINE=Innodb; - -CREATE TABLE allDefaults ( - id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(255) -) ENGINE=Innodb;` - VSchema = ` -{ - "sharded": false, - "tables": { - "t1": { - "columns": [ - { - "name": "c1", - "type": "INT64" - }, - { - "name": "c2", - "type": "INT64" - }, - { - "name": "c3", - "type": "INT64" - }, - { - "name": "c4", - "type": "VARCHAR" - } - ] - }, - "allDefaults": { - "columns": [ - { - "name": "id", - "type": "INT64" - }, - { - "name": "name", - "type": "VARCHAR" - } - ] - } - } -} -` - - createProcSQL = `use vt_customer; -CREATE PROCEDURE sp_insert() -BEGIN - insert into allDefaults () values (); -END; - -CREATE PROCEDURE sp_delete() -BEGIN - delete from allDefaults; -END; - -CREATE PROCEDURE sp_multi_dml() -BEGIN - insert into allDefaults () values (); - delete from allDefaults; -END; - -CREATE PROCEDURE sp_variable() -BEGIN - insert into allDefaults () values (); - SELECT min(id) INTO @myvar FROM allDefaults; - DELETE FROM allDefaults WHERE id = @myvar; -END; - -CREATE PROCEDURE sp_select() -BEGIN - SELECT * FROM allDefaults; -END; - -CREATE PROCEDURE sp_all() -BEGIN - insert into allDefaults () values (); - select * from allDefaults; - delete from allDefaults; - set autocommit = 0; -END; - -CREATE PROCEDURE in_parameter(IN val int) -BEGIN - insert into allDefaults(id) values(val); -END; - -CREATE PROCEDURE out_parameter(OUT val int) -BEGIN - insert into allDefaults(id) values (128); - select 128 into val from dual; -END; -` ) -type testPlugin struct { - create, drop func(name string, vcursor engine.VCursor) (*sqltypes.Result, error) -} - -func (t *testPlugin) CreateDatabase(name string, vcursor engine.VCursor) (*sqltypes.Result, error) { - return t.create(name, vcursor) -} - -func (t *testPlugin) DropDatabase(name string, vcursor engine.VCursor) (*sqltypes.Result, error) { - return t.drop(name, vcursor) -} - -var _ engine.DBDDLPlugin = (*testPlugin)(nil) - func TestMain(m *testing.M) { defer cluster.PanicHandler(nil) flag.Parse() - before := engine.DatabaseCreator - engine.DatabaseCreator = &testPlugin{ - create: func(name string, vcursor engine.VCursor) (*sqltypes.Result, error) { - - }, - drop: nil, - } - exitCode := func() int { clusterInstance = cluster.NewCluster(cell, hostname) defer clusterInstance.Teardown() @@ -184,36 +54,31 @@ func TestMain(m *testing.M) { } // Start keyspace - Keyspace := &cluster.Keyspace{ - Name: KeyspaceName, - SchemaSQL: SchemaSQL, - VSchema: VSchema, + keyspace := &cluster.Keyspace{ + Name: keyspaceName, } - if err := clusterInstance.StartUnshardedKeyspace(*Keyspace, 0, false); err != nil { - log.Fatal(err.Error()) + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 0, false); err != nil { return 1 } // Start vtgate - if err := clusterInstance.StartVtgate(); err != nil { - log.Fatal(err.Error()) + clusterInstance.VtGateExtraArgs = []string{"-dbddl_plugin", "noop"} + vtgateProcess := clusterInstance.NewVtgateInstance() + vtgateProcess.SysVarSetEnabled = true + if err := vtgateProcess.Setup(); err != nil { return 1 } - masterProcess := clusterInstance.Keyspaces[0].Shards[0].MasterTablet().VttabletProcess - if _, err := masterProcess.QueryTablet(createProcSQL, KeyspaceName, false); err != nil { - log.Fatal(err.Error()) - return 1 + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, } - return m.Run() }() os.Exit(exitCode) } -func TestSelectIntoAndLoadFrom(t *testing.T) { - // Test is skipped because it requires secure-file-priv variable to be set to not NULL or empty. - t.Skip() +func TestDBDDLPluginSync(t *testing.T) { defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ @@ -221,84 +86,31 @@ func TestSelectIntoAndLoadFrom(t *testing.T) { Port: clusterInstance.VtgateMySQLPort, } conn, err := mysql.Connect(ctx, &vtParams) - require.Nil(t, err) + require.NoError(t, err) defer conn.Close() - defer exec(t, conn, `delete from t1`) - exec(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc')`) - res := exec(t, conn, `select @@secure_file_priv;`) - directory := res.Rows[0][0].ToString() - query := `select * from t1 into outfile '` + directory + `x.txt'` - exec(t, conn, query) - defer os.Remove(directory + `x.txt`) - query = `load data infile '` + directory + `x.txt' into table t1` - execAssertError(t, conn, query, "Duplicate entry '300' for key 'PRIMARY'") - exec(t, conn, `delete from t1`) - exec(t, conn, query) - assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)]]`) - query = `select * from t1 into dumpfile '` + directory + `x1.txt'` - exec(t, conn, query) - defer os.Remove(directory + `x1.txt`) - query = `select * from t1 into outfile '` + directory + `x2.txt' Fields terminated by ';' optionally enclosed by '"' escaped by '\t' lines terminated by '\n'` - exec(t, conn, query) - defer os.Remove(directory + `x2.txt`) - query = `load data infile '` + directory + `x2.txt' replace into table t1 Fields terminated by ';' optionally enclosed by '"' escaped by '\t' lines terminated by '\n'` - exec(t, conn, query) - assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)]]`) -} + qr := exec(t, conn, `create database aaa`) + require.EqualValues(t, 1, qr.RowsAffected) -func TestEmptyStatement(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: "localhost", - Port: clusterInstance.VtgateMySQLPort, + keyspace := &cluster.Keyspace{ + Name: "aaa", } - conn, err := mysql.Connect(ctx, &vtParams) - require.Nil(t, err) - defer conn.Close() - defer exec(t, conn, `delete from t1`) - execAssertError(t, conn, " \t;", "Query was empty") - execMulti(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc'); ;; insert into t1(c1, c2, c3, c4) values (301,101,301,'abcd');;`) - assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) -} + require.NoError(t, + clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false), + "new database creation failed") -func TestTopoDownServingQuery(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: "localhost", - Port: clusterInstance.VtgateMySQLPort, - } - conn, err := mysql.Connect(ctx, &vtParams) - require.Nil(t, err) - defer conn.Close() + exec(t, conn, `use aaa`) - defer exec(t, conn, `delete from t1`) + exec(t, conn, `create table t (id bigint primary key)`) + exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`) + assertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`) - execMulti(t, conn, `insert into t1(c1, c2, c3, c4) values (300,100,300,'abc'); ;; insert into t1(c1, c2, c3, c4) values (301,101,301,'abcd');;`) - assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) - clusterInstance.TopoProcess.TearDown(clusterInstance.Cell, clusterInstance.OriginalVTDATAROOT, clusterInstance.CurrentVTDATAROOT, true, *clusterInstance.TopoFlavorString()) - time.Sleep(3 * time.Second) - assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) -} + exec(t, conn, `drop database aaa`) -func TestInsertAllDefaults(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: "localhost", - Port: clusterInstance.VtgateMySQLPort, - } - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - - exec(t, conn, `insert into allDefaults () values ()`) - assertMatches(t, conn, `select * from allDefaults`, "[[INT64(1) NULL]]") + execAssertError(t, conn, "select count(*) from t", `some error`) } -func TestDDLUnsharded(t *testing.T) { +func TestDBDDLPluginASync(t *testing.T) { defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ @@ -309,85 +121,27 @@ func TestDDLUnsharded(t *testing.T) { require.NoError(t, err) defer conn.Close() - exec(t, conn, `create table tempt1(c1 BIGINT NOT NULL,c2 BIGINT NOT NULL,c3 BIGINT,c4 varchar(100),PRIMARY KEY (c1), UNIQUE KEY (c2),UNIQUE KEY (c3), UNIQUE KEY (c4))`) - // Test that create view works and the output is as expected - exec(t, conn, `create view v1 as select * from tempt1`) - exec(t, conn, `insert into tempt1(c1, c2, c3, c4) values (300,100,300,'abc'),(30,10,30,'ac'),(3,0,3,'a')`) - assertMatches(t, conn, "select * from v1", `[[INT64(3) INT64(0) INT64(3) VARCHAR("a")] [INT64(30) INT64(10) INT64(30) VARCHAR("ac")] [INT64(300) INT64(100) INT64(300) VARCHAR("abc")]]`) - exec(t, conn, `drop view v1`) - exec(t, conn, `drop table tempt1`) - assertMatches(t, conn, "show tables", `[[VARCHAR("allDefaults")] [VARCHAR("t1")]]`) -} - -func TestCallProcedure(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: "localhost", - Port: clusterInstance.VtgateMySQLPort, - Flags: mysql.CapabilityClientMultiResults, - DbName: "@master", - } - time.Sleep(5 * time.Second) - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - qr := exec(t, conn, `CALL sp_insert()`) - require.EqualValues(t, 1, qr.RowsAffected) - - _, err = conn.ExecuteFetch(`CALL sp_select()`, 1000, true) - require.Error(t, err) - require.Contains(t, err.Error(), "Multi-Resultset not supported in stored procedure") - - _, err = conn.ExecuteFetch(`CALL sp_all()`, 1000, true) - require.Error(t, err) - require.Contains(t, err.Error(), "Multi-Resultset not supported in stored procedure") - - qr = exec(t, conn, `CALL sp_delete()`) - require.GreaterOrEqual(t, 1, int(qr.RowsAffected)) - - qr = exec(t, conn, `CALL sp_multi_dml()`) + qr := exec(t, conn, `create database aaa`) require.EqualValues(t, 1, qr.RowsAffected) - qr = exec(t, conn, `CALL sp_variable()`) - require.EqualValues(t, 1, qr.RowsAffected) + go func() { + keyspace := &cluster.Keyspace{ + Name: "aaa", + } + require.NoError(t, + clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false), + "new database creation failed") + }() - qr = exec(t, conn, `CALL in_parameter(42)`) - require.EqualValues(t, 1, qr.RowsAffected) + exec(t, conn, `use aaa`) - _ = exec(t, conn, `SET @foo = 123`) - qr = exec(t, conn, `CALL in_parameter(@foo)`) - require.EqualValues(t, 1, qr.RowsAffected) - qr = exec(t, conn, "select * from allDefaults where id = 123") - assert.NotEmpty(t, qr.Rows) + exec(t, conn, `create table t (id bigint primary key)`) + exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`) + assertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`) - _, err = conn.ExecuteFetch(`CALL out_parameter(@foo)`, 100, true) - require.Error(t, err) - require.Contains(t, err.Error(), "OUT and INOUT parameters are not supported") -} + exec(t, conn, `drop database aaa`) -func TestTempTable(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: "localhost", - Port: clusterInstance.VtgateMySQLPort, - } - conn1, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn1.Close() - - _ = exec(t, conn1, `create temporary table temp_t(id bigint primary key)`) - _ = exec(t, conn1, `insert into temp_t(id) values (1),(2),(3)`) - assertMatches(t, conn1, `select id from temp_t order by id`, `[[INT64(1)] [INT64(2)] [INT64(3)]]`) - assertMatches(t, conn1, `select count(table_id) from information_schema.innodb_temp_table_info`, `[[INT64(1)]]`) - - conn2, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn2.Close() - - assertMatches(t, conn2, `select count(table_id) from information_schema.innodb_temp_table_info`, `[[INT64(1)]]`) - execAssertError(t, conn2, `show create table temp_t`, `Table 'vt_customer.temp_t' doesn't exist (errno 1146) (sqlstate 42S02)`) + execAssertError(t, conn, "select count(*) from t", `some error`) } func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { @@ -397,20 +151,6 @@ func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { return qr } -func execMulti(t *testing.T, conn *mysql.Conn, query string) []*sqltypes.Result { - t.Helper() - var res []*sqltypes.Result - qr, more, err := conn.ExecuteFetchMulti(query, 1000, true) - res = append(res, qr) - require.NoError(t, err) - for more == true { - qr, more, _, err = conn.ReadQueryResult(1000, true) - require.NoError(t, err) - res = append(res, qr) - } - return res -} - func execAssertError(t *testing.T, conn *mysql.Conn, query string, errorString string) { t.Helper() _, err := conn.ExecuteFetch(query, 1000, true) From a429c60a9510acf8bcfeaa33465ba23bf3293db2 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 3 Mar 2021 16:59:10 +0100 Subject: [PATCH 09/23] [wip] implement the dbddl primitive Signed-off-by: Andres Taylor --- .../vtgate/createdb_plugin/main_test.go | 46 +++-------- go/vt/vtgate/engine/dbddl.go | 20 ++++- go/vt/vtgate/engine/dbddl_test.go | 76 +++++++++++++++++++ go/vt/vtgate/planbuilder/builder.go | 4 +- 4 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 go/vt/vtgate/engine/dbddl_test.go diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 8eede10b521..4924f8ab153 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -21,6 +21,7 @@ import ( "flag" "fmt" "os" + "sync" "testing" "github.com/google/go-cmp/cmp" @@ -89,8 +90,13 @@ func TestDBDDLPluginSync(t *testing.T) { require.NoError(t, err) defer conn.Close() - qr := exec(t, conn, `create database aaa`) - require.EqualValues(t, 1, qr.RowsAffected) + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + qr := exec(t, conn, `create database aaa`) + require.EqualValues(t, 1, qr.RowsAffected) + }() keyspace := &cluster.Keyspace{ Name: "aaa", @@ -99,6 +105,7 @@ func TestDBDDLPluginSync(t *testing.T) { clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false), "new database creation failed") + // wait until the create database query has returned exec(t, conn, `use aaa`) exec(t, conn, `create table t (id bigint primary key)`) @@ -107,40 +114,7 @@ func TestDBDDLPluginSync(t *testing.T) { exec(t, conn, `drop database aaa`) - execAssertError(t, conn, "select count(*) from t", `some error`) -} - -func TestDBDDLPluginASync(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - vtParams := mysql.ConnParams{ - Host: "localhost", - Port: clusterInstance.VtgateMySQLPort, - } - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - - qr := exec(t, conn, `create database aaa`) - require.EqualValues(t, 1, qr.RowsAffected) - - go func() { - keyspace := &cluster.Keyspace{ - Name: "aaa", - } - require.NoError(t, - clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false), - "new database creation failed") - }() - - exec(t, conn, `use aaa`) - - exec(t, conn, `create table t (id bigint primary key)`) - exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`) - assertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`) - - exec(t, conn, `drop database aaa`) - + // TODO: we should chant down babylon here (aka take down the keyspace with all tablets) execAssertError(t, conn, "select count(*) from t", `some error`) } diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 39117875592..4bfcbf19def 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -19,6 +19,7 @@ package engine import ( "context" "strings" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/mysql" @@ -49,9 +50,9 @@ type DBDDL struct { noTxNeeded } -// CreateDropCreateDatabase creates the engine primitive +// NewDBDDL creates the engine primitive // `create` will be true for CREATE, and false for DROP -func CreateDropCreateDatabase(dbName string, create bool) *DBDDL { +func NewDBDDL(dbName string, create bool) *DBDDL { return &DBDDL{ name: dbName, create: create, @@ -89,6 +90,21 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b if err != nil { return nil, err } + done := false + oldDb := vcursor.GetKeyspace() + for !done { + // loop until we have found a valid shard + err := vcursor.Session().SetTarget(c.name) + if err == nil { + done = true + } + log.Error(err) + } + err = vcursor.Session().SetTarget(oldDb) + if err != nil { + return nil, err + } + return &sqltypes.Result{RowsAffected: 1}, nil } diff --git a/go/vt/vtgate/engine/dbddl_test.go b/go/vt/vtgate/engine/dbddl_test.go new file mode 100644 index 00000000000..6cf0dc0ead3 --- /dev/null +++ b/go/vt/vtgate/engine/dbddl_test.go @@ -0,0 +1,76 @@ +package engine + +import ( + "context" + "fmt" + "testing" + "time" + + "vitess.io/vitess/go/sync2" + + "github.com/stretchr/testify/require" +) + +type dbddlTestFake struct { + pluginName, oldKS string + + createCalled, dropCalled bool + + setTargetError error + + noopVCursor + targetSet string +} + +func (d *dbddlTestFake) GetDBDDLPluginName() string { + return d.pluginName +} +func (d *dbddlTestFake) CreateDatabase(ctx context.Context, name string) error { + d.createCalled = true + return nil +} + +func (d *dbddlTestFake) DropDatabase(ctx context.Context, name string) error { + d.dropCalled = true + return nil +} + +func (d *dbddlTestFake) Session() SessionActions { + return d +} +func (d *dbddlTestFake) SetTarget(t string) error { + d.targetSet = t + return d.setTargetError +} + +var _ VCursor = (*dbddlTestFake)(nil) +var _ SessionActions = (*dbddlTestFake)(nil) +var _ DBDDLPlugin = (*dbddlTestFake)(nil) + +func TestDBDDLCreateExecute(t *testing.T) { + fake := &dbddlTestFake{ + pluginName: "plugin", + oldKS: "ks", + setTargetError: fmt.Errorf("oh noes"), + } + + databaseCreatorPlugins["plugin"] = fake + + primitive := &DBDDL{ + name: "basedata", + create: true, + } + + canStop := sync2.AtomicBool{} + canStop.Set(false) + + go func() { + _, err := primitive.Execute(fake, nil, false) + require.NoError(t, err) + require.True(t, canStop.Get()) + }() + + time.Sleep(1 * time.Second) + canStop.Set(true) + fake.setTargetError = nil +} diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index e52932179f3..dacb2491fcb 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -205,7 +205,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_NOT_FOUND, vterrors.DbDropExists, "Can't drop database '%s'; database doesn't exists", ksName) } - return engine.CreateDropCreateDatabase(ksName, false), nil + return engine.NewDBDDL(ksName, false), nil case *sqlparser.AlterDatabase: if !ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_NOT_FOUND, vterrors.BadDb, "Can't alter database '%s'; unknown database", ksName) @@ -218,7 +218,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !dbDDL.IfNotExists && ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_ALREADY_EXISTS, vterrors.DbCreateExists, "Can't create database '%s'; database exists", ksName) } - return engine.CreateDropCreateDatabase(ksName, true), nil + return engine.NewDBDDL(ksName, true), nil } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] database ddl not recognized: %s", sqlparser.String(dbDDLstmt)) } From 90b697d7dc4e9fb0af3bb5d92f0f1aa0332a1b45 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 3 Mar 2021 19:10:34 +0100 Subject: [PATCH 10/23] implemented more of the primitive Signed-off-by: Andres Taylor --- go/test/endtoend/cluster/cluster_process.go | 2 +- .../vtgate/createdb_plugin/main_test.go | 1 + go/vt/vtgate/engine/dbddl.go | 62 ++++++++++++++----- go/vt/vtgate/engine/dbddl_plugin.go | 4 +- 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index c92de019d90..d7a0ce7035d 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -42,7 +42,7 @@ const ( ) var ( - keepData = flag.Bool("keep-data", false, "don't delete the per-test VTDATAROOT subfolders") + keepData = flag.Bool("keep-data", true, "don't delete the per-test VTDATAROOT subfolders") topoFlavor = flag.String("topo-flavor", "etcd2", "choose a topo server from etcd2, zk2 or consul") isCoverage = flag.Bool("is-coverage", false, "whether coverage is required") forceVTDATAROOT = flag.String("force-vtdataroot", "", "force path for VTDATAROOT, which may already be populated") diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 4924f8ab153..0427df1b233 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -106,6 +106,7 @@ func TestDBDDLPluginSync(t *testing.T) { "new database creation failed") // wait until the create database query has returned + wg.Wait() exec(t, conn, `use aaa`) exec(t, conn, `create table t (id bigint primary key)`) diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 4bfcbf19def..b35b70f7501 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -19,10 +19,15 @@ package engine import ( "context" "strings" + "time" - "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" + + "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/srvtopo" - "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/sqltypes" querypb "vitess.io/vitess/go/vt/proto/query" @@ -85,34 +90,57 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b log.Errorf("'%s' database ddl plugin is not registered. Falling back to default plugin", name) plugin = databaseCreatorPlugins[defaultDBDDLPlugin] } + if c.create { - err := plugin.CreateDatabase(vcursor.Context(), c.name) + ctx := vcursor.Context() + err := plugin.CreateDatabase(ctx, c.name) if err != nil { return nil, err } - done := false - oldDb := vcursor.GetKeyspace() - for !done { + var destinations []*srvtopo.ResolvedShard + for { // loop until we have found a valid shard - err := vcursor.Session().SetTarget(c.name) + destinations, _, err = vcursor.ResolveDestinations(c.name, nil, []key.Destination{key.DestinationAllShards{}}) if err == nil { - done = true + break + } + log.Errorf("waiting for db create, step1: %s", err.Error()) + select { + case <-ctx.Done(): //context cancelled + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") + case <-time.After(500 * time.Millisecond): //timeout } - log.Error(err) } - err = vcursor.Session().SetTarget(oldDb) - if err != nil { - return nil, err + var queries []*querypb.BoundQuery + for range destinations { + queries = append(queries, &querypb.BoundQuery{ + Sql: "select 42 from dual where null", + BindVariables: nil, + }) + } + + for { + _, errors := vcursor.ExecuteMultiShard(destinations, queries, false, true) + + for _, err := range errors { + if err != nil { + log.Errorf("waiting for db create, step2: %s", err.Error()) + select { + case <-ctx.Done(): //context cancelled + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") + case <-time.After(500 * time.Millisecond): //timeout + } + continue + } + } + + break } return &sqltypes.Result{RowsAffected: 1}, nil } - err := plugin.DropDatabase(vcursor.Context(), c.name) - if err != nil { - return nil, err - } - return &sqltypes.Result{StatusFlags: mysql.ServerStatusDbDropped}, nil + panic("implement me") } // StreamExecute implements the Primitive interface diff --git a/go/vt/vtgate/engine/dbddl_plugin.go b/go/vt/vtgate/engine/dbddl_plugin.go index cdac65e602d..5be85d3170e 100644 --- a/go/vt/vtgate/engine/dbddl_plugin.go +++ b/go/vt/vtgate/engine/dbddl_plugin.go @@ -48,8 +48,8 @@ func (noOp) DropDatabase(context.Context, string) error { } const ( - faildbDDL = "fail" - noOpdbDDL = "noop" + faildbDDL = "fail" + noOpdbDDL = "noop" defaultDBDDLPlugin = faildbDDL ) From 6657063f0430c385edb1d8f75c065e817b945d59 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 4 Mar 2021 13:12:08 +0530 Subject: [PATCH 11/23] fix the primitive on create db and implement drop db Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/dbddl.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index b35b70f7501..3eb3f3b7cfd 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -91,8 +91,8 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b plugin = databaseCreatorPlugins[defaultDBDDLPlugin] } + ctx := vcursor.Context() if c.create { - ctx := vcursor.Context() err := plugin.CreateDatabase(ctx, c.name) if err != nil { return nil, err @@ -122,25 +122,31 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b for { _, errors := vcursor.ExecuteMultiShard(destinations, queries, false, true) + noErr := true for _, err := range errors { if err != nil { + noErr = false log.Errorf("waiting for db create, step2: %s", err.Error()) select { case <-ctx.Done(): //context cancelled return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") case <-time.After(500 * time.Millisecond): //timeout } - continue + break } } - - break + if noErr { + break + } } - return &sqltypes.Result{RowsAffected: 1}, nil } - panic("implement me") + err := plugin.DropDatabase(ctx, c.name) + if err != nil { + return nil, err + } + return &sqltypes.Result{StatusFlags: sqltypes.ServerStatusDbDropped}, err } // StreamExecute implements the Primitive interface From c77f7c50ca0437f6bfc381822373d3d587142bc5 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 4 Mar 2021 13:12:31 +0530 Subject: [PATCH 12/23] e2e test for drop db Signed-off-by: Harshit Gangal --- go/test/endtoend/cluster/cluster_process.go | 2 +- .../vtgate/createdb_plugin/main_test.go | 49 +++++++++++++------ 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index d7a0ce7035d..c92de019d90 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -42,7 +42,7 @@ const ( ) var ( - keepData = flag.Bool("keep-data", true, "don't delete the per-test VTDATAROOT subfolders") + keepData = flag.Bool("keep-data", false, "don't delete the per-test VTDATAROOT subfolders") topoFlavor = flag.String("topo-flavor", "etcd2", "choose a topo server from etcd2, zk2 or consul") isCoverage = flag.Bool("is-coverage", false, "whether coverage is required") forceVTDATAROOT = flag.String("force-vtdataroot", "", "force path for VTDATAROOT, which may already be populated") diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 0427df1b233..64fac6ed2f6 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -25,7 +25,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql" @@ -98,12 +97,7 @@ func TestDBDDLPluginSync(t *testing.T) { require.EqualValues(t, 1, qr.RowsAffected) }() - keyspace := &cluster.Keyspace{ - Name: "aaa", - } - require.NoError(t, - clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false), - "new database creation failed") + start(t, "aaa") // wait until the create database query has returned wg.Wait() @@ -115,8 +109,38 @@ func TestDBDDLPluginSync(t *testing.T) { exec(t, conn, `drop database aaa`) - // TODO: we should chant down babylon here (aka take down the keyspace with all tablets) - execAssertError(t, conn, "select count(*) from t", `some error`) + shutdown("aaa") + + _, err = conn.ExecuteFetch(`select count(*) from t`, 1000, true) + require.Error(t, err) +} + +func start(t *testing.T, ksName string) { + keyspace := &cluster.Keyspace{ + Name: ksName, + } + require.NoError(t, + clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false), + "new database creation failed") +} + +func shutdown(ksName string) { + for _, ks := range clusterInstance.Keyspaces { + if ks.Name != ksName { + continue + } + for _, shard := range ks.Shards { + for _, tablet := range shard.Vttablets { + if tablet.MysqlctlProcess.TabletUID > 0 { + tablet.MysqlctlProcess.StopProcess() + } + if tablet.MysqlctldProcess.TabletUID > 0 { + tablet.MysqlctldProcess.Stop() + } + tablet.VttabletProcess.TearDown() + } + } + } } func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { @@ -126,13 +150,6 @@ func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { return qr } -func execAssertError(t *testing.T, conn *mysql.Conn, query string, errorString string) { - t.Helper() - _, err := conn.ExecuteFetch(query, 1000, true) - require.Error(t, err) - assert.Contains(t, err.Error(), errorString) -} - func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) From 73eb606274e9ae37007bc23a0344b5102fc62c30 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 4 Mar 2021 14:33:03 +0530 Subject: [PATCH 13/23] fix dbdddl plugin unit test Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/dbddl_test.go | 52 ++++-------------------- go/vt/vtgate/engine/fake_vcursor_test.go | 3 +- 2 files changed, 11 insertions(+), 44 deletions(-) diff --git a/go/vt/vtgate/engine/dbddl_test.go b/go/vt/vtgate/engine/dbddl_test.go index 6cf0dc0ead3..baa4c22f50f 100644 --- a/go/vt/vtgate/engine/dbddl_test.go +++ b/go/vt/vtgate/engine/dbddl_test.go @@ -2,29 +2,15 @@ package engine import ( "context" - "fmt" "testing" - "time" - - "vitess.io/vitess/go/sync2" "github.com/stretchr/testify/require" ) type dbddlTestFake struct { - pluginName, oldKS string - createCalled, dropCalled bool - - setTargetError error - - noopVCursor - targetSet string } -func (d *dbddlTestFake) GetDBDDLPluginName() string { - return d.pluginName -} func (d *dbddlTestFake) CreateDatabase(ctx context.Context, name string) error { d.createCalled = true return nil @@ -35,42 +21,22 @@ func (d *dbddlTestFake) DropDatabase(ctx context.Context, name string) error { return nil } -func (d *dbddlTestFake) Session() SessionActions { - return d -} -func (d *dbddlTestFake) SetTarget(t string) error { - d.targetSet = t - return d.setTargetError -} - -var _ VCursor = (*dbddlTestFake)(nil) -var _ SessionActions = (*dbddlTestFake)(nil) var _ DBDDLPlugin = (*dbddlTestFake)(nil) func TestDBDDLCreateExecute(t *testing.T) { - fake := &dbddlTestFake{ - pluginName: "plugin", - oldKS: "ks", - setTargetError: fmt.Errorf("oh noes"), - } - - databaseCreatorPlugins["plugin"] = fake + pluginName := "fake" + plugin := &dbddlTestFake{} + databaseCreatorPlugins[pluginName] = plugin primitive := &DBDDL{ - name: "basedata", + name: "ks", create: true, } - canStop := sync2.AtomicBool{} - canStop.Set(false) - - go func() { - _, err := primitive.Execute(fake, nil, false) - require.NoError(t, err) - require.True(t, canStop.Get()) - }() + vc := &loggingVCursor{dbDDLPlugin: pluginName} - time.Sleep(1 * time.Second) - canStop.Set(true) - fake.setTargetError = nil + _, err := primitive.Execute(vc, nil, false) + require.NoError(t, err) + require.True(t, plugin.createCalled) + require.False(t, plugin.dropCalled) } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 966e45b39ff..e5b8917c770 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -267,6 +267,7 @@ type loggingVCursor struct { resolvedTargetTabletType topodatapb.TabletType tableRoutes tableRoutes + dbDDLPlugin string } type tableRoutes struct { @@ -513,7 +514,7 @@ func (f *loggingVCursor) FindRoutedTable(tbl sqlparser.TableName) (*vindexes.Tab } func (f *loggingVCursor) GetDBDDLPluginName() string { - panic("implement me") + return f.dbDDLPlugin } func (f *loggingVCursor) nextResult() (*sqltypes.Result, error) { From c8569f07778b006c24d18e5d36fafd6fe8de5499 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 4 Mar 2021 15:07:32 +0530 Subject: [PATCH 14/23] dbddl: code refactor Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/dbddl.go | 10 ++++++++++ go/vt/vtgate/engine/dbddl_plugin.go | 4 ++-- go/vt/vtgate/engine/dbddl_test.go | 19 +++++++++++++++++-- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 3eb3f3b7cfd..aa6d7e41589 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -18,6 +18,7 @@ package engine import ( "context" + "fmt" "strings" "time" @@ -39,6 +40,15 @@ var _ Primitive = (*DBDDL)(nil) //goland:noinspection GoVarAndConstTypeMayBeOmitted var databaseCreatorPlugins = map[string]DBDDLPlugin{} +// DBDDLRegister registers a dbDDL plugin under the specified name. +// A duplicate plugin will generate a panic. +func DBDDLRegister(name string, plugin DBDDLPlugin) { + if _, ok := databaseCreatorPlugins[name]; ok { + panic(fmt.Sprintf("%s is already registered", name)) + } + databaseCreatorPlugins[name] = plugin +} + // DBDDLPlugin is the interface that you need to implement to add a custom CREATE/DROP DATABASE handler type DBDDLPlugin interface { CreateDatabase(ctx context.Context, name string) error diff --git a/go/vt/vtgate/engine/dbddl_plugin.go b/go/vt/vtgate/engine/dbddl_plugin.go index 5be85d3170e..1b132f330a2 100644 --- a/go/vt/vtgate/engine/dbddl_plugin.go +++ b/go/vt/vtgate/engine/dbddl_plugin.go @@ -54,6 +54,6 @@ const ( ) func init() { - databaseCreatorPlugins[faildbDDL] = failDBDDL{} - databaseCreatorPlugins[noOpdbDDL] = noOp{} + DBDDLRegister(faildbDDL, failDBDDL{}) + DBDDLRegister(noOpdbDDL, noOp{}) } diff --git a/go/vt/vtgate/engine/dbddl_test.go b/go/vt/vtgate/engine/dbddl_test.go index baa4c22f50f..bffaa79f720 100644 --- a/go/vt/vtgate/engine/dbddl_test.go +++ b/go/vt/vtgate/engine/dbddl_test.go @@ -24,9 +24,9 @@ func (d *dbddlTestFake) DropDatabase(ctx context.Context, name string) error { var _ DBDDLPlugin = (*dbddlTestFake)(nil) func TestDBDDLCreateExecute(t *testing.T) { - pluginName := "fake" + pluginName := "createFake" plugin := &dbddlTestFake{} - databaseCreatorPlugins[pluginName] = plugin + DBDDLRegister(pluginName, plugin) primitive := &DBDDL{ name: "ks", @@ -40,3 +40,18 @@ func TestDBDDLCreateExecute(t *testing.T) { require.True(t, plugin.createCalled) require.False(t, plugin.dropCalled) } + +func TestDBDDLDropExecute(t *testing.T) { + pluginName := "dropFake" + plugin := &dbddlTestFake{} + DBDDLRegister(pluginName, plugin) + + primitive := &DBDDL{name: "ks"} + + vc := &loggingVCursor{dbDDLPlugin: pluginName} + + _, err := primitive.Execute(vc, nil, false) + require.NoError(t, err) + require.False(t, plugin.createCalled) + require.True(t, plugin.dropCalled) +} From 295f84866e481b72f78c850027f12dcc101911dc Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 4 Mar 2021 19:55:15 +0530 Subject: [PATCH 15/23] added comments to dbddl Signed-off-by: Harshit Gangal --- go/vt/sqlparser/ast.go | 13 +- go/vt/sqlparser/clone.go | 2 + go/vt/sqlparser/parse_test.go | 8 +- go/vt/sqlparser/rewriter.go | 6 + go/vt/sqlparser/sql.go | 3449 ++++++++++++++++----------------- go/vt/sqlparser/sql.y | 8 +- 6 files changed, 1735 insertions(+), 1751 deletions(-) diff --git a/go/vt/sqlparser/ast.go b/go/vt/sqlparser/ast.go index a146d4b792d..48fdd723946 100644 --- a/go/vt/sqlparser/ast.go +++ b/go/vt/sqlparser/ast.go @@ -17,7 +17,6 @@ limitations under the License. package sqlparser import ( - "fmt" "strings" "vitess.io/vitess/go/sqltypes" @@ -342,6 +341,7 @@ type ( // DropDatabase represents a DROP database statement. DropDatabase struct { + Comments Comments DBName string IfExists bool } @@ -358,6 +358,7 @@ type ( // CreateDatabase represents a CREATE database statement. CreateDatabase struct { + Comments Comments DBName string IfNotExists bool CreateOptions []CollateAndCharset @@ -1998,9 +1999,9 @@ func (node *SetTransaction) Format(buf *TrackedBuffer) { func (node *DropDatabase) Format(buf *TrackedBuffer) { exists := "" if node.IfExists { - exists = " if exists" + exists = "if exists " } - buf.WriteString(fmt.Sprintf("%s database%s %v", DropStr, exists, node.DBName)) + buf.astPrintf(node, "%s database %v%s%s", DropStr, node.Comments, exists, node.DBName) } // Format formats the node. @@ -3163,11 +3164,11 @@ func (node *SelectInto) Format(buf *TrackedBuffer) { // Format formats the node. func (node *CreateDatabase) Format(buf *TrackedBuffer) { - buf.WriteString("create database") + buf.astPrintf(node, "create database %v", node.Comments) if node.IfNotExists { - buf.WriteString(" if not exists") + buf.WriteString("if not exists ") } - buf.astPrintf(node, " %s", node.DBName) + buf.astPrintf(node, "%s", node.DBName) if node.CreateOptions != nil { for _, createOption := range node.CreateOptions { if createOption.IsDefault { diff --git a/go/vt/sqlparser/clone.go b/go/vt/sqlparser/clone.go index 7999702feb7..d0e31ba6346 100644 --- a/go/vt/sqlparser/clone.go +++ b/go/vt/sqlparser/clone.go @@ -994,6 +994,7 @@ func CloneRefOfCreateDatabase(n *CreateDatabase) *CreateDatabase { return nil } out := *n + out.Comments = CloneComments(n.Comments) out.CreateOptions = CloneSliceOfCollateAndCharset(n.CreateOptions) return &out } @@ -1004,6 +1005,7 @@ func CloneRefOfDropDatabase(n *DropDatabase) *DropDatabase { return nil } out := *n + out.Comments = CloneComments(n.Comments) return &out } diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 24495dddae0..9109af17300 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1751,12 +1751,12 @@ var ( }, { input: "rollback", }, { - input: "create database test_db", + input: "create database /* simple */ test_db", }, { input: "create schema test_db", output: "create database test_db", }, { - input: "create database if not exists test_db", + input: "create database /* simple */ if not exists test_db", }, { input: "create schema if not exists test_db", output: "create database if not exists test_db", @@ -1772,12 +1772,12 @@ var ( input: "CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysql` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;", output: "create database if not exists mysql default character set utf8mb4 collate utf8mb4_0900_ai_ci", }, { - input: "drop database test_db", + input: "drop database /* simple */ test_db", }, { input: "drop schema test_db", output: "drop database test_db", }, { - input: "drop database if exists test_db", + input: "drop database /* simple */ if exists test_db", }, { input: "delete a.*, b.* from tbl_a a, tbl_b b where a.id = b.id and b.name = 'test'", output: "delete a, b from tbl_a as a, tbl_b as b where a.id = b.id and b.`name` = 'test'", diff --git a/go/vt/sqlparser/rewriter.go b/go/vt/sqlparser/rewriter.go index 18cefa42fca..3a3d7099ac8 100644 --- a/go/vt/sqlparser/rewriter.go +++ b/go/vt/sqlparser/rewriter.go @@ -249,6 +249,9 @@ func (a *application) apply(parent, node SQLNode, replacer replacerFunc) { parent.(*ConvertUsingExpr).Expr = newNode.(Expr) }) case *CreateDatabase: + a.apply(node, n.Comments, func(newNode, parent SQLNode) { + parent.(*CreateDatabase).Comments = newNode.(Comments) + }) case *CreateTable: a.apply(node, n.Table, func(newNode, parent SQLNode) { parent.(*CreateTable).Table = newNode.(TableName) @@ -308,6 +311,9 @@ func (a *application) apply(parent, node SQLNode, replacer replacerFunc) { parent.(*DropColumn).Name = newNode.(*ColName) }) case *DropDatabase: + a.apply(node, n.Comments, func(newNode, parent SQLNode) { + parent.(*DropDatabase).Comments = newNode.(Comments) + }) case *DropKey: case *DropTable: a.apply(node, n.FromTables, func(newNode, parent SQLNode) { diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 7e9f2d04c45..9dffb61ccb2 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1131,565 +1131,516 @@ var yyExca = [...]int{ -1, 755, 118, 1105, -2, 915, - -1, 790, + -1, 789, 175, 37, 180, 37, -2, 240, - -1, 869, + -1, 868, 1, 371, 468, 371, -2, 117, - -1, 1105, + -1, 1104, 1, 267, 468, 267, -2, 117, - -1, 1183, + -1, 1182, 169, 229, 170, 229, -2, 318, - -1, 1192, + -1, 1191, 175, 38, 180, 38, -2, 241, - -1, 1400, + -1, 1399, 150, 948, -2, 944, - -1, 1492, + -1, 1491, 74, 65, 82, 65, -2, 69, - -1, 1513, + -1, 1512, 1, 268, 468, 268, -2, 117, - -1, 1921, + -1, 1923, 5, 812, 18, 812, 20, 812, 32, 812, 83, 812, -2, 596, - -1, 2133, + -1, 2135, 46, 886, -2, 884, } const yyPrivate = 57344 -const yyLast = 27803 +const yyLast = 27560 var yyAct = [...]int{ - 570, 2214, 2201, 2133, 1834, 2178, 1803, 2142, 514, 1724, - 1973, 2062, 543, 2084, 1901, 927, 1510, 1691, 1008, 1902, - 529, 1437, 1970, 1725, 1898, 1576, 81, 3, 1528, 1167, - 582, 1711, 1543, 1060, 1548, 1053, 512, 1788, 759, 1162, - 1789, 1489, 820, 1913, 1807, 1860, 1208, 1394, 176, 1651, - 908, 188, 1787, 477, 188, 1626, 1550, 1301, 1781, 493, - 881, 188, 1574, 616, 1386, 1097, 79, 1190, 1090, 188, - 785, 1478, 1471, 1063, 131, 591, 1080, 1058, 1439, 1081, - 1083, 1046, 32, 505, 1420, 145, 516, 576, 1363, 944, - 493, 1280, 1197, 493, 188, 493, 798, 766, 771, 1166, - 763, 1454, 786, 787, 767, 613, 1087, 791, 1539, 1096, - 1494, 788, 77, 925, 1306, 875, 148, 108, 109, 862, - 1070, 1182, 114, 1094, 1529, 115, 775, 1021, 500, 76, - 8, 7, 175, 6, 1022, 1826, 1825, 1605, 2086, 1848, - 1849, 1267, 1352, 177, 178, 179, 1434, 1435, 1351, 1350, - 1349, 1348, 1347, 503, 2170, 504, 1689, 1340, 598, 602, - 577, 110, 2130, 760, 2041, 2108, 1947, 116, 2107, 2057, - 824, 188, 2058, 2220, 823, 2175, 822, 453, 2213, 2153, - 82, 188, 1641, 874, 2204, 78, 188, 1974, 1593, 836, - 837, 501, 840, 841, 842, 843, 945, 2174, 846, 847, - 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, - 858, 859, 860, 610, 617, 802, 84, 85, 86, 87, - 88, 89, 825, 1877, 110, 779, 778, 2005, 777, 2152, - 801, 1690, 1168, 1612, 1927, 780, 945, 1611, 915, 1847, - 917, 833, 34, 1639, 1495, 70, 38, 39, 1504, 826, - 827, 828, 900, 1553, 1755, 1928, 1929, 1754, 174, 901, - 1756, 955, 555, 169, 561, 562, 559, 560, 1436, 558, - 557, 556, 102, 838, 1505, 1506, 481, 914, 916, 563, - 564, 1098, 105, 1099, 182, 183, 923, 894, 111, 574, - 133, 573, 110, 839, 1772, 169, 781, 888, 889, 153, - 877, 955, 1522, 2120, 970, 969, 979, 980, 972, 973, - 974, 975, 976, 977, 978, 971, 1836, 69, 981, 1996, - 111, 1341, 1342, 1343, 1994, 1339, 491, 105, 480, 97, - 143, 153, 1552, 495, 100, 132, 943, 99, 98, 103, - 177, 178, 179, 105, 170, 2155, 489, 1397, 902, 1808, - 1575, 951, 886, 150, 1608, 151, 887, 888, 889, 1257, - 120, 121, 142, 141, 168, 922, 1286, 1281, 2203, 1830, - 863, 921, 1759, 907, 2171, 913, 895, 1831, 912, 918, - 905, 906, 903, 904, 103, 150, 1839, 151, 1837, 1620, - 870, 951, 845, 1289, 911, 1290, 168, 1291, 844, 1838, - 1285, 1258, 1283, 1259, 481, 2104, 2052, 481, 1577, 809, - 1472, 818, 137, 118, 144, 125, 117, 807, 138, 139, - 1287, 817, 154, 816, 815, 814, 813, 812, 811, 806, - 782, 2053, 159, 126, 1946, 1176, 819, 764, 1861, 104, - 2221, 1284, 794, 2190, 800, 764, 898, 129, 127, 122, - 123, 124, 128, 188, 154, 793, 480, 119, 764, 480, - 1495, 107, 762, 876, 159, 604, 130, 173, 776, 2218, - 1840, 919, 1599, 1610, 1196, 1195, 1294, 1797, 493, 493, - 493, 1863, 1769, 1764, 104, 931, 829, 950, 947, 948, - 949, 954, 956, 953, 920, 952, 493, 493, 2151, 1554, - 104, 810, 946, 1640, 800, 1607, 800, 1625, 1423, 808, - 481, 1886, 1885, 1884, 774, 884, 2121, 890, 891, 892, - 893, 2143, 1692, 1694, 937, 773, 1765, 950, 947, 948, - 949, 954, 956, 953, 146, 952, 800, 924, 835, 1865, - 772, 1869, 946, 1864, 800, 1862, 1818, 873, 1767, 770, - 1867, 1762, 452, 180, 2156, 2137, 1628, 1619, 867, 1866, - 1618, 1627, 480, 1763, 71, 1511, 146, 1269, 1268, 1270, - 1271, 1272, 1868, 1870, 188, 1595, 897, 2025, 1670, 799, - 1926, 800, 993, 994, 1716, 803, 793, 140, 899, 1659, - 585, 1585, 928, 929, 885, 804, 1500, 1074, 991, 134, - 1006, 493, 135, 1628, 188, 1051, 188, 188, 1627, 493, - 1050, 879, 981, 805, 1751, 493, 2216, 1667, 1693, 2217, - 1450, 2215, 1770, 1768, 613, 1336, 961, 1009, 940, 938, - 909, 939, 92, 177, 178, 179, 2112, 869, 864, 799, - 865, 799, 1307, 866, 1879, 803, 793, 1079, 793, 796, - 797, 883, 764, 821, 1047, 804, 790, 794, 1911, 1282, - 509, 974, 975, 976, 977, 978, 971, 1064, 1100, 981, - 971, 799, 941, 981, 868, 789, 1421, 93, 1677, 799, - 958, 834, 1421, 1173, 1024, 1026, 1028, 1030, 1032, 1034, - 1035, 1025, 1027, 1777, 1031, 1033, 961, 1036, 1592, 1594, - 1590, 1044, 1587, 147, 152, 149, 155, 156, 157, 158, - 160, 161, 162, 163, 809, 807, 799, 993, 994, 164, - 165, 166, 167, 793, 796, 797, 1591, 764, 1067, 1766, - 1931, 790, 794, 617, 1370, 147, 152, 149, 155, 156, - 157, 158, 160, 161, 162, 163, 910, 2040, 1368, 1369, - 1367, 164, 165, 166, 167, 2039, 993, 994, 1308, 188, - 1052, 1587, 1665, 1158, 882, 177, 178, 179, 2208, 1388, - 1664, 960, 958, 1169, 1170, 1171, 1172, 972, 973, 974, - 975, 976, 977, 978, 971, 1589, 2222, 981, 961, 493, - 2008, 1192, 1358, 1360, 1361, 959, 960, 958, 2205, 1201, - 2195, 1455, 1456, 1205, 1359, 1952, 493, 493, 1888, 493, - 1202, 493, 493, 961, 493, 493, 493, 493, 493, 493, - 1644, 1645, 1646, 1174, 1175, 1389, 2206, 1188, 2196, 493, - 1785, 172, 1784, 188, 1241, 1236, 1237, 970, 969, 979, - 980, 972, 973, 974, 975, 976, 977, 978, 971, 1254, - 1095, 981, 1557, 1210, 2223, 1211, 1889, 1213, 1215, 1181, - 493, 1219, 1221, 1223, 1225, 1227, 1200, 1238, 188, 1277, - 1262, 1261, 1276, 959, 960, 958, 188, 1260, 1300, 1252, - 188, 1244, 1245, 959, 960, 958, 1452, 1250, 1251, 1164, - 1199, 961, 1246, 1198, 1198, 1157, 188, 1165, 177, 178, - 179, 961, 1758, 188, 1786, 1178, 1179, 1243, 1242, 1177, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 493, - 493, 493, 69, 1191, 959, 960, 958, 769, 959, 960, - 958, 1275, 1881, 1666, 1366, 1217, 1062, 1309, 1310, 603, - 608, 2207, 961, 1303, 188, 2197, 961, 1274, 2186, 1451, - 2075, 1314, 1910, 2037, 1239, 1311, 1264, 2013, 1321, 177, - 178, 179, 1315, 1569, 1317, 1318, 1319, 1320, 1934, 1322, - 177, 178, 179, 1890, 959, 960, 958, 1364, 1794, 177, - 178, 179, 1387, 1567, 1782, 1635, 110, 779, 778, 1295, - 1603, 1390, 961, 970, 969, 979, 980, 972, 973, 974, - 975, 976, 977, 978, 971, 493, 1273, 981, 177, 178, - 179, 1313, 1255, 1602, 1833, 1263, 1304, 959, 960, 958, - 1265, 1253, 1398, 1409, 1412, 1249, 1248, 605, 606, 1422, - 1391, 1392, 1332, 1333, 1334, 961, 1247, 586, 493, 493, - 1959, 2189, 2102, 1404, 1959, 2149, 1959, 2138, 2101, 188, - 1346, 1365, 1652, 1972, 532, 531, 534, 535, 536, 537, - 1959, 586, 493, 533, 1399, 538, 1959, 2110, 1444, 188, - 1400, 1810, 493, 80, 78, 1009, 188, 1796, 188, 2055, - 586, 1445, 1587, 586, 2023, 586, 188, 188, 1428, 1429, - 1398, 1457, 1519, 493, 1959, 1964, 493, 979, 980, 972, - 973, 974, 975, 976, 977, 978, 971, 493, 613, 981, - 1899, 613, 1490, 1944, 1943, 1940, 1941, 1940, 1939, 1910, - 1401, 969, 979, 980, 972, 973, 974, 975, 976, 977, - 978, 971, 1469, 2020, 981, 1463, 586, 1712, 1400, 1463, - 1465, 1495, 1827, 1161, 1812, 1515, 1805, 1806, 1464, 1530, - 1531, 1532, 586, 1523, 34, 1524, 1525, 1526, 1527, 1475, - 586, 1496, 493, 1496, 957, 586, 188, 1161, 1160, 493, - 1712, 1535, 1536, 1537, 1538, 1566, 1568, 1518, 995, 996, - 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 493, 1545, - 1551, 1514, 1467, 1493, 493, 1106, 1105, 1474, 1201, 1498, - 1201, 957, 34, 1502, 34, 2042, 1475, 1745, 1586, 1517, - 1516, 2111, 1959, 1588, 1942, 1495, 1501, 617, 1463, 1475, - 617, 1503, 1682, 1497, 1232, 1497, 1573, 1719, 1681, 69, - 579, 1499, 1463, 1495, 1587, 1570, 1453, 1432, 493, 1910, - 1387, 1344, 1293, 1092, 784, 1387, 1387, 783, 1475, 2141, - 1720, 69, 2091, 2043, 2044, 2045, 1558, 2064, 1546, 1971, - 2031, 571, 1541, 1542, 1556, 1583, 1555, 1584, 1587, 1562, - 1563, 1564, 1233, 1234, 1235, 2210, 1596, 69, 1163, 69, - 188, 1544, 1832, 802, 188, 188, 188, 188, 188, 1582, - 1580, 1579, 1546, 1198, 188, 188, 188, 188, 801, 1578, - 1540, 1597, 1534, 1533, 1598, 69, 1279, 188, 1193, 1600, - 1601, 1189, 189, 1159, 188, 189, 94, 1791, 174, 1835, - 494, 2046, 189, 2065, 1790, 1480, 1483, 1484, 1485, 1481, - 189, 1482, 1486, 1229, 1168, 1914, 1915, 2202, 188, 493, - 1480, 1483, 1484, 1485, 1481, 1917, 1482, 1486, 1914, 1915, - 1061, 494, 1899, 1801, 494, 189, 494, 1800, 1405, 1406, - 1799, 1560, 1411, 1414, 1415, 1920, 2047, 2048, 1337, 1791, - 1630, 1631, 1296, 1919, 1733, 1633, 1736, 1732, 1230, 1231, - 1364, 1737, 1634, 1734, 2192, 2173, 1606, 1427, 1735, 1891, - 1430, 1431, 1701, 2024, 1962, 965, 1738, 968, 1484, 1485, - 1710, 1709, 1623, 982, 983, 984, 985, 986, 987, 988, - 2161, 966, 967, 964, 970, 969, 979, 980, 972, 973, - 974, 975, 976, 977, 978, 971, 2158, 2194, 981, 596, - 592, 2177, 189, 188, 1638, 1661, 96, 2179, 1699, 2185, - 101, 188, 189, 2184, 2134, 593, 1700, 189, 2132, 1795, - 1292, 572, 1417, 831, 1365, 830, 1647, 1983, 1790, 1054, - 1846, 2089, 930, 1820, 1819, 188, 111, 1418, 1065, 1066, - 595, 1055, 594, 1936, 1935, 1581, 188, 188, 188, 188, - 188, 1698, 1207, 1726, 577, 1206, 181, 171, 188, 1660, - 184, 1194, 188, 1705, 2018, 188, 188, 1448, 1721, 188, - 188, 188, 1717, 1565, 1676, 1299, 1714, 1455, 1456, 2103, - 2059, 1488, 1757, 1047, 1688, 1708, 1402, 1403, 1743, 1696, - 580, 581, 1643, 1707, 583, 2199, 2198, 2182, 2162, 2017, - 1776, 1704, 1958, 1571, 596, 592, 1746, 1713, 584, 80, - 1748, 1715, 2016, 1894, 1712, 1775, 1671, 1778, 1779, 1780, - 593, 1668, 1727, 1773, 1774, 1730, 1728, 1729, 1739, 1731, - 1446, 188, 2212, 2211, 1303, 1744, 1075, 1068, 1749, 1752, - 2212, 2135, 493, 589, 590, 595, 1933, 594, 493, 1551, - 1449, 493, 579, 1201, 1809, 78, 1761, 1813, 493, 83, - 75, 1, 465, 1783, 1433, 1793, 1045, 476, 2200, 1760, - 1824, 1815, 1266, 1256, 1975, 2061, 1792, 1965, 188, 1549, - 792, 136, 1512, 1513, 2145, 1823, 91, 757, 90, 795, - 896, 1572, 2056, 1771, 1362, 1521, 188, 1371, 1372, 1373, - 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, - 1384, 1385, 1822, 1399, 1112, 1181, 1110, 1111, 1109, 1400, - 1814, 1114, 1113, 1108, 1338, 490, 1487, 1101, 1069, 1821, - 493, 832, 455, 1945, 1335, 1604, 1387, 461, 989, 1706, - 1753, 614, 607, 1905, 2183, 1857, 2159, 1842, 2157, 1841, - 1844, 2131, 2085, 1845, 1424, 2160, 2129, 2193, 2176, 1520, - 1447, 1057, 2015, 1893, 1858, 1675, 493, 1859, 1850, 1018, - 1419, 1084, 515, 1443, 1357, 530, 1856, 188, 1878, 527, - 528, 1458, 1872, 1718, 189, 963, 513, 493, 507, 1076, - 1479, 1477, 1476, 493, 493, 1297, 1088, 1916, 1726, 1900, - 1871, 1912, 1857, 1903, 1082, 1462, 1609, 1829, 942, 494, - 494, 494, 1887, 1656, 1657, 588, 188, 502, 1897, 95, - 1416, 2119, 1642, 2004, 587, 60, 1909, 494, 494, 37, - 497, 2169, 933, 597, 1674, 31, 30, 29, 28, 23, - 1908, 22, 21, 20, 1918, 19, 1922, 25, 1924, 18, - 1925, 17, 16, 106, 47, 44, 42, 1923, 113, 112, - 1937, 1938, 45, 41, 871, 27, 1953, 26, 188, 15, - 188, 188, 188, 14, 13, 12, 493, 11, 10, 9, - 5, 4, 936, 24, 1007, 2, 0, 1961, 0, 188, - 0, 0, 0, 0, 0, 0, 0, 1949, 0, 1948, - 0, 586, 0, 1950, 1951, 189, 1976, 493, 493, 493, - 0, 188, 1551, 1966, 1960, 1930, 0, 1963, 0, 0, - 1984, 0, 0, 0, 0, 0, 0, 1968, 0, 0, - 0, 0, 494, 0, 0, 189, 1969, 189, 189, 0, - 494, 0, 0, 0, 0, 0, 494, 970, 969, 979, - 980, 972, 973, 974, 975, 976, 977, 978, 971, 1987, - 0, 981, 0, 0, 0, 0, 0, 0, 1992, 1654, - 0, 1989, 1990, 1655, 1991, 1981, 1982, 1993, 0, 1995, - 0, 0, 0, 0, 1662, 1663, 0, 0, 2014, 1726, - 1669, 0, 0, 1672, 1673, 2019, 0, 0, 0, 0, - 0, 1679, 0, 1680, 2028, 0, 1683, 1684, 1685, 1686, - 1687, 0, 0, 2027, 0, 0, 0, 0, 0, 0, - 0, 0, 1697, 0, 2035, 2034, 2033, 0, 0, 493, - 493, 0, 0, 0, 0, 2050, 0, 0, 2036, 0, - 2038, 0, 493, 0, 0, 493, 600, 2049, 2060, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2063, 2068, 0, 0, 0, 0, 0, 0, 1741, 1742, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 493, 493, 493, 188, 0, 0, 2078, 2080, 2081, 2067, - 189, 0, 0, 2066, 493, 0, 493, 0, 0, 1648, - 1649, 1650, 493, 1903, 2082, 2074, 2088, 1903, 2097, 2094, - 2090, 506, 2083, 0, 0, 0, 0, 0, 0, 2092, - 494, 0, 0, 2099, 188, 2100, 0, 0, 2096, 0, - 0, 0, 0, 0, 2098, 493, 188, 494, 494, 0, - 494, 2113, 494, 494, 0, 494, 494, 494, 494, 494, - 494, 2106, 0, 0, 0, 0, 2109, 0, 0, 0, - 494, 0, 0, 0, 189, 0, 0, 0, 0, 542, - 2128, 0, 0, 0, 1903, 0, 2136, 0, 0, 0, - 0, 0, 493, 493, 0, 0, 0, 0, 0, 0, - 0, 494, 0, 2144, 2002, 0, 0, 2063, 2146, 189, - 2139, 0, 0, 0, 0, 0, 0, 189, 493, 0, - 0, 189, 493, 2154, 1726, 2163, 0, 2165, 2168, 0, - 187, 0, 0, 488, 2172, 0, 0, 189, 0, 0, - 187, 2181, 2180, 0, 189, 1854, 1855, 0, 187, 2007, - 0, 189, 189, 189, 189, 189, 189, 189, 189, 189, - 494, 494, 494, 2191, 601, 601, 0, 0, 0, 0, - 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2209, 0, 189, 0, 0, 0, 0, - 0, 0, 0, 0, 2219, 0, 970, 969, 979, 980, - 972, 973, 974, 975, 976, 977, 978, 971, 0, 0, - 981, 1906, 0, 970, 969, 979, 980, 972, 973, 974, - 975, 976, 977, 978, 971, 0, 0, 981, 0, 0, - 0, 0, 1921, 970, 969, 979, 980, 972, 973, 974, - 975, 976, 977, 978, 971, 0, 494, 981, 0, 0, - 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 0, 0, 0, 0, 187, 0, 0, 0, 0, - 0, 0, 0, 177, 178, 179, 0, 0, 0, 494, - 494, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 0, 0, 1852, 1853, 0, 0, 0, 0, 0, - 0, 0, 2001, 494, 0, 0, 0, 0, 1873, 1874, - 189, 1875, 1876, 494, 0, 0, 0, 189, 0, 189, - 0, 0, 1882, 1883, 0, 0, 0, 189, 189, 0, - 0, 0, 0, 470, 494, 0, 0, 494, 0, 0, - 0, 0, 469, 0, 0, 1986, 0, 169, 494, 1988, - 0, 0, 467, 0, 0, 0, 0, 0, 0, 0, - 1997, 1998, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 111, 0, 0, 0, 2012, 0, 0, 0, - 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, - 0, 464, 0, 2021, 2022, 0, 0, 2026, 0, 0, - 475, 0, 0, 494, 0, 1932, 0, 189, 0, 0, - 494, 970, 969, 979, 980, 972, 973, 974, 975, 976, - 977, 978, 971, 0, 0, 981, 0, 0, 0, 494, - 0, 0, 0, 0, 0, 494, 0, 150, 0, 151, - 0, 0, 0, 481, 0, 0, 0, 0, 168, 0, - 0, 0, 0, 0, 2054, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 962, 0, 0, 0, 0, - 454, 456, 457, 2000, 473, 474, 482, 0, 0, 494, - 471, 472, 483, 458, 459, 487, 486, 0, 463, 460, - 462, 468, 1985, 0, 0, 480, 466, 484, 2079, 0, - 0, 506, 0, 0, 0, 0, 154, 0, 0, 0, - 1019, 0, 0, 0, 0, 0, 159, 0, 0, 0, - 0, 189, 0, 0, 0, 189, 189, 189, 189, 189, - 0, 0, 187, 0, 0, 189, 189, 189, 189, 0, - 1056, 1059, 0, 0, 0, 0, 0, 0, 189, 0, - 0, 0, 0, 0, 0, 189, 0, 0, 2115, 2116, - 2117, 2118, 0, 2122, 0, 2123, 2124, 2125, 0, 2126, - 2127, 0, 0, 0, 0, 0, 0, 0, 1999, 189, - 494, 0, 970, 969, 979, 980, 972, 973, 974, 975, - 976, 977, 978, 971, 0, 0, 981, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2150, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 146, 0, - 0, 485, 0, 0, 0, 0, 0, 0, 0, 544, - 33, 0, 0, 0, 0, 0, 0, 0, 0, 478, - 2069, 2070, 2071, 2072, 2073, 0, 0, 0, 2076, 2077, - 0, 0, 0, 187, 479, 2187, 2188, 0, 0, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 601, 0, - 0, 541, 0, 0, 189, 0, 0, 0, 0, 0, - 0, 0, 189, 187, 0, 187, 1091, 970, 969, 979, - 980, 972, 973, 974, 975, 976, 977, 978, 971, 0, - 0, 981, 0, 0, 0, 0, 189, 578, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 189, 189, - 189, 189, 0, 1851, 0, 0, 0, 0, 0, 189, - 492, 0, 0, 189, 0, 0, 189, 189, 0, 0, - 189, 189, 189, 970, 969, 979, 980, 972, 973, 974, - 975, 976, 977, 978, 971, 0, 0, 981, 0, 0, - 0, 615, 0, 0, 761, 0, 768, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2166, 0, 0, 0, 0, 0, 147, 152, 149, - 155, 156, 157, 158, 160, 161, 162, 163, 0, 0, - 0, 0, 189, 164, 165, 166, 167, 0, 0, 0, - 0, 0, 0, 494, 0, 0, 0, 0, 0, 494, - 0, 0, 494, 0, 0, 0, 0, 0, 0, 494, - 34, 35, 36, 70, 38, 39, 0, 0, 187, 0, - 1305, 0, 0, 0, 0, 0, 0, 0, 1653, 189, - 74, 0, 0, 0, 0, 40, 66, 67, 0, 64, - 68, 0, 0, 0, 0, 0, 65, 189, 970, 969, - 979, 980, 972, 973, 974, 975, 976, 977, 978, 971, - 0, 1204, 981, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 53, 0, 0, 0, 0, - 0, 494, 0, 0, 0, 69, 1204, 1204, 0, 0, - 0, 0, 187, 0, 1353, 1354, 1355, 1356, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 494, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 187, 189, 0, - 0, 0, 0, 0, 0, 187, 0, 0, 494, 1302, - 0, 0, 0, 0, 494, 494, 0, 0, 0, 1407, - 1408, 0, 0, 0, 0, 187, 0, 43, 46, 49, - 48, 51, 187, 63, 0, 0, 0, 189, 0, 1323, - 1324, 187, 187, 187, 187, 187, 187, 187, 0, 0, - 0, 0, 0, 0, 0, 0, 506, 0, 52, 73, - 72, 0, 0, 61, 62, 50, 0, 0, 0, 0, - 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, - 0, 189, 189, 189, 0, 0, 0, 494, 0, 0, - 54, 55, 0, 56, 57, 58, 59, 1509, 0, 0, - 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 494, 494, - 494, 0, 189, 0, 0, 601, 1302, 0, 0, 0, - 601, 601, 0, 0, 601, 601, 601, 0, 0, 0, - 1204, 0, 0, 0, 0, 0, 0, 926, 926, 926, - 0, 0, 0, 0, 0, 0, 1547, 0, 0, 601, - 601, 601, 601, 601, 0, 0, 0, 33, 1441, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 990, 992, 0, 0, 0, 0, 0, 0, 187, 615, - 615, 615, 71, 0, 1302, 187, 0, 187, 0, 0, - 0, 0, 0, 0, 0, 187, 187, 932, 934, 0, - 0, 1005, 0, 0, 0, 1010, 1011, 1012, 1013, 1014, - 1015, 1016, 1017, 0, 1020, 1023, 1023, 1023, 1029, 1023, - 1023, 1029, 1023, 1037, 1038, 1039, 1040, 1041, 1042, 1043, - 494, 494, 0, 0, 0, 1049, 0, 0, 33, 0, - 0, 0, 0, 494, 0, 0, 494, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1085, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 0, 1048, 0, 0, + 570, 2216, 2203, 1975, 2180, 2135, 1836, 2144, 1725, 2086, + 926, 1805, 81, 3, 2064, 1692, 1903, 1904, 1007, 543, + 1509, 1436, 1576, 1972, 529, 1726, 1900, 1809, 1052, 1547, + 1542, 1167, 1712, 512, 1527, 1789, 1915, 1790, 514, 1862, + 1059, 1488, 819, 1788, 1652, 907, 1626, 131, 176, 1300, + 1393, 188, 1549, 477, 188, 1189, 616, 1782, 582, 493, + 1574, 188, 759, 1385, 784, 1089, 1079, 1096, 1470, 188, + 1080, 1477, 591, 79, 1057, 1062, 145, 1438, 1082, 576, + 32, 1045, 1419, 505, 1362, 943, 790, 516, 766, 763, + 493, 1166, 880, 493, 188, 493, 797, 1538, 771, 785, + 613, 1196, 1279, 1453, 787, 786, 767, 1493, 1095, 1069, + 77, 1305, 1164, 924, 1086, 874, 1181, 114, 148, 861, + 108, 115, 109, 1020, 1528, 1161, 1093, 76, 500, 82, + 1021, 8, 7, 6, 1828, 1827, 1605, 1850, 2088, 1851, + 1433, 1434, 1351, 175, 1350, 1349, 1348, 1347, 1207, 1266, + 177, 178, 179, 1346, 503, 1690, 504, 760, 577, 2172, + 598, 602, 116, 110, 1339, 84, 85, 86, 87, 88, + 89, 188, 2132, 2043, 2222, 1949, 821, 453, 2110, 2109, + 823, 188, 2059, 873, 822, 2060, 188, 2177, 2215, 835, + 836, 501, 839, 840, 841, 842, 944, 1642, 845, 846, + 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, + 857, 858, 859, 824, 617, 801, 610, 1168, 78, 2155, + 944, 2206, 1422, 800, 1976, 1593, 110, 2176, 778, 2154, + 777, 775, 1879, 776, 2007, 779, 1612, 1691, 1552, 174, + 1611, 832, 825, 826, 827, 1097, 555, 1098, 561, 562, + 559, 560, 1503, 558, 557, 556, 1930, 1931, 481, 1494, + 1929, 954, 1435, 563, 564, 34, 1504, 1505, 70, 38, + 39, 1756, 169, 837, 1755, 1849, 105, 1757, 182, 183, + 1640, 838, 887, 888, 899, 954, 922, 780, 102, 900, + 574, 893, 573, 1773, 110, 1521, 169, 111, 914, 133, + 916, 1998, 1838, 1996, 585, 1396, 491, 1804, 153, 1338, + 480, 2157, 1810, 489, 876, 495, 1575, 1551, 1832, 1608, + 2205, 111, 1280, 133, 105, 170, 1833, 1285, 1340, 1341, + 1342, 862, 153, 103, 904, 905, 942, 913, 915, 143, + 69, 1256, 885, 105, 132, 97, 886, 887, 888, 920, + 100, 950, 1841, 99, 98, 902, 903, 906, 177, 178, + 179, 869, 150, 143, 151, 921, 2106, 1620, 132, 120, + 121, 142, 141, 168, 1839, 950, 844, 1284, 901, 2173, + 894, 1286, 843, 1257, 1840, 1258, 150, 1288, 151, 1289, + 799, 1290, 481, 1183, 1184, 142, 141, 168, 481, 1282, + 103, 2054, 808, 509, 1577, 2122, 969, 968, 978, 979, + 971, 972, 973, 974, 975, 976, 977, 970, 1283, 1471, + 980, 137, 118, 144, 125, 117, 817, 138, 139, 816, + 806, 154, 815, 104, 814, 912, 813, 812, 911, 917, + 600, 159, 126, 1948, 480, 137, 1185, 144, 173, 1182, + 480, 138, 139, 188, 910, 154, 129, 127, 122, 123, + 124, 128, 811, 810, 805, 159, 119, 781, 1175, 1494, + 818, 918, 2055, 107, 2223, 130, 1610, 764, 493, 493, + 493, 104, 793, 2192, 1553, 1625, 764, 949, 946, 947, + 948, 953, 955, 952, 809, 951, 493, 493, 2153, 799, + 104, 919, 945, 792, 764, 506, 897, 2220, 762, 875, + 936, 949, 946, 947, 948, 953, 955, 952, 1641, 951, + 2158, 1863, 807, 1195, 1194, 798, 945, 1165, 481, 1770, + 1765, 834, 792, 795, 796, 604, 764, 799, 1842, 1599, + 789, 793, 1293, 146, 930, 828, 1798, 883, 1607, 889, + 890, 891, 892, 1888, 2145, 1693, 1695, 799, 1887, 788, + 799, 799, 1886, 774, 1865, 1628, 773, 146, 772, 923, + 1627, 1820, 872, 1766, 188, 1268, 1267, 1269, 1270, 1271, + 480, 1628, 770, 452, 180, 1619, 1627, 71, 1618, 992, + 993, 1050, 927, 928, 884, 1768, 140, 2139, 1763, 990, + 1595, 493, 2027, 1928, 188, 1717, 188, 188, 134, 493, + 1764, 135, 1660, 1585, 1499, 493, 1073, 1049, 2123, 613, + 140, 1005, 1867, 878, 1871, 1008, 1866, 1671, 1864, 939, + 937, 938, 134, 1869, 798, 135, 896, 1510, 1668, 980, + 802, 792, 1868, 970, 1752, 1449, 980, 1078, 898, 868, + 803, 1694, 1046, 908, 2218, 1870, 1872, 2219, 882, 2217, + 92, 1335, 960, 1369, 1063, 177, 178, 179, 804, 1771, + 1769, 1306, 798, 957, 833, 2114, 866, 1367, 1368, 1366, + 1023, 1025, 1027, 1029, 1031, 1033, 1034, 1024, 1026, 960, + 1030, 1032, 798, 1035, 820, 798, 798, 1881, 802, 792, + 1913, 1043, 792, 795, 796, 93, 764, 1281, 803, 1051, + 789, 793, 147, 152, 149, 155, 156, 157, 158, 160, + 161, 162, 163, 1099, 1594, 1778, 940, 867, 164, 165, + 166, 167, 1420, 617, 1678, 1420, 147, 152, 149, 155, + 156, 157, 158, 160, 161, 162, 163, 177, 178, 179, + 1559, 1387, 164, 165, 166, 167, 863, 1451, 864, 188, + 1592, 865, 2224, 1157, 1590, 1933, 992, 993, 808, 909, + 806, 881, 1066, 1169, 1170, 1171, 1767, 992, 993, 971, + 972, 973, 974, 975, 976, 977, 970, 1307, 493, 980, + 1191, 973, 974, 975, 976, 977, 970, 1587, 1200, 980, + 1787, 1666, 1204, 1587, 2210, 493, 493, 1388, 493, 1665, + 493, 493, 2207, 493, 493, 493, 493, 493, 493, 2042, + 1450, 1591, 1173, 1174, 958, 959, 957, 1589, 493, 2197, + 2225, 1180, 188, 1240, 958, 959, 957, 959, 957, 1201, + 2208, 2041, 960, 1954, 1786, 958, 959, 957, 1253, 1275, + 1187, 172, 960, 1199, 960, 1454, 1455, 2198, 1785, 493, + 958, 959, 957, 960, 1235, 1236, 1556, 188, 1883, 1276, + 1357, 1359, 1360, 1261, 1260, 188, 1259, 1273, 960, 188, + 1243, 1244, 1358, 958, 959, 957, 1249, 1250, 1172, 1163, + 1237, 69, 1197, 1197, 1061, 188, 1251, 1245, 1198, 1177, + 1178, 960, 188, 1365, 1176, 1242, 1156, 1241, 1274, 188, + 188, 188, 188, 188, 188, 188, 188, 188, 493, 493, + 493, 994, 995, 996, 997, 998, 999, 1000, 1001, 1002, + 1003, 1308, 1309, 1190, 1667, 1302, 1272, 958, 959, 957, + 1645, 1646, 1647, 188, 1094, 1313, 1216, 769, 1853, 961, + 2209, 2199, 1320, 1238, 1209, 960, 1210, 603, 1212, 1214, + 2188, 2077, 1218, 1220, 1222, 1224, 1226, 2039, 969, 968, + 978, 979, 971, 972, 973, 974, 975, 976, 977, 970, + 1890, 1386, 980, 1363, 2015, 506, 1310, 110, 1294, 778, + 1389, 777, 1299, 1314, 1018, 1316, 1317, 1318, 1319, 1835, + 1321, 177, 178, 179, 493, 1759, 1263, 1312, 177, 178, + 179, 1936, 1569, 177, 178, 179, 1397, 1567, 958, 959, + 957, 177, 178, 179, 1055, 1058, 1390, 1391, 1891, 1892, + 1795, 1331, 1332, 1333, 608, 1783, 960, 493, 493, 177, + 178, 179, 1636, 1254, 1603, 605, 606, 1602, 188, 1403, + 1303, 1364, 1408, 1411, 1264, 1398, 1252, 1345, 1421, 1248, + 1247, 493, 1399, 1246, 78, 1262, 586, 1443, 188, 1961, + 2191, 493, 1008, 1961, 2151, 188, 2104, 188, 1961, 2140, + 1961, 586, 1961, 2112, 1397, 188, 188, 2057, 586, 571, + 1427, 1428, 493, 1587, 586, 493, 2103, 1489, 2025, 586, + 1961, 1966, 613, 1946, 1945, 613, 493, 1713, 1444, 1974, + 532, 531, 534, 535, 536, 537, 1713, 1400, 1456, 533, + 1812, 538, 80, 1468, 1942, 1943, 1942, 1941, 1462, 586, + 1399, 1494, 1829, 1160, 1814, 1797, 1464, 1807, 1808, 1518, + 189, 1746, 586, 189, 1474, 586, 34, 1495, 494, 1494, + 189, 956, 586, 1495, 1529, 1530, 1531, 1901, 189, 1160, + 1159, 493, 1105, 1104, 2044, 188, 1912, 1912, 1514, 493, + 1517, 1720, 34, 1565, 1566, 1568, 1474, 1588, 1231, 494, + 1466, 1513, 494, 189, 494, 1912, 1544, 493, 1462, 2022, + 956, 1550, 2113, 493, 1721, 1497, 34, 1200, 1463, 1200, + 1492, 1501, 1473, 1961, 1944, 1516, 1474, 1586, 1502, 1496, + 1683, 1515, 2045, 2046, 2047, 1496, 617, 1498, 1500, 617, + 2093, 69, 1792, 1494, 1682, 1462, 1232, 1233, 1234, 1401, + 1402, 1587, 1587, 1570, 579, 1452, 1431, 493, 1522, 1386, + 1523, 1524, 1525, 1526, 1386, 1386, 1545, 69, 2143, 1573, + 1540, 1541, 1583, 1474, 1584, 1343, 1534, 1535, 1536, 1537, + 189, 1562, 1563, 1564, 1292, 1555, 1557, 1554, 1462, 1091, + 189, 69, 69, 1445, 783, 189, 782, 1578, 2066, 188, + 1545, 1579, 801, 188, 188, 188, 188, 188, 1973, 2033, + 800, 1162, 1197, 188, 188, 188, 188, 1582, 1597, 1596, + 1629, 1791, 1598, 586, 1543, 1834, 188, 1600, 1601, 69, + 1580, 1539, 1533, 188, 1532, 1404, 1405, 1278, 1192, 1410, + 1413, 1414, 1188, 1304, 1158, 969, 968, 978, 979, 971, + 972, 973, 974, 975, 976, 977, 970, 188, 493, 980, + 94, 174, 2048, 2212, 1426, 1228, 1792, 1429, 1430, 969, + 968, 978, 979, 971, 972, 973, 974, 975, 976, 977, + 970, 1916, 1917, 980, 1837, 2067, 1361, 2010, 1168, 1370, + 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, + 1381, 1382, 1383, 1384, 1653, 2194, 1363, 2049, 2050, 2204, + 1229, 1230, 1919, 1606, 1901, 1803, 1802, 1352, 1353, 1354, + 1355, 1631, 1632, 1801, 1560, 1336, 1634, 1295, 1739, 1623, + 1483, 1484, 1922, 1635, 969, 968, 978, 979, 971, 972, + 973, 974, 975, 976, 977, 970, 1423, 1921, 980, 1639, + 1734, 1733, 188, 2175, 1893, 1479, 1482, 1483, 1484, 1480, + 188, 1481, 1485, 1737, 1735, 1916, 1917, 1702, 1738, 1736, + 1060, 1648, 1406, 1407, 1364, 2026, 2179, 1964, 1711, 1710, + 2163, 2160, 1662, 2196, 188, 1479, 1482, 1483, 1484, 1480, + 96, 1481, 1485, 1699, 101, 188, 188, 188, 188, 188, + 1661, 577, 2181, 1722, 1700, 1706, 2187, 188, 2186, 506, + 2136, 188, 1701, 2134, 188, 188, 1291, 572, 188, 188, + 188, 1677, 1718, 1744, 1796, 1715, 830, 1416, 829, 1985, + 1046, 1758, 1727, 1689, 1053, 1791, 1848, 1697, 929, 1822, + 181, 171, 1417, 1821, 184, 111, 1054, 1705, 2091, 1777, + 1938, 1937, 1581, 1206, 1205, 1747, 1193, 1716, 1714, 1749, + 1508, 1728, 189, 2020, 1731, 1447, 1729, 1730, 1776, 1732, + 1779, 1780, 1781, 1454, 1455, 1799, 1302, 1740, 1774, 1775, + 1745, 188, 1298, 2105, 1750, 2061, 1487, 494, 494, 494, + 1753, 1644, 493, 580, 581, 583, 1709, 2201, 493, 1762, + 1550, 493, 2200, 1200, 1708, 494, 494, 2184, 493, 1761, + 2164, 1784, 1815, 2019, 1794, 1960, 1817, 1571, 584, 1546, + 1826, 1793, 80, 2018, 1896, 1713, 2214, 2213, 188, 1672, + 1669, 1074, 1655, 1067, 1811, 2214, 1656, 2137, 1180, 1825, + 1935, 1448, 579, 78, 83, 1824, 188, 1663, 1664, 75, + 1, 465, 1432, 1670, 1044, 1398, 1673, 1674, 1816, 476, + 2202, 1265, 1399, 1255, 1680, 1977, 1681, 2063, 1967, 1684, + 1685, 1686, 1687, 1688, 1548, 791, 136, 1823, 1511, 1512, + 2147, 493, 91, 189, 757, 1698, 90, 1386, 1844, 794, + 1843, 1859, 895, 1572, 2058, 1772, 1846, 1520, 1111, 1847, + 978, 979, 971, 972, 973, 974, 975, 976, 977, 970, + 494, 1861, 980, 189, 1852, 189, 189, 493, 494, 1109, + 1657, 1658, 1860, 1110, 494, 1108, 1113, 1874, 188, 1112, + 1858, 1742, 1743, 1107, 1337, 542, 1880, 490, 493, 1486, + 1100, 1675, 596, 592, 493, 493, 1068, 831, 1859, 1902, + 1873, 455, 1947, 1334, 1604, 461, 988, 1707, 593, 1754, + 614, 1905, 607, 1907, 2185, 2161, 2159, 188, 2133, 2087, + 2162, 596, 592, 2131, 2195, 2178, 1519, 1446, 1911, 1727, + 1056, 1064, 1065, 595, 2017, 594, 187, 593, 1920, 488, + 1895, 1649, 1650, 1651, 1676, 1017, 187, 1899, 1924, 1418, + 1926, 1083, 1927, 515, 187, 1442, 1356, 530, 1925, 527, + 589, 590, 595, 528, 594, 1939, 1940, 1955, 1457, 188, + 601, 601, 188, 188, 188, 1719, 962, 513, 493, 187, + 968, 978, 979, 971, 972, 973, 974, 975, 976, 977, + 970, 188, 507, 980, 1075, 1478, 1951, 1950, 1476, 1475, + 1296, 1087, 1918, 1914, 1952, 1953, 1081, 1932, 1978, 493, + 493, 493, 1968, 188, 1965, 1889, 1550, 1461, 189, 1963, + 1609, 1971, 1986, 1831, 941, 588, 1970, 502, 95, 1415, + 2121, 1679, 1643, 2006, 587, 60, 37, 497, 2171, 932, + 1962, 597, 31, 1910, 30, 29, 28, 494, 23, 22, + 1856, 1857, 21, 20, 19, 25, 187, 18, 17, 16, + 106, 1703, 1704, 1058, 494, 494, 187, 494, 1994, 494, + 494, 187, 494, 494, 494, 494, 494, 494, 47, 44, + 42, 113, 112, 45, 41, 870, 27, 494, 26, 1989, + 15, 189, 14, 13, 12, 11, 2016, 10, 9, 2021, + 5, 4, 935, 24, 1006, 2, 0, 0, 2030, 1983, + 1984, 0, 0, 0, 0, 0, 1908, 0, 494, 0, + 0, 1727, 2029, 0, 0, 0, 189, 0, 2036, 0, + 2037, 493, 493, 0, 189, 2035, 0, 1923, 189, 0, + 0, 0, 2052, 0, 493, 0, 2038, 493, 2040, 0, + 2051, 0, 0, 0, 189, 2062, 0, 2065, 0, 1991, + 1992, 189, 1993, 2070, 0, 1995, 0, 1997, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 494, 494, 494, + 0, 0, 493, 493, 493, 188, 0, 0, 2068, 0, + 0, 0, 0, 2080, 2082, 2083, 493, 2069, 493, 0, + 0, 0, 189, 0, 493, 0, 2084, 2094, 2090, 0, + 2092, 0, 1905, 2096, 0, 2099, 1905, 0, 0, 0, + 2085, 0, 0, 0, 0, 0, 188, 1854, 1855, 2101, + 0, 2102, 0, 0, 0, 2076, 0, 493, 188, 0, + 0, 0, 1875, 1876, 2111, 1877, 1878, 0, 2115, 0, + 2108, 1988, 0, 0, 0, 1990, 1884, 1885, 2098, 0, + 0, 0, 0, 494, 2100, 0, 1999, 2000, 0, 0, + 2130, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2138, 0, 2014, 1905, 493, 493, 0, 0, 2141, 1882, + 0, 0, 0, 0, 2065, 2148, 494, 494, 2146, 2023, + 2024, 0, 0, 2028, 0, 0, 0, 189, 0, 0, + 493, 2156, 0, 0, 493, 0, 2165, 0, 0, 2167, + 494, 0, 0, 0, 1897, 2170, 0, 189, 2174, 0, + 494, 0, 0, 2182, 189, 2183, 189, 0, 187, 1934, + 0, 0, 0, 0, 189, 189, 1727, 0, 2193, 0, + 0, 494, 0, 0, 494, 0, 0, 0, 0, 0, + 2056, 0, 0, 0, 0, 494, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2211, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2221, 0, 0, 964, + 0, 967, 0, 0, 0, 0, 0, 981, 982, 983, + 984, 985, 986, 987, 2081, 965, 966, 963, 969, 968, + 978, 979, 971, 972, 973, 974, 975, 976, 977, 970, + 494, 0, 980, 0, 189, 0, 0, 1987, 494, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 541, 0, + 177, 178, 179, 0, 0, 0, 494, 0, 0, 0, + 0, 0, 494, 0, 0, 0, 0, 0, 0, 187, + 0, 0, 0, 0, 2117, 2118, 2119, 2120, 0, 2124, + 0, 2125, 2126, 2127, 601, 2128, 2129, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 0, 187, 1090, 0, 2008, 0, 494, 492, 0, 0, + 470, 0, 0, 0, 0, 0, 0, 0, 0, 469, + 0, 0, 0, 0, 2152, 0, 0, 506, 0, 467, + 0, 0, 0, 0, 2031, 0, 0, 2032, 615, 0, + 2034, 761, 0, 768, 0, 0, 0, 0, 189, 0, + 0, 0, 189, 189, 189, 189, 189, 0, 0, 0, + 0, 2009, 189, 189, 189, 189, 0, 0, 464, 0, + 0, 2189, 2190, 0, 0, 189, 0, 475, 0, 0, + 0, 0, 189, 0, 0, 2071, 2072, 2073, 2074, 2075, + 0, 0, 0, 2078, 2079, 0, 169, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 494, 969, 968, + 978, 979, 971, 972, 973, 974, 975, 976, 977, 970, + 481, 111, 980, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 153, 0, 0, 0, 0, 0, 0, 2089, + 506, 0, 0, 0, 0, 0, 0, 454, 456, 457, + 0, 473, 474, 482, 187, 0, 0, 471, 472, 483, + 458, 459, 487, 486, 0, 463, 460, 462, 468, 0, + 0, 0, 480, 466, 484, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 150, 0, 151, 0, + 0, 0, 0, 0, 169, 0, 1203, 168, 0, 0, + 0, 189, 0, 0, 0, 0, 0, 0, 0, 189, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 111, + 0, 1203, 1203, 0, 0, 0, 2168, 187, 0, 0, + 153, 0, 0, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 189, 189, 189, 189, 0, + 0, 0, 0, 0, 0, 154, 189, 0, 0, 0, + 189, 0, 187, 189, 189, 159, 0, 189, 189, 189, + 187, 1760, 0, 2004, 1301, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 150, 0, 151, 0, 0, 0, + 187, 0, 0, 0, 0, 168, 0, 187, 485, 0, + 0, 0, 0, 0, 1322, 1323, 187, 187, 187, 187, + 187, 187, 187, 0, 0, 0, 478, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 189, 479, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 494, 0, 0, 0, 0, 0, 494, 0, 0, + 494, 0, 0, 154, 0, 0, 0, 494, 0, 0, + 0, 0, 0, 159, 0, 0, 0, 146, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 189, 0, 0, + 0, 0, 969, 968, 978, 979, 971, 972, 973, 974, + 975, 976, 977, 970, 0, 189, 980, 0, 1047, 0, + 601, 1301, 0, 0, 0, 601, 601, 0, 2003, 601, + 601, 601, 0, 0, 0, 1203, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 615, 615, 615, 0, + 494, 0, 0, 0, 601, 601, 601, 601, 601, 0, + 0, 0, 0, 1440, 931, 933, 0, 0, 0, 186, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 496, + 0, 0, 0, 187, 0, 146, 494, 575, 0, 1301, + 187, 0, 187, 0, 0, 0, 0, 189, 0, 0, + 187, 187, 0, 0, 2002, 0, 0, 494, 0, 0, + 0, 0, 765, 494, 494, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2001, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 544, 33, 189, 969, 968, 978, + 979, 971, 972, 973, 974, 975, 976, 977, 970, 0, + 0, 980, 0, 0, 0, 0, 147, 152, 149, 155, + 156, 157, 158, 160, 161, 162, 163, 0, 33, 1071, + 0, 0, 164, 165, 166, 167, 0, 615, 0, 0, + 187, 0, 0, 1101, 0, 0, 0, 0, 189, 860, + 0, 189, 189, 189, 0, 0, 0, 494, 0, 871, + 0, 0, 0, 0, 877, 0, 0, 0, 0, 0, + 189, 0, 578, 969, 968, 978, 979, 971, 972, 973, + 974, 975, 976, 977, 970, 0, 0, 980, 494, 494, + 494, 0, 189, 969, 968, 978, 979, 971, 972, 973, + 974, 975, 976, 977, 970, 0, 0, 980, 0, 0, + 0, 0, 0, 0, 147, 152, 149, 155, 156, 157, + 158, 160, 161, 162, 163, 0, 0, 0, 0, 0, + 164, 165, 166, 167, 969, 968, 978, 979, 971, 972, + 973, 974, 975, 976, 977, 970, 0, 0, 980, 0, + 0, 0, 0, 0, 187, 0, 0, 0, 187, 187, + 187, 187, 187, 0, 0, 0, 0, 0, 187, 187, + 187, 187, 1654, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 0, 0, 0, 0, 0, 0, 187, 0, + 0, 0, 969, 968, 978, 979, 971, 972, 973, 974, + 975, 976, 977, 970, 0, 0, 980, 0, 0, 0, + 494, 494, 187, 0, 0, 0, 761, 0, 0, 0, + 0, 0, 0, 494, 0, 0, 494, 0, 0, 1202, + 0, 0, 0, 1208, 1208, 0, 1208, 0, 1208, 1208, + 0, 1217, 1208, 1208, 1208, 1208, 1208, 0, 0, 0, + 0, 0, 0, 0, 1202, 1202, 761, 0, 0, 0, 0, 494, 494, 494, 189, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 494, 0, 494, 0, 0, - 0, 0, 1072, 494, 0, 0, 0, 0, 0, 0, - 615, 0, 0, 0, 0, 0, 1102, 0, 0, 0, - 0, 0, 0, 0, 0, 189, 0, 0, 186, 0, - 0, 0, 0, 0, 0, 0, 494, 189, 496, 0, - 0, 0, 0, 0, 0, 0, 575, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 765, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 494, 494, 0, 0, 0, 0, 187, - 0, 0, 0, 187, 187, 187, 187, 187, 0, 0, - 0, 0, 0, 187, 187, 187, 187, 0, 1678, 494, - 0, 0, 0, 494, 0, 0, 187, 0, 0, 0, - 1129, 0, 0, 187, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1702, 1703, - 1059, 0, 0, 0, 0, 0, 0, 187, 861, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 872, 0, - 0, 0, 0, 878, 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, - 761, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1203, 0, 601, 601, 1209, 1209, 0, - 1209, 0, 1209, 1209, 0, 1218, 1209, 1209, 1209, 1209, - 1209, 0, 0, 0, 0, 0, 601, 0, 1203, 1203, - 761, 0, 0, 1117, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 0, 0, 0, 0, 0, 0, 0, - 1441, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1278, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 601, 187, 0, 1130, 0, 926, 926, - 926, 0, 0, 0, 1204, 187, 187, 187, 187, 187, - 0, 0, 0, 0, 0, 0, 0, 1740, 0, 0, - 0, 187, 0, 0, 187, 187, 0, 0, 187, 1750, - 1302, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 615, 615, 615, 1143, 1146, 1147, 1148, 1149, 1150, 1151, - 0, 1152, 1153, 1154, 1155, 1156, 1131, 1132, 1133, 1134, - 1115, 1116, 1144, 0, 1118, 0, 1119, 1120, 1121, 1122, - 1123, 1124, 1125, 1126, 1127, 1128, 1135, 1136, 1137, 1138, - 1139, 1140, 1141, 1142, 1880, 0, 0, 0, 0, 0, - 187, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1204, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1302, 0, 0, 0, 1895, - 0, 0, 0, 0, 0, 0, 1393, 0, 615, 0, - 0, 0, 0, 0, 0, 0, 0, 187, 0, 0, - 0, 0, 1203, 0, 0, 0, 0, 0, 1145, 0, - 880, 0, 0, 0, 0, 187, 0, 0, 0, 1425, - 1426, 0, 0, 0, 0, 1491, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1459, 0, 0, 0, 0, 601, 0, - 0, 0, 0, 1072, 0, 0, 615, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 615, 0, 0, 615, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 761, 0, - 0, 0, 0, 0, 0, 0, 187, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1204, - 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, 187, 0, 0, 0, 0, - 0, 0, 0, 768, 0, 0, 0, 0, 2006, 0, - 1561, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1078, 0, 0, 1089, 0, 0, 0, 0, 761, - 0, 506, 0, 0, 0, 768, 0, 0, 2029, 0, - 0, 2030, 0, 0, 2032, 0, 0, 187, 0, 187, - 187, 187, 0, 0, 0, 0, 0, 0, 1204, 0, - 0, 0, 0, 0, 0, 0, 0, 169, 187, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1802, 761, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 0, 111, 0, 133, 0, 0, 0, 0, 0, - 0, 0, 0, 153, 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, 143, 0, 0, 0, 0, 132, - 0, 0, 0, 2087, 506, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 150, 0, 151, - 1204, 0, 0, 0, 1184, 1185, 142, 141, 168, 0, - 0, 0, 0, 0, 0, 0, 1107, 0, 0, 0, - 1637, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1658, 0, - 0, 578, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 137, 1186, 144, 0, - 1183, 0, 138, 139, 0, 0, 154, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 159, 0, 1695, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1240, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1441, 0, 1085, 0, 0, 0, 0, 0, - 0, 1722, 1723, 0, 0, 1085, 1085, 1085, 1085, 1085, - 0, 0, 0, 0, 0, 1288, 0, 0, 0, 0, - 0, 1491, 0, 1298, 1085, 0, 0, 0, 1085, 0, - 169, 0, 0, 187, 0, 0, 0, 0, 0, 0, - 0, 1180, 0, 1312, 0, 187, 1203, 0, 0, 0, - 1316, 0, 0, 0, 0, 111, 0, 133, 0, 1325, - 1326, 1327, 1328, 1329, 1330, 1331, 153, 0, 146, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1089, 0, 0, 0, 0, 0, 143, 0, 0, - 0, 0, 132, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1204, 0, 0, 1817, 0, - 150, 140, 151, 0, 0, 0, 0, 1184, 1185, 142, - 141, 168, 0, 134, 0, 0, 135, 0, 0, 0, - 0, 0, 0, 1804, 0, 0, 0, 1203, 0, 1811, - 0, 0, 1804, 0, 0, 0, 0, 615, 0, 1816, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 137, - 1186, 144, 0, 1183, 0, 138, 139, 0, 0, 154, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 159, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1466, 0, 0, 0, - 0, 0, 0, 1470, 0, 1473, 0, 0, 0, 0, - 0, 615, 0, 0, 1492, 0, 0, 147, 152, 149, - 155, 156, 157, 158, 160, 161, 162, 163, 0, 0, - 1904, 0, 33, 164, 165, 166, 167, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1209, 0, 0, - 0, 0, 0, 0, 0, 1085, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 615, 0, - 0, 1203, 0, 0, 1907, 1209, 0, 0, 0, 0, - 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1559, 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, 140, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 134, 0, 0, 135, - 0, 0, 0, 0, 0, 0, 0, 761, 0, 0, - 1203, 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, 2003, 1977, 1978, - 1979, 0, 0, 0, 2009, 2010, 2011, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1089, 0, 0, + 601, 601, 0, 0, 0, 494, 0, 494, 0, 0, + 0, 0, 0, 494, 0, 0, 0, 1277, 0, 0, + 0, 601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 189, 0, 187, 0, 0, + 0, 0, 0, 0, 0, 1440, 494, 189, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 879, 0, 0, 0, 0, 0, 0, 601, 187, + 0, 0, 0, 0, 0, 0, 615, 615, 615, 1203, + 187, 187, 187, 187, 187, 0, 0, 0, 0, 0, + 0, 0, 1741, 494, 494, 0, 187, 0, 0, 187, + 187, 0, 0, 187, 1751, 1301, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 494, + 0, 0, 0, 494, 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, 1392, 0, 615, 0, 187, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1202, 0, + 0, 1203, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1301, 0, 0, 0, 1424, 1425, 0, 0, 0, + 0, 0, 925, 925, 925, 0, 0, 0, 0, 0, + 0, 0, 1077, 187, 0, 1088, 0, 0, 0, 1458, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 1071, + 0, 187, 615, 0, 0, 989, 991, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 615, 0, 0, 615, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 761, 601, 1004, 0, 0, 0, + 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 0, 1019, + 1022, 1022, 1022, 1028, 1022, 1022, 1028, 1022, 1036, 1037, + 1038, 1039, 1040, 1041, 1042, 0, 0, 0, 0, 0, + 1048, 0, 0, 33, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 0, 0, 0, 0, 0, 768, + 0, 169, 0, 0, 0, 0, 1203, 1561, 1128, 0, + 1084, 0, 1179, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 761, 111, 0, 133, 0, + 0, 768, 187, 0, 0, 0, 0, 153, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1106, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 143, 0, + 0, 0, 0, 132, 0, 761, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 0, 0, 187, 187, 187, + 0, 150, 0, 151, 0, 0, 1203, 0, 1183, 1184, + 142, 141, 168, 0, 0, 0, 187, 34, 35, 36, + 70, 38, 39, 0, 0, 0, 0, 0, 0, 0, + 1239, 1116, 0, 0, 0, 0, 0, 74, 187, 0, + 0, 0, 40, 66, 67, 0, 64, 68, 0, 0, + 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, + 137, 1185, 144, 0, 1182, 1287, 138, 139, 0, 0, + 154, 0, 0, 1297, 1129, 0, 0, 0, 0, 0, + 159, 0, 53, 0, 0, 0, 1638, 0, 0, 0, + 0, 0, 69, 1311, 0, 0, 0, 0, 0, 0, + 1315, 0, 0, 0, 0, 0, 0, 0, 1203, 1324, + 1325, 1326, 1327, 1328, 1329, 1330, 0, 0, 0, 0, + 0, 1142, 1145, 1146, 1147, 1148, 1149, 1150, 0, 1151, + 1152, 1153, 1154, 1155, 1130, 1131, 1132, 1133, 1114, 1115, + 1143, 1088, 1117, 0, 1118, 1119, 1120, 1121, 1122, 1123, + 1124, 1125, 1126, 1127, 1134, 1135, 1136, 1137, 1138, 1139, + 1140, 1141, 0, 0, 43, 46, 49, 48, 51, 0, + 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 52, 73, 72, 0, 0, + 61, 62, 50, 0, 0, 0, 0, 0, 0, 0, + 1440, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1202, 0, 0, 0, 1144, 0, 0, 0, + 0, 0, 925, 925, 925, 140, 0, 54, 55, 0, + 56, 57, 58, 59, 0, 0, 0, 134, 0, 0, + 135, 187, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 0, 0, 1465, 0, 0, 0, + 0, 0, 0, 1469, 0, 1472, 0, 0, 0, 0, + 0, 0, 0, 0, 1491, 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, + 1806, 0, 0, 0, 1202, 0, 1813, 0, 0, 1806, + 0, 0, 0, 1203, 615, 0, 1818, 0, 0, 71, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 147, 152, 149, 155, 156, 157, 158, 160, 161, + 162, 163, 0, 1558, 0, 0, 0, 164, 165, 166, + 167, 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, 1490, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 615, + 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, 1208, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 615, 0, 0, 1202, + 0, 0, 1909, 1208, 0, 0, 0, 1088, 0, 0, 0, 1613, 1614, 1615, 1616, 1617, 0, 0, 0, 0, - 0, 1621, 1622, 1089, 1624, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1629, 0, 0, 0, 0, 0, - 0, 1632, 0, 0, 0, 0, 0, 0, 0, 0, - 147, 152, 149, 155, 156, 157, 158, 160, 161, 162, - 163, 0, 1203, 0, 0, 1636, 164, 165, 166, 167, + 0, 1621, 1622, 1088, 1624, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1630, 0, 0, 0, 0, 0, + 0, 1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1637, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 761, 0, 0, 1202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1804, 2051, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1804, 0, 0, 615, 0, 0, 0, - 1904, 0, 33, 0, 1904, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1979, 1980, 1981, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1804, 1804, 1804, 0, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 2093, 0, 2095, 0, 0, - 0, 0, 0, 1804, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1904, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 33, 2140, 0, 1804, 0, 0, 0, - 0, 0, 0, 1747, 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, 615, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1203, 1798, 2164, - 0, 0, 0, 1804, 0, 0, 0, 0, 0, 0, + 0, 1202, 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, 1748, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1806, + 2053, 0, 1659, 0, 0, 578, 0, 0, 0, 0, + 0, 0, 1806, 0, 0, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1843, 0, 0, 0, 0, 0, 0, + 0, 0, 1696, 0, 0, 0, 0, 0, 0, 1800, + 1806, 1806, 1806, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2095, 0, 2097, 0, 1084, 0, + 0, 0, 1806, 0, 0, 1723, 1724, 0, 0, 1084, + 1084, 1084, 1084, 1084, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1490, 1830, 0, 1084, 0, + 0, 0, 1084, 0, 0, 1806, 0, 0, 0, 0, + 0, 0, 0, 0, 1845, 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, 615, 615, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1202, 0, 2166, 0, + 0, 0, 1806, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1819, 0, 0, 1894, 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, 1892, 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, 0, 0, 0, 0, 1956, 0, 0, + 1957, 1958, 1959, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1906, 0, 33, 0, + 0, 1982, 0, 0, 0, 0, 0, 0, 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, 0, - 0, 0, 0, 0, 0, 1954, 0, 1955, 1956, 1957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1967, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1980, 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, @@ -1697,7 +1648,78 @@ var yyAct = [...]int{ 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, 739, 726, 0, 0, 675, 742, 646, 664, 751, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2005, 0, 0, 0, 0, 0, + 0, 2011, 2012, 2013, 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, 2107, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2116, 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, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1906, 0, 33, + 0, 1906, 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, 33, 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, 1906, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 739, 726, + 33, 2142, 675, 742, 646, 664, 751, 666, 669, 709, + 626, 688, 331, 661, 0, 650, 622, 657, 623, 648, + 677, 241, 681, 645, 728, 691, 741, 289, 0, 628, + 651, 345, 711, 382, 227, 298, 296, 410, 251, 244, + 240, 226, 273, 304, 343, 400, 337, 748, 293, 698, + 0, 391, 316, 0, 0, 0, 679, 731, 686, 722, + 674, 710, 635, 697, 743, 662, 706, 744, 279, 225, + 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, + 0, 2149, 2150, 0, 0, 0, 0, 0, 217, 0, + 223, 703, 738, 659, 705, 237, 277, 243, 236, 407, + 708, 754, 621, 700, 0, 624, 627, 750, 734, 654, + 655, 0, 0, 0, 0, 0, 0, 0, 678, 687, + 719, 672, 0, 0, 0, 0, 0, 0, 0, 0, + 652, 0, 696, 0, 0, 0, 631, 625, 0, 0, + 0, 0, 676, 0, 0, 0, 634, 0, 653, 720, + 0, 619, 263, 629, 317, 724, 733, 673, 438, 737, + 671, 670, 740, 715, 632, 730, 665, 288, 630, 285, + 191, 205, 0, 663, 327, 366, 372, 729, 649, 658, + 228, 656, 370, 341, 424, 213, 253, 363, 346, 368, + 695, 713, 369, 294, 412, 358, 422, 439, 440, 235, + 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, + 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, + 399, 420, 218, 380, 0, 0, 0, 200, 418, 396, + 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, + 415, 416, 229, 450, 208, 435, 202, 209, 434, 323, + 411, 419, 312, 303, 201, 417, 310, 302, 287, 249, + 269, 356, 297, 357, 270, 319, 318, 320, 0, 196, + 0, 393, 428, 451, 215, 644, 725, 406, 444, 447, + 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, + 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, + 272, 389, 286, 295, 717, 753, 340, 371, 219, 426, + 390, 639, 643, 637, 638, 689, 690, 640, 745, 746, + 747, 721, 633, 0, 641, 642, 0, 727, 735, 736, + 694, 190, 203, 291, 749, 360, 256, 449, 433, 429, + 620, 636, 234, 647, 0, 0, 660, 667, 668, 680, + 682, 683, 684, 685, 693, 701, 702, 704, 712, 714, + 716, 718, 723, 732, 752, 192, 193, 204, 212, 221, + 233, 246, 254, 264, 268, 271, 274, 275, 278, 283, + 300, 305, 306, 307, 308, 324, 325, 326, 329, 332, + 333, 336, 338, 339, 342, 348, 349, 350, 351, 352, + 354, 361, 365, 373, 374, 375, 376, 377, 378, 379, + 383, 384, 385, 386, 394, 398, 413, 414, 425, 437, + 441, 265, 421, 442, 0, 299, 692, 699, 301, 250, + 267, 276, 707, 432, 395, 207, 367, 257, 197, 224, + 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, + 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, + 238, 739, 726, 0, 0, 675, 742, 646, 664, 751, 666, 669, 709, 626, 688, 331, 661, 0, 650, 622, 657, 623, 648, 677, 241, 681, 645, 728, 691, 741, 289, 0, 628, 651, 345, 711, 382, 227, 298, 296, @@ -1705,14 +1727,14 @@ var yyAct = [...]int{ 748, 293, 698, 0, 391, 316, 0, 0, 0, 679, 731, 686, 722, 674, 710, 635, 697, 743, 662, 706, 744, 279, 225, 195, 328, 392, 255, 0, 0, 0, - 177, 178, 179, 0, 2147, 2148, 0, 0, 0, 0, + 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 703, 738, 659, 705, 237, 277, 243, 236, 407, 708, 754, 621, 700, 0, 624, 627, 750, 734, 654, 655, 0, 0, 0, 0, 0, 0, 0, 678, 687, 719, 672, 0, 0, 0, 0, 0, - 0, 0, 0, 652, 0, 696, 0, 0, 0, 631, - 625, 2105, 0, 0, 0, 676, 0, 0, 0, 634, - 0, 653, 720, 2114, 619, 263, 629, 317, 724, 733, + 0, 1898, 0, 652, 0, 696, 0, 0, 0, 631, + 625, 0, 0, 0, 0, 676, 0, 0, 0, 634, + 0, 653, 720, 0, 619, 263, 629, 317, 724, 733, 673, 438, 737, 671, 670, 740, 715, 632, 730, 665, 288, 630, 285, 191, 205, 0, 663, 327, 366, 372, 729, 649, 658, 228, 656, 370, 341, 424, 213, 253, @@ -1756,7 +1778,7 @@ var yyAct = [...]int{ 705, 237, 277, 243, 236, 407, 708, 754, 621, 700, 0, 624, 627, 750, 734, 654, 655, 0, 0, 0, 0, 0, 0, 0, 678, 687, 719, 672, 0, 0, - 0, 0, 0, 0, 1896, 0, 652, 0, 696, 0, + 0, 0, 0, 0, 1752, 0, 652, 0, 696, 0, 0, 0, 631, 625, 0, 0, 0, 0, 676, 0, 0, 0, 634, 0, 653, 720, 0, 619, 263, 629, 317, 724, 733, 673, 438, 737, 671, 670, 740, 715, @@ -1802,7 +1824,7 @@ var yyAct = [...]int{ 703, 738, 659, 705, 237, 277, 243, 236, 407, 708, 754, 621, 700, 0, 624, 627, 750, 734, 654, 655, 0, 0, 0, 0, 0, 0, 0, 678, 687, 719, - 672, 0, 0, 0, 0, 0, 0, 1751, 0, 652, + 672, 0, 0, 0, 0, 0, 0, 1467, 0, 652, 0, 696, 0, 0, 0, 631, 625, 0, 0, 0, 0, 676, 0, 0, 0, 634, 0, 653, 720, 0, 619, 263, 629, 317, 724, 733, 673, 438, 737, 671, @@ -1843,13 +1865,13 @@ var yyAct = [...]int{ 251, 244, 240, 226, 273, 304, 343, 400, 337, 748, 293, 698, 0, 391, 316, 0, 0, 0, 679, 731, 686, 722, 674, 710, 635, 697, 743, 662, 706, 744, - 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, + 279, 225, 195, 328, 392, 255, 69, 0, 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 703, 738, 659, 705, 237, 277, 243, 236, 407, 708, 754, 621, 700, 0, 624, 627, 750, 734, 654, 655, 0, 0, 0, 0, 0, 0, 0, 678, 687, 719, 672, 0, 0, 0, 0, 0, 0, - 1468, 0, 652, 0, 696, 0, 0, 0, 631, 625, + 0, 0, 652, 0, 696, 0, 0, 0, 631, 625, 0, 0, 0, 0, 676, 0, 0, 0, 634, 0, 653, 720, 0, 619, 263, 629, 317, 724, 733, 673, 438, 737, 671, 670, 740, 715, 632, 730, 665, 288, @@ -1889,7 +1911,7 @@ var yyAct = [...]int{ 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 748, 293, 698, 0, 391, 316, 0, 0, 0, 679, 731, 686, 722, 674, 710, 635, 697, 743, - 662, 706, 744, 279, 225, 195, 328, 392, 255, 69, + 662, 706, 744, 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 703, 738, 659, 705, 237, 277, 243, 236, 407, 708, 754, 621, 700, 0, @@ -1953,12 +1975,12 @@ var yyAct = [...]int{ 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, 218, 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, 415, 416, - 229, 450, 208, 435, 202, 209, 434, 323, 411, 419, + 229, 450, 208, 435, 202, 756, 434, 323, 411, 419, 312, 303, 201, 417, 310, 302, 287, 249, 269, 356, 297, 357, 270, 319, 318, 320, 0, 196, 0, 393, 428, 451, 215, 644, 725, 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, - 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, + 353, 266, 334, 423, 252, 431, 618, 755, 612, 611, 286, 295, 717, 753, 340, 371, 219, 426, 390, 639, 643, 637, 638, 689, 690, 640, 745, 746, 747, 721, 633, 0, 641, 642, 0, 727, 735, 736, 694, 190, @@ -1997,7 +2019,7 @@ var yyAct = [...]int{ 368, 695, 713, 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, 194, 292, - 198, 399, 420, 218, 380, 0, 0, 0, 200, 418, + 198, 399, 1092, 218, 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, 415, 416, 229, 450, 208, 435, 202, 756, 434, 323, 411, 419, 312, 303, 201, 417, 310, 302, 287, @@ -2043,7 +2065,7 @@ var yyAct = [...]int{ 253, 363, 346, 368, 695, 713, 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, - 261, 194, 292, 198, 399, 1093, 218, 380, 0, 0, + 261, 194, 292, 198, 399, 609, 218, 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, 415, 416, 229, 450, 208, 435, 202, 756, 434, 323, 411, 419, 312, 303, 201, 417, @@ -2067,190 +2089,9 @@ var yyAct = [...]int{ 692, 699, 301, 250, 267, 276, 707, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, - 402, 403, 405, 313, 238, 739, 726, 0, 0, 675, - 742, 646, 664, 751, 666, 669, 709, 626, 688, 331, - 661, 0, 650, 622, 657, 623, 648, 677, 241, 681, - 645, 728, 691, 741, 289, 0, 628, 651, 345, 711, - 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, - 304, 343, 400, 337, 748, 293, 698, 0, 391, 316, - 0, 0, 0, 679, 731, 686, 722, 674, 710, 635, - 697, 743, 662, 706, 744, 279, 225, 195, 328, 392, - 255, 0, 0, 0, 177, 178, 179, 0, 0, 0, - 0, 0, 0, 0, 0, 217, 0, 223, 703, 738, - 659, 705, 237, 277, 243, 236, 407, 708, 754, 621, - 700, 0, 624, 627, 750, 734, 654, 655, 0, 0, - 0, 0, 0, 0, 0, 678, 687, 719, 672, 0, - 0, 0, 0, 0, 0, 0, 0, 652, 0, 696, - 0, 0, 0, 631, 625, 0, 0, 0, 0, 676, - 0, 0, 0, 634, 0, 653, 720, 0, 619, 263, - 629, 317, 724, 733, 673, 438, 737, 671, 670, 740, - 715, 632, 730, 665, 288, 630, 285, 191, 205, 0, - 663, 327, 366, 372, 729, 649, 658, 228, 656, 370, - 341, 424, 213, 253, 363, 346, 368, 695, 713, 369, - 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, - 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, - 409, 284, 387, 261, 194, 292, 198, 399, 609, 218, - 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, - 199, 0, 362, 239, 259, 230, 330, 415, 416, 229, - 450, 208, 435, 202, 756, 434, 323, 411, 419, 312, - 303, 201, 417, 310, 302, 287, 249, 269, 356, 297, - 357, 270, 319, 318, 320, 0, 196, 0, 393, 428, - 451, 215, 644, 725, 406, 444, 447, 0, 359, 216, - 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, - 266, 334, 423, 252, 431, 618, 755, 612, 611, 286, - 295, 717, 753, 340, 371, 219, 426, 390, 639, 643, - 637, 638, 689, 690, 640, 745, 746, 747, 721, 633, - 0, 641, 642, 0, 727, 735, 736, 694, 190, 203, - 291, 749, 360, 256, 449, 433, 429, 620, 636, 234, - 647, 0, 0, 660, 667, 668, 680, 682, 683, 684, - 685, 693, 701, 702, 704, 712, 714, 716, 718, 723, - 732, 752, 192, 193, 204, 212, 221, 233, 246, 254, - 264, 268, 271, 274, 275, 278, 283, 300, 305, 306, - 307, 308, 324, 325, 326, 329, 332, 333, 336, 338, - 339, 342, 348, 349, 350, 351, 352, 354, 361, 365, - 373, 374, 375, 376, 377, 378, 379, 383, 384, 385, - 386, 394, 398, 413, 414, 425, 437, 441, 265, 421, - 442, 0, 299, 692, 699, 301, 250, 267, 276, 707, - 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, - 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, - 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, - 0, 1395, 0, 511, 0, 0, 0, 241, 0, 510, - 0, 0, 0, 289, 0, 0, 1396, 345, 0, 382, - 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, - 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, - 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, - 69, 0, 0, 177, 178, 179, 532, 531, 534, 535, - 536, 537, 0, 0, 217, 533, 223, 538, 539, 540, - 0, 237, 277, 243, 236, 407, 0, 0, 0, 508, - 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 522, 523, 599, 0, 0, 0, 568, 0, - 524, 0, 0, 517, 518, 520, 519, 521, 526, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, - 317, 567, 0, 0, 438, 0, 0, 565, 0, 0, - 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, - 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, - 424, 213, 253, 363, 346, 368, 0, 0, 369, 294, - 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, - 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, - 284, 387, 261, 194, 292, 198, 399, 420, 218, 380, - 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, - 0, 362, 239, 259, 230, 330, 415, 416, 229, 450, - 208, 435, 202, 209, 434, 323, 411, 419, 312, 303, - 201, 417, 310, 302, 287, 249, 269, 356, 297, 357, - 270, 319, 318, 320, 0, 196, 0, 393, 428, 451, - 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, - 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, - 334, 423, 252, 431, 322, 210, 272, 389, 286, 295, - 0, 0, 340, 371, 219, 426, 390, 555, 566, 561, - 562, 559, 560, 0, 558, 557, 556, 569, 547, 548, - 549, 550, 552, 0, 563, 564, 551, 190, 203, 291, - 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 204, 212, 221, 233, 246, 254, 264, - 268, 271, 274, 275, 278, 283, 300, 305, 306, 307, - 308, 324, 325, 326, 329, 332, 333, 336, 338, 339, - 342, 348, 349, 350, 351, 352, 354, 361, 365, 373, - 374, 375, 376, 377, 378, 379, 383, 384, 385, 386, - 394, 398, 413, 414, 425, 437, 441, 265, 421, 442, - 0, 299, 0, 0, 301, 250, 267, 276, 0, 432, - 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, - 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, - 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, - 0, 0, 511, 0, 0, 0, 241, 0, 510, 0, - 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, - 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, - 400, 337, 554, 293, 0, 0, 391, 316, 0, 0, - 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, - 0, 1507, 0, 279, 225, 195, 328, 392, 255, 69, - 0, 0, 177, 178, 179, 532, 531, 534, 535, 536, - 537, 0, 0, 217, 533, 223, 538, 539, 540, 1508, - 237, 277, 243, 236, 407, 0, 0, 0, 508, 525, - 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 522, 523, 0, 0, 0, 0, 568, 0, 524, - 0, 0, 517, 518, 520, 519, 521, 526, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 263, 0, 317, - 567, 0, 0, 438, 0, 0, 565, 0, 0, 0, - 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, - 366, 372, 0, 0, 0, 228, 0, 370, 341, 424, - 213, 253, 363, 346, 368, 0, 0, 369, 294, 412, - 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, - 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, - 387, 261, 194, 292, 198, 399, 420, 218, 380, 0, - 0, 0, 200, 418, 396, 311, 281, 282, 199, 0, - 362, 239, 259, 230, 330, 415, 416, 229, 450, 208, - 435, 202, 209, 434, 323, 411, 419, 312, 303, 201, - 417, 310, 302, 287, 249, 269, 356, 297, 357, 270, - 319, 318, 320, 0, 196, 0, 393, 428, 451, 215, - 0, 0, 406, 444, 447, 0, 359, 216, 260, 248, - 355, 258, 290, 443, 445, 446, 214, 353, 266, 334, - 423, 252, 431, 322, 210, 272, 389, 286, 295, 0, - 0, 340, 371, 219, 426, 390, 555, 566, 561, 562, - 559, 560, 0, 558, 557, 556, 569, 547, 548, 549, - 550, 552, 0, 563, 564, 551, 190, 203, 291, 0, - 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 192, 193, 204, 212, 221, 233, 246, 254, 264, 268, - 271, 274, 275, 278, 283, 300, 305, 306, 307, 308, - 324, 325, 326, 329, 332, 333, 336, 338, 339, 342, - 348, 349, 350, 351, 352, 354, 361, 365, 373, 374, - 375, 376, 377, 378, 379, 383, 384, 385, 386, 394, - 398, 413, 414, 425, 437, 441, 265, 421, 442, 0, - 299, 0, 0, 301, 250, 267, 276, 0, 432, 395, - 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, - 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, - 401, 402, 403, 405, 313, 238, 331, 0, 0, 0, - 0, 511, 0, 0, 0, 241, 0, 510, 0, 0, - 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, - 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, - 337, 554, 293, 0, 0, 391, 316, 0, 0, 0, - 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, - 0, 0, 279, 225, 195, 328, 392, 255, 69, 0, - 586, 177, 178, 179, 532, 531, 534, 535, 536, 537, - 0, 0, 217, 533, 223, 538, 539, 540, 0, 237, - 277, 243, 236, 407, 0, 0, 0, 508, 525, 0, - 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 522, 523, 0, 0, 0, 0, 568, 0, 524, 0, - 0, 517, 518, 520, 519, 521, 526, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 263, 0, 317, 567, - 0, 0, 438, 0, 0, 565, 0, 0, 0, 0, - 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, - 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, - 253, 363, 346, 368, 0, 0, 369, 294, 412, 358, - 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, - 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, - 261, 194, 292, 198, 399, 420, 218, 380, 0, 0, - 0, 200, 418, 396, 311, 281, 282, 199, 0, 362, - 239, 259, 230, 330, 415, 416, 229, 450, 208, 435, - 202, 209, 434, 323, 411, 419, 312, 303, 201, 417, - 310, 302, 287, 249, 269, 356, 297, 357, 270, 319, - 318, 320, 0, 196, 0, 393, 428, 451, 215, 0, - 0, 406, 444, 447, 0, 359, 216, 260, 248, 355, - 258, 290, 443, 445, 446, 214, 353, 266, 334, 423, - 252, 431, 322, 210, 272, 389, 286, 295, 0, 0, - 340, 371, 219, 426, 390, 555, 566, 561, 562, 559, - 560, 0, 558, 557, 556, 569, 547, 548, 549, 550, - 552, 0, 563, 564, 551, 190, 203, 291, 0, 360, - 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, - 193, 204, 212, 221, 233, 246, 254, 264, 268, 271, - 274, 275, 278, 283, 300, 305, 306, 307, 308, 324, - 325, 326, 329, 332, 333, 336, 338, 339, 342, 348, - 349, 350, 351, 352, 354, 361, 365, 373, 374, 375, - 376, 377, 378, 379, 383, 384, 385, 386, 394, 398, - 413, 414, 425, 437, 441, 265, 421, 442, 0, 299, - 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, - 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, - 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, - 402, 403, 405, 313, 238, 331, 0, 0, 0, 0, + 402, 403, 405, 313, 238, 331, 0, 0, 1394, 0, 511, 0, 0, 0, 241, 0, 510, 0, 0, 0, - 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, + 289, 0, 0, 1395, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, @@ -2298,14 +2139,14 @@ var yyAct = [...]int{ 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, - 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, + 545, 546, 0, 0, 0, 0, 0, 0, 1506, 0, 279, 225, 195, 328, 392, 255, 69, 0, 0, 177, - 178, 179, 532, 1413, 534, 535, 536, 537, 0, 0, - 217, 533, 223, 538, 539, 540, 0, 237, 277, 243, + 178, 179, 532, 531, 534, 535, 536, 537, 0, 0, + 217, 533, 223, 538, 539, 540, 1507, 237, 277, 243, 236, 407, 0, 0, 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, 523, - 599, 0, 0, 0, 568, 0, 524, 0, 0, 517, + 0, 0, 0, 0, 568, 0, 524, 0, 0, 517, 518, 520, 519, 521, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, 317, 567, 0, 0, 438, 0, 0, 565, 0, 0, 0, 0, 0, 288, @@ -2344,12 +2185,12 @@ var yyAct = [...]int{ 244, 240, 226, 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 225, 195, 328, 392, 255, 69, 0, 0, 177, 178, - 179, 532, 1410, 534, 535, 536, 537, 0, 0, 217, + 225, 195, 328, 392, 255, 69, 0, 586, 177, 178, + 179, 532, 531, 534, 535, 536, 537, 0, 0, 217, 533, 223, 538, 539, 540, 0, 237, 277, 243, 236, 407, 0, 0, 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 522, 523, 599, + 0, 0, 0, 0, 0, 0, 0, 522, 523, 0, 0, 0, 0, 568, 0, 524, 0, 0, 517, 518, 520, 519, 521, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, 317, 567, 0, 0, 438, @@ -2383,152 +2224,152 @@ var yyAct = [...]int{ 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, - 313, 238, 579, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, - 511, 0, 0, 0, 241, 0, 510, 0, 0, 0, - 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, - 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, - 554, 293, 0, 0, 391, 316, 0, 0, 0, 0, - 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, - 0, 279, 225, 195, 328, 392, 255, 69, 0, 0, - 177, 178, 179, 532, 531, 534, 535, 536, 537, 0, - 0, 217, 533, 223, 538, 539, 540, 0, 237, 277, - 243, 236, 407, 0, 0, 0, 508, 525, 0, 553, + 313, 238, 331, 0, 0, 0, 0, 511, 0, 0, + 0, 241, 0, 510, 0, 0, 0, 289, 0, 0, + 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, + 240, 226, 273, 304, 343, 400, 337, 554, 293, 0, + 0, 391, 316, 0, 0, 0, 0, 0, 545, 546, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, + 195, 328, 392, 255, 69, 0, 0, 177, 178, 179, + 532, 531, 534, 535, 536, 537, 0, 0, 217, 533, + 223, 538, 539, 540, 0, 237, 277, 243, 236, 407, + 0, 0, 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, - 523, 0, 0, 0, 0, 568, 0, 524, 0, 0, - 517, 518, 520, 519, 521, 526, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 263, 0, 317, 567, 0, - 0, 438, 0, 0, 565, 0, 0, 0, 0, 0, - 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, - 0, 0, 0, 228, 0, 370, 341, 424, 213, 253, - 363, 346, 368, 0, 0, 369, 294, 412, 358, 422, - 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, - 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, - 194, 292, 198, 399, 420, 218, 380, 0, 0, 0, - 200, 418, 396, 311, 281, 282, 199, 0, 362, 239, - 259, 230, 330, 415, 416, 229, 450, 208, 435, 202, - 209, 434, 323, 411, 419, 312, 303, 201, 417, 310, - 302, 287, 249, 269, 356, 297, 357, 270, 319, 318, - 320, 0, 196, 0, 393, 428, 451, 215, 0, 0, - 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, - 290, 443, 445, 446, 214, 353, 266, 334, 423, 252, - 431, 322, 210, 272, 389, 286, 295, 0, 0, 340, - 371, 219, 426, 390, 555, 566, 561, 562, 559, 560, - 0, 558, 557, 556, 569, 547, 548, 549, 550, 552, - 0, 563, 564, 551, 190, 203, 291, 0, 360, 256, - 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 522, 523, 599, 0, + 0, 0, 568, 0, 524, 0, 0, 517, 518, 520, + 519, 521, 526, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 263, 0, 317, 567, 0, 0, 438, 0, + 0, 565, 0, 0, 0, 0, 0, 288, 0, 285, + 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, + 228, 0, 370, 341, 424, 213, 253, 363, 346, 368, + 0, 0, 369, 294, 412, 358, 422, 439, 440, 235, + 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, + 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, + 399, 420, 218, 380, 0, 0, 0, 200, 418, 396, + 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, + 415, 416, 229, 450, 208, 435, 202, 209, 434, 323, + 411, 419, 312, 303, 201, 417, 310, 302, 287, 249, + 269, 356, 297, 357, 270, 319, 318, 320, 0, 196, + 0, 393, 428, 451, 215, 0, 0, 406, 444, 447, + 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, + 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, + 272, 389, 286, 295, 0, 0, 340, 371, 219, 426, + 390, 555, 566, 561, 562, 559, 560, 0, 558, 557, + 556, 569, 547, 548, 549, 550, 552, 0, 563, 564, + 551, 190, 203, 291, 0, 360, 256, 449, 433, 429, + 0, 0, 234, 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, 192, 193, - 204, 212, 221, 233, 246, 254, 264, 268, 271, 274, - 275, 278, 283, 300, 305, 306, 307, 308, 324, 325, - 326, 329, 332, 333, 336, 338, 339, 342, 348, 349, - 350, 351, 352, 354, 361, 365, 373, 374, 375, 376, - 377, 378, 379, 383, 384, 385, 386, 394, 398, 413, - 414, 425, 437, 441, 265, 421, 442, 0, 299, 0, - 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, - 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, - 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, - 403, 405, 313, 238, 331, 0, 0, 0, 0, 511, - 0, 0, 0, 241, 0, 510, 0, 0, 0, 289, - 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, - 251, 244, 240, 226, 273, 304, 343, 400, 337, 554, - 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, - 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, - 279, 225, 195, 328, 392, 255, 69, 0, 0, 177, - 178, 179, 532, 531, 534, 535, 536, 537, 0, 0, - 217, 533, 223, 538, 539, 540, 0, 237, 277, 243, - 236, 407, 0, 0, 0, 508, 525, 0, 553, 0, + 0, 0, 0, 0, 0, 192, 193, 204, 212, 221, + 233, 246, 254, 264, 268, 271, 274, 275, 278, 283, + 300, 305, 306, 307, 308, 324, 325, 326, 329, 332, + 333, 336, 338, 339, 342, 348, 349, 350, 351, 352, + 354, 361, 365, 373, 374, 375, 376, 377, 378, 379, + 383, 384, 385, 386, 394, 398, 413, 414, 425, 437, + 441, 265, 421, 442, 0, 299, 0, 0, 301, 250, + 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, + 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, + 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, + 238, 331, 0, 0, 0, 0, 511, 0, 0, 0, + 241, 0, 510, 0, 0, 0, 289, 0, 0, 0, + 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, + 226, 273, 304, 343, 400, 337, 554, 293, 0, 0, + 391, 316, 0, 0, 0, 0, 0, 545, 546, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, + 328, 392, 255, 69, 0, 0, 177, 178, 179, 532, + 1412, 534, 535, 536, 537, 0, 0, 217, 533, 223, + 538, 539, 540, 0, 237, 277, 243, 236, 407, 0, + 0, 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 522, 523, - 0, 0, 0, 0, 568, 0, 524, 0, 0, 517, - 518, 520, 519, 521, 526, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 263, 0, 317, 567, 0, 0, - 438, 0, 0, 565, 0, 0, 0, 0, 0, 288, - 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, - 0, 0, 228, 0, 370, 341, 424, 213, 253, 363, - 346, 368, 0, 0, 369, 294, 412, 358, 422, 439, - 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, - 397, 427, 388, 314, 408, 409, 284, 387, 261, 194, - 292, 198, 399, 420, 218, 380, 0, 0, 0, 200, - 418, 396, 311, 281, 282, 199, 0, 362, 239, 259, - 230, 330, 415, 416, 229, 450, 208, 435, 202, 209, - 434, 323, 411, 419, 312, 303, 201, 417, 310, 302, - 287, 249, 269, 356, 297, 357, 270, 319, 318, 320, - 0, 196, 0, 393, 428, 451, 215, 0, 0, 406, - 444, 447, 0, 359, 216, 260, 248, 355, 258, 290, - 443, 445, 446, 214, 353, 266, 334, 423, 252, 431, - 322, 210, 272, 389, 286, 295, 0, 0, 340, 371, - 219, 426, 390, 555, 566, 561, 562, 559, 560, 0, - 558, 557, 556, 569, 547, 548, 549, 550, 552, 0, - 563, 564, 551, 190, 203, 291, 0, 360, 256, 449, - 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 522, 523, 599, 0, 0, + 0, 568, 0, 524, 0, 0, 517, 518, 520, 519, + 521, 526, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 263, 0, 317, 567, 0, 0, 438, 0, 0, + 565, 0, 0, 0, 0, 0, 288, 0, 285, 191, + 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, + 0, 370, 341, 424, 213, 253, 363, 346, 368, 0, + 0, 369, 294, 412, 358, 422, 439, 440, 235, 321, + 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, + 314, 408, 409, 284, 387, 261, 194, 292, 198, 399, + 420, 218, 380, 0, 0, 0, 200, 418, 396, 311, + 281, 282, 199, 0, 362, 239, 259, 230, 330, 415, + 416, 229, 450, 208, 435, 202, 209, 434, 323, 411, + 419, 312, 303, 201, 417, 310, 302, 287, 249, 269, + 356, 297, 357, 270, 319, 318, 320, 0, 196, 0, + 393, 428, 451, 215, 0, 0, 406, 444, 447, 0, + 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, + 214, 353, 266, 334, 423, 252, 431, 322, 210, 272, + 389, 286, 295, 0, 0, 340, 371, 219, 426, 390, + 555, 566, 561, 562, 559, 560, 0, 558, 557, 556, + 569, 547, 548, 549, 550, 552, 0, 563, 564, 551, + 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, + 0, 234, 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, 192, 193, 204, - 212, 221, 233, 246, 254, 264, 268, 271, 274, 275, - 278, 283, 300, 305, 306, 307, 308, 324, 325, 326, - 329, 332, 333, 336, 338, 339, 342, 348, 349, 350, - 351, 352, 354, 361, 365, 373, 374, 375, 376, 377, - 378, 379, 383, 384, 385, 386, 394, 398, 413, 414, - 425, 437, 441, 265, 421, 442, 0, 299, 0, 0, - 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, - 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, - 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, - 405, 313, 238, 331, 0, 0, 0, 0, 0, 0, - 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, - 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, - 244, 240, 226, 273, 304, 343, 400, 337, 554, 293, - 0, 0, 391, 316, 0, 0, 0, 0, 0, 545, - 546, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 225, 195, 328, 392, 255, 69, 0, 0, 177, 178, - 179, 532, 531, 534, 535, 536, 537, 0, 0, 217, - 533, 223, 538, 539, 540, 0, 237, 277, 243, 236, - 407, 0, 0, 0, 0, 525, 0, 553, 0, 0, + 0, 0, 0, 0, 192, 193, 204, 212, 221, 233, + 246, 254, 264, 268, 271, 274, 275, 278, 283, 300, + 305, 306, 307, 308, 324, 325, 326, 329, 332, 333, + 336, 338, 339, 342, 348, 349, 350, 351, 352, 354, + 361, 365, 373, 374, 375, 376, 377, 378, 379, 383, + 384, 385, 386, 394, 398, 413, 414, 425, 437, 441, + 265, 421, 442, 0, 299, 0, 0, 301, 250, 267, + 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, + 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, + 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, + 331, 0, 0, 0, 0, 511, 0, 0, 0, 241, + 0, 510, 0, 0, 0, 289, 0, 0, 0, 345, + 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, + 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, + 316, 0, 0, 0, 0, 0, 545, 546, 0, 0, + 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, + 392, 255, 69, 0, 0, 177, 178, 179, 532, 1409, + 534, 535, 536, 537, 0, 0, 217, 533, 223, 538, + 539, 540, 0, 237, 277, 243, 236, 407, 0, 0, + 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 599, 0, 0, 0, + 568, 0, 524, 0, 0, 517, 518, 520, 519, 521, + 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 263, 0, 317, 567, 0, 0, 438, 0, 0, 565, + 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, + 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, + 370, 341, 424, 213, 253, 363, 346, 368, 0, 0, + 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, + 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, + 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, + 218, 380, 0, 0, 0, 200, 418, 396, 311, 281, + 282, 199, 0, 362, 239, 259, 230, 330, 415, 416, + 229, 450, 208, 435, 202, 209, 434, 323, 411, 419, + 312, 303, 201, 417, 310, 302, 287, 249, 269, 356, + 297, 357, 270, 319, 318, 320, 0, 196, 0, 393, + 428, 451, 215, 0, 0, 406, 444, 447, 0, 359, + 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, + 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, + 286, 295, 0, 0, 340, 371, 219, 426, 390, 555, + 566, 561, 562, 559, 560, 0, 558, 557, 556, 569, + 547, 548, 549, 550, 552, 0, 563, 564, 551, 190, + 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, + 234, 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, 522, 523, 0, - 0, 0, 0, 568, 0, 524, 0, 0, 517, 518, - 520, 519, 521, 526, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 263, 0, 317, 567, 0, 0, 438, - 0, 0, 565, 0, 0, 0, 0, 0, 288, 0, - 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, - 0, 228, 0, 370, 341, 424, 213, 253, 363, 346, - 368, 2167, 0, 369, 294, 412, 358, 422, 439, 440, - 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, - 427, 388, 314, 408, 409, 284, 387, 261, 194, 292, - 198, 399, 420, 218, 380, 0, 0, 0, 200, 418, - 396, 311, 281, 282, 199, 0, 362, 239, 259, 230, - 330, 415, 416, 229, 450, 208, 435, 202, 209, 434, - 323, 411, 419, 312, 303, 201, 417, 310, 302, 287, - 249, 269, 356, 297, 357, 270, 319, 318, 320, 0, - 196, 0, 393, 428, 451, 215, 0, 0, 406, 444, - 447, 0, 359, 216, 260, 248, 355, 258, 290, 443, - 445, 446, 214, 353, 266, 334, 423, 252, 431, 322, - 210, 272, 389, 286, 295, 0, 0, 340, 371, 219, - 426, 390, 555, 566, 561, 562, 559, 560, 0, 558, - 557, 556, 569, 547, 548, 549, 550, 552, 0, 563, - 564, 551, 190, 203, 291, 0, 360, 256, 449, 433, - 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 193, 204, 212, 221, 233, 246, + 254, 264, 268, 271, 274, 275, 278, 283, 300, 305, + 306, 307, 308, 324, 325, 326, 329, 332, 333, 336, + 338, 339, 342, 348, 349, 350, 351, 352, 354, 361, + 365, 373, 374, 375, 376, 377, 378, 379, 383, 384, + 385, 386, 394, 398, 413, 414, 425, 437, 441, 265, + 421, 442, 0, 299, 0, 0, 301, 250, 267, 276, + 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, + 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, + 364, 220, 381, 401, 402, 403, 405, 313, 238, 579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 192, 193, 204, 212, - 221, 233, 246, 254, 264, 268, 271, 274, 275, 278, - 283, 300, 305, 306, 307, 308, 324, 325, 326, 329, - 332, 333, 336, 338, 339, 342, 348, 349, 350, 351, - 352, 354, 361, 365, 373, 374, 375, 376, 377, 378, - 379, 383, 384, 385, 386, 394, 398, 413, 414, 425, - 437, 441, 265, 421, 442, 0, 299, 0, 0, 301, - 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, - 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, - 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, - 313, 238, 331, 0, 0, 0, 0, 0, 0, 0, - 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, + 0, 0, 331, 0, 0, 0, 0, 511, 0, 0, + 0, 241, 0, 510, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, - 195, 328, 392, 255, 69, 0, 586, 177, 178, 179, + 195, 328, 392, 255, 69, 0, 0, 177, 178, 179, 532, 531, 534, 535, 536, 537, 0, 0, 217, 533, 223, 538, 539, 540, 0, 237, 277, 243, 236, 407, - 0, 0, 0, 0, 525, 0, 553, 0, 0, 0, + 0, 0, 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, 523, 0, 0, 0, 0, 568, 0, 524, 0, 0, 517, 518, 520, @@ -2564,8 +2405,8 @@ var yyAct = [...]int{ 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, - 238, 331, 0, 0, 0, 0, 0, 0, 0, 0, - 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, + 238, 331, 0, 0, 0, 0, 511, 0, 0, 0, + 241, 0, 510, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 545, 546, 0, @@ -2573,7 +2414,7 @@ var yyAct = [...]int{ 328, 392, 255, 69, 0, 0, 177, 178, 179, 532, 531, 534, 535, 536, 537, 0, 0, 217, 533, 223, 538, 539, 540, 0, 237, 277, 243, 236, 407, 0, - 0, 0, 0, 525, 0, 553, 0, 0, 0, 0, + 0, 0, 508, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522, 523, 0, 0, 0, 0, 568, 0, 524, 0, 0, 517, 518, 520, 519, @@ -2612,21 +2453,21 @@ var yyAct = [...]int{ 331, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, - 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, - 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 273, 304, 343, 400, 337, 554, 293, 0, 0, 391, + 316, 0, 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, - 392, 255, 0, 0, 0, 177, 178, 179, 0, 0, - 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, - 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 970, 969, 979, 980, 972, 973, 974, 975, 976, 977, - 978, 971, 0, 0, 981, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 263, 0, 317, 0, 0, 0, 438, 0, 0, 0, + 392, 255, 69, 0, 0, 177, 178, 179, 532, 531, + 534, 535, 536, 537, 0, 0, 217, 533, 223, 538, + 539, 540, 0, 237, 277, 243, 236, 407, 0, 0, + 0, 0, 525, 0, 553, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 0, 0, 0, 0, + 568, 0, 524, 0, 0, 517, 518, 520, 519, 521, + 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 263, 0, 317, 567, 0, 0, 438, 0, 0, 565, 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, - 370, 341, 424, 213, 253, 363, 346, 368, 0, 0, + 370, 341, 424, 213, 253, 363, 346, 368, 2169, 0, 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, @@ -2638,9 +2479,9 @@ var yyAct = [...]int{ 428, 451, 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, - 286, 295, 0, 0, 340, 371, 219, 426, 390, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, + 286, 295, 0, 0, 340, 371, 219, 426, 390, 555, + 566, 561, 562, 559, 560, 0, 558, 557, 556, 569, + 547, 548, 549, 550, 552, 0, 563, 564, 551, 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2654,160 +2495,24 @@ var yyAct = [...]int{ 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, - 0, 0, 0, 0, 0, 0, 0, 0, 241, 800, - 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, - 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, - 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, - 255, 0, 0, 0, 177, 178, 179, 0, 0, 0, - 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, - 0, 0, 237, 277, 243, 236, 407, 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, 263, - 0, 317, 0, 0, 799, 438, 0, 0, 0, 0, - 0, 0, 796, 797, 288, 764, 285, 191, 205, 790, - 794, 327, 366, 372, 0, 0, 0, 228, 0, 370, - 341, 424, 213, 253, 363, 346, 368, 0, 0, 369, - 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, - 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, - 409, 284, 387, 261, 194, 292, 198, 399, 420, 218, - 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, - 199, 0, 362, 239, 259, 230, 330, 415, 416, 229, - 450, 208, 435, 202, 209, 434, 323, 411, 419, 312, - 303, 201, 417, 310, 302, 287, 249, 269, 356, 297, - 357, 270, 319, 318, 320, 0, 196, 0, 393, 428, - 451, 215, 0, 0, 406, 444, 447, 0, 359, 216, - 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, - 266, 334, 423, 252, 431, 322, 210, 272, 389, 286, - 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 190, 203, - 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 192, 193, 204, 212, 221, 233, 246, 254, - 264, 268, 271, 274, 275, 278, 283, 300, 305, 306, - 307, 308, 324, 325, 326, 329, 332, 333, 336, 338, - 339, 342, 348, 349, 350, 351, 352, 354, 361, 365, - 373, 374, 375, 376, 377, 378, 379, 383, 384, 385, - 386, 394, 398, 413, 414, 425, 437, 441, 265, 421, - 442, 0, 299, 0, 0, 301, 250, 267, 276, 0, - 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, - 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, - 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, - 0, 0, 1071, 0, 0, 0, 0, 241, 0, 0, - 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, - 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, - 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, - 0, 0, 0, 177, 178, 179, 0, 1073, 0, 0, - 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, - 0, 237, 277, 243, 236, 407, 959, 960, 958, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 961, 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, 263, 0, - 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, - 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, - 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, - 424, 213, 253, 363, 346, 368, 0, 0, 369, 294, - 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, - 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, - 284, 387, 261, 194, 292, 198, 399, 420, 218, 380, - 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, - 0, 362, 239, 259, 230, 330, 415, 416, 229, 450, - 208, 435, 202, 209, 434, 323, 411, 419, 312, 303, - 201, 417, 310, 302, 287, 249, 269, 356, 297, 357, - 270, 319, 318, 320, 0, 196, 0, 393, 428, 451, - 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, - 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, - 334, 423, 252, 431, 322, 210, 272, 389, 286, 295, - 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 190, 203, 291, - 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 204, 212, 221, 233, 246, 254, 264, - 268, 271, 274, 275, 278, 283, 300, 305, 306, 307, - 308, 324, 325, 326, 329, 332, 333, 336, 338, 339, - 342, 348, 349, 350, 351, 352, 354, 361, 365, 373, - 374, 375, 376, 377, 378, 379, 383, 384, 385, 386, - 394, 398, 413, 414, 425, 437, 441, 265, 421, 442, - 0, 299, 0, 0, 301, 250, 267, 276, 0, 432, - 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, - 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, - 381, 401, 402, 403, 405, 313, 238, 34, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 331, 0, 0, 0, 0, 0, 0, 0, 0, 241, - 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, - 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, - 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, - 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, - 392, 255, 69, 0, 586, 177, 178, 179, 0, 0, - 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, - 0, 0, 0, 237, 277, 243, 236, 407, 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, - 263, 0, 317, 0, 0, 0, 438, 0, 0, 0, - 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, - 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, - 370, 341, 424, 213, 253, 363, 346, 368, 0, 0, - 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, - 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, - 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, - 218, 380, 0, 0, 0, 200, 418, 396, 311, 281, - 282, 199, 0, 362, 239, 259, 230, 330, 415, 416, - 229, 450, 208, 435, 202, 209, 434, 323, 411, 419, - 312, 303, 201, 417, 310, 302, 287, 249, 269, 356, - 297, 357, 270, 319, 318, 320, 0, 196, 0, 393, - 428, 451, 215, 0, 0, 406, 444, 447, 0, 359, - 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, - 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, - 286, 295, 0, 0, 340, 371, 219, 426, 390, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, - 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, - 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 192, 193, 204, 212, 221, 233, 246, - 254, 264, 268, 271, 274, 275, 278, 283, 300, 305, - 306, 307, 308, 324, 325, 326, 329, 332, 333, 336, - 338, 339, 342, 348, 349, 350, 351, 352, 354, 361, - 365, 373, 374, 375, 376, 377, 378, 379, 383, 384, - 385, 386, 394, 398, 413, 414, 425, 437, 441, 265, - 421, 442, 0, 299, 0, 0, 301, 250, 267, 276, - 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, - 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, - 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, - 0, 0, 0, 1440, 0, 0, 0, 0, 241, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, - 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 304, 343, 400, 337, 554, 293, 0, 0, 391, 316, + 0, 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, - 255, 0, 0, 0, 177, 178, 179, 0, 1442, 0, - 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, - 0, 0, 237, 277, 243, 236, 407, 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, + 255, 69, 0, 586, 177, 178, 179, 532, 531, 534, + 535, 536, 537, 0, 0, 217, 533, 223, 538, 539, + 540, 0, 237, 277, 243, 236, 407, 0, 0, 0, + 0, 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 522, 523, 0, 0, 0, 0, 568, + 0, 524, 0, 0, 517, 518, 520, 519, 521, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, - 0, 317, 0, 0, 0, 438, 0, 0, 0, 0, + 0, 317, 567, 0, 0, 438, 0, 0, 565, 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, - 341, 424, 213, 253, 363, 346, 368, 0, 1438, 369, + 341, 424, 213, 253, 363, 346, 368, 0, 0, 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, 218, @@ -2819,9 +2524,9 @@ var yyAct = [...]int{ 451, 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, 286, - 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 190, 203, + 295, 0, 0, 340, 371, 219, 426, 390, 555, 566, + 561, 562, 559, 560, 0, 558, 557, 556, 569, 547, + 548, 549, 550, 552, 0, 563, 564, 551, 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2838,19 +2543,19 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, - 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 343, 400, 337, 554, 293, 0, 0, 391, 316, 0, + 0, 0, 0, 0, 545, 546, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, - 0, 0, 0, 177, 178, 179, 0, 0, 0, 0, - 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, + 69, 0, 0, 177, 178, 179, 532, 531, 534, 535, + 536, 537, 0, 0, 217, 533, 223, 538, 539, 540, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, + 525, 0, 553, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 758, 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, 522, 523, 0, 0, 0, 0, 568, 0, + 524, 0, 0, 517, 518, 520, 519, 521, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, - 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, - 0, 0, 0, 288, 764, 285, 191, 205, 762, 0, + 317, 567, 0, 0, 438, 0, 0, 565, 0, 0, + 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, 253, 363, 346, 368, 0, 0, 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, @@ -2864,9 +2569,9 @@ var yyAct = [...]int{ 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, 286, 295, - 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 190, 203, 291, + 0, 0, 340, 371, 219, 426, 390, 555, 566, 561, + 562, 559, 560, 0, 558, 557, 556, 569, 547, 548, + 549, 550, 552, 0, 563, 564, 551, 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2880,19 +2585,19 @@ var yyAct = [...]int{ 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, - 0, 1440, 0, 0, 0, 0, 241, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, - 0, 0, 177, 178, 179, 0, 1442, 0, 0, 0, + 0, 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 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, 969, 968, 978, + 979, 971, 972, 973, 974, 975, 976, 977, 970, 0, + 0, 980, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 263, 0, 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, @@ -2924,105 +2629,105 @@ var yyAct = [...]int{ 299, 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, - 401, 402, 403, 405, 313, 238, 34, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, - 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, - 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, - 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, - 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, + 401, 402, 403, 405, 313, 238, 331, 0, 0, 0, + 0, 0, 0, 0, 0, 241, 799, 0, 0, 0, + 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, + 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, + 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, - 255, 69, 0, 0, 177, 178, 179, 0, 0, 0, - 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, - 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, + 0, 0, 279, 225, 195, 328, 392, 255, 0, 0, + 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, + 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, + 277, 243, 236, 407, 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, 263, - 0, 317, 0, 0, 0, 438, 0, 0, 0, 0, - 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, - 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, - 341, 424, 213, 253, 363, 346, 368, 0, 0, 369, - 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, - 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, - 409, 284, 387, 261, 194, 292, 198, 399, 420, 218, - 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, - 199, 0, 362, 239, 259, 230, 330, 415, 416, 229, - 450, 208, 435, 202, 209, 434, 323, 411, 419, 312, - 303, 201, 417, 310, 302, 287, 249, 269, 356, 297, - 357, 270, 319, 318, 320, 0, 196, 0, 393, 428, - 451, 215, 0, 0, 406, 444, 447, 0, 359, 216, - 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, - 266, 334, 423, 252, 431, 322, 210, 272, 389, 286, - 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 190, 203, - 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 192, 193, 204, 212, 221, 233, 246, 254, - 264, 268, 271, 274, 275, 278, 283, 300, 305, 306, - 307, 308, 324, 325, 326, 329, 332, 333, 336, 338, - 339, 342, 348, 349, 350, 351, 352, 354, 361, 365, - 373, 374, 375, 376, 377, 378, 379, 383, 384, 385, - 386, 394, 398, 413, 414, 425, 437, 441, 265, 421, - 442, 0, 299, 0, 0, 301, 250, 267, 276, 0, - 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, - 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, - 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, - 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, - 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, - 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, - 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, + 0, 0, 0, 0, 0, 0, 263, 0, 317, 0, + 0, 798, 438, 0, 0, 0, 0, 0, 0, 795, + 796, 288, 764, 285, 191, 205, 789, 793, 327, 366, + 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, + 253, 363, 346, 368, 0, 0, 369, 294, 412, 358, + 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, + 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, + 261, 194, 292, 198, 399, 420, 218, 380, 0, 0, + 0, 200, 418, 396, 311, 281, 282, 199, 0, 362, + 239, 259, 230, 330, 415, 416, 229, 450, 208, 435, + 202, 209, 434, 323, 411, 419, 312, 303, 201, 417, + 310, 302, 287, 249, 269, 356, 297, 357, 270, 319, + 318, 320, 0, 196, 0, 393, 428, 451, 215, 0, + 0, 406, 444, 447, 0, 359, 216, 260, 248, 355, + 258, 290, 443, 445, 446, 214, 353, 266, 334, 423, + 252, 431, 322, 210, 272, 389, 286, 295, 0, 0, + 340, 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, - 0, 0, 0, 177, 178, 179, 0, 0, 1460, 0, - 0, 1461, 0, 0, 217, 0, 223, 0, 0, 0, - 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 190, 203, 291, 0, 360, + 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, + 193, 204, 212, 221, 233, 246, 254, 264, 268, 271, + 274, 275, 278, 283, 300, 305, 306, 307, 308, 324, + 325, 326, 329, 332, 333, 336, 338, 339, 342, 348, + 349, 350, 351, 352, 354, 361, 365, 373, 374, 375, + 376, 377, 378, 379, 383, 384, 385, 386, 394, 398, + 413, 414, 425, 437, 441, 265, 421, 442, 0, 299, + 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, + 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, + 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, + 402, 403, 405, 313, 238, 331, 0, 0, 0, 1070, + 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, + 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, + 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, + 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 279, 225, 195, 328, 392, 255, 0, 0, 0, + 177, 178, 179, 0, 1072, 0, 0, 0, 0, 0, + 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, + 243, 236, 407, 958, 959, 957, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 960, 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, 263, 0, - 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, - 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, - 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, - 424, 213, 253, 363, 346, 368, 0, 0, 369, 294, - 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, - 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, - 284, 387, 261, 194, 292, 198, 399, 420, 218, 380, - 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, - 0, 362, 239, 259, 230, 330, 415, 416, 229, 450, - 208, 435, 202, 209, 434, 323, 411, 419, 312, 303, - 201, 417, 310, 302, 287, 249, 269, 356, 297, 357, - 270, 319, 318, 320, 0, 196, 0, 393, 428, 451, - 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, - 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, - 334, 423, 252, 431, 322, 210, 272, 389, 286, 295, - 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 190, 203, 291, - 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, + 0, 0, 0, 0, 0, 263, 0, 317, 0, 0, + 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, + 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, + 0, 0, 0, 228, 0, 370, 341, 424, 213, 253, + 363, 346, 368, 0, 0, 369, 294, 412, 358, 422, + 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, + 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, + 194, 292, 198, 399, 420, 218, 380, 0, 0, 0, + 200, 418, 396, 311, 281, 282, 199, 0, 362, 239, + 259, 230, 330, 415, 416, 229, 450, 208, 435, 202, + 209, 434, 323, 411, 419, 312, 303, 201, 417, 310, + 302, 287, 249, 269, 356, 297, 357, 270, 319, 318, + 320, 0, 196, 0, 393, 428, 451, 215, 0, 0, + 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, + 290, 443, 445, 446, 214, 353, 266, 334, 423, 252, + 431, 322, 210, 272, 389, 286, 295, 0, 0, 340, + 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 190, 203, 291, 0, 360, 256, + 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 204, 212, 221, 233, 246, 254, 264, - 268, 271, 274, 275, 278, 283, 300, 305, 306, 307, - 308, 324, 325, 326, 329, 332, 333, 336, 338, 339, - 342, 348, 349, 350, 351, 352, 354, 361, 365, 373, - 374, 375, 376, 377, 378, 379, 383, 384, 385, 386, - 394, 398, 413, 414, 425, 437, 441, 265, 421, 442, - 0, 299, 0, 0, 301, 250, 267, 276, 0, 432, - 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, - 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, - 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, - 0, 0, 0, 0, 0, 0, 241, 0, 1104, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, + 204, 212, 221, 233, 246, 254, 264, 268, 271, 274, + 275, 278, 283, 300, 305, 306, 307, 308, 324, 325, + 326, 329, 332, 333, 336, 338, 339, 342, 348, 349, + 350, 351, 352, 354, 361, 365, 373, 374, 375, 376, + 377, 378, 379, 383, 384, 385, 386, 394, 398, 413, + 414, 425, 437, 441, 265, 421, 442, 0, 299, 0, + 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, + 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, + 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, + 403, 405, 313, 238, 34, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 331, 0, 0, + 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, - 0, 0, 177, 178, 179, 0, 1103, 0, 0, 0, + 0, 0, 0, 279, 225, 195, 328, 392, 255, 69, + 0, 586, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3061,13 +2766,13 @@ var yyAct = [...]int{ 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, 0, - 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, + 1439, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, 0, - 586, 177, 178, 179, 0, 0, 0, 0, 0, 0, + 0, 177, 178, 179, 0, 1441, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3078,7 +2783,7 @@ var yyAct = [...]int{ 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, - 253, 363, 346, 368, 0, 0, 369, 294, 412, 358, + 253, 363, 346, 368, 0, 1437, 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, 218, 380, 0, 0, @@ -3111,11 +2816,147 @@ var yyAct = [...]int{ 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 279, 225, 195, 328, 392, 255, 69, 0, 0, + 0, 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 758, 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, 263, 0, 317, 0, 0, + 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, + 288, 764, 285, 191, 205, 762, 0, 327, 366, 372, + 0, 0, 0, 228, 0, 370, 341, 424, 213, 253, + 363, 346, 368, 0, 0, 369, 294, 412, 358, 422, + 439, 440, 235, 321, 430, 404, 436, 448, 206, 232, + 335, 397, 427, 388, 314, 408, 409, 284, 387, 261, + 194, 292, 198, 399, 420, 218, 380, 0, 0, 0, + 200, 418, 396, 311, 281, 282, 199, 0, 362, 239, + 259, 230, 330, 415, 416, 229, 450, 208, 435, 202, + 209, 434, 323, 411, 419, 312, 303, 201, 417, 310, + 302, 287, 249, 269, 356, 297, 357, 270, 319, 318, + 320, 0, 196, 0, 393, 428, 451, 215, 0, 0, + 406, 444, 447, 0, 359, 216, 260, 248, 355, 258, + 290, 443, 445, 446, 214, 353, 266, 334, 423, 252, + 431, 322, 210, 272, 389, 286, 295, 0, 0, 340, + 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 190, 203, 291, 0, 360, 256, + 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, + 204, 212, 221, 233, 246, 254, 264, 268, 271, 274, + 275, 278, 283, 300, 305, 306, 307, 308, 324, 325, + 326, 329, 332, 333, 336, 338, 339, 342, 348, 349, + 350, 351, 352, 354, 361, 365, 373, 374, 375, 376, + 377, 378, 379, 383, 384, 385, 386, 394, 398, 413, + 414, 425, 437, 441, 265, 421, 442, 0, 299, 0, + 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, + 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, + 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, + 403, 405, 313, 238, 331, 0, 0, 0, 1439, 0, + 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, + 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, + 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, + 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, + 178, 179, 0, 1441, 0, 0, 0, 0, 0, 0, + 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, + 236, 407, 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, 263, 0, 317, 0, 0, 0, + 438, 0, 0, 0, 0, 0, 0, 0, 0, 288, + 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, + 0, 0, 228, 0, 370, 341, 424, 213, 253, 363, + 346, 368, 0, 0, 369, 294, 412, 358, 422, 439, + 440, 235, 321, 430, 404, 436, 448, 206, 232, 335, + 397, 427, 388, 314, 408, 409, 284, 387, 261, 194, + 292, 198, 399, 420, 218, 380, 0, 0, 0, 200, + 418, 396, 311, 281, 282, 199, 0, 362, 239, 259, + 230, 330, 415, 416, 229, 450, 208, 435, 202, 209, + 434, 323, 411, 419, 312, 303, 201, 417, 310, 302, + 287, 249, 269, 356, 297, 357, 270, 319, 318, 320, + 0, 196, 0, 393, 428, 451, 215, 0, 0, 406, + 444, 447, 0, 359, 216, 260, 248, 355, 258, 290, + 443, 445, 446, 214, 353, 266, 334, 423, 252, 431, + 322, 210, 272, 389, 286, 295, 0, 0, 340, 371, + 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 190, 203, 291, 0, 360, 256, 449, + 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 192, 193, 204, + 212, 221, 233, 246, 254, 264, 268, 271, 274, 275, + 278, 283, 300, 305, 306, 307, 308, 324, 325, 326, + 329, 332, 333, 336, 338, 339, 342, 348, 349, 350, + 351, 352, 354, 361, 365, 373, 374, 375, 376, 377, + 378, 379, 383, 384, 385, 386, 394, 398, 413, 414, + 425, 437, 441, 265, 421, 442, 0, 299, 0, 0, + 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, + 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, + 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, + 405, 313, 238, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, + 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, + 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, + 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, + 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 279, 225, 195, 328, 392, 255, 69, 0, + 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, + 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, + 277, 243, 236, 407, 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, 263, 0, 317, 0, + 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, + 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, + 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, + 253, 363, 346, 368, 0, 0, 369, 294, 412, 358, + 422, 439, 440, 235, 321, 430, 404, 436, 448, 206, + 232, 335, 397, 427, 388, 314, 408, 409, 284, 387, + 261, 194, 292, 198, 399, 420, 218, 380, 0, 0, + 0, 200, 418, 396, 311, 281, 282, 199, 0, 362, + 239, 259, 230, 330, 415, 416, 229, 450, 208, 435, + 202, 209, 434, 323, 411, 419, 312, 303, 201, 417, + 310, 302, 287, 249, 269, 356, 297, 357, 270, 319, + 318, 320, 0, 196, 0, 393, 428, 451, 215, 0, + 0, 406, 444, 447, 0, 359, 216, 260, 248, 355, + 258, 290, 443, 445, 446, 214, 353, 266, 334, 423, + 252, 431, 322, 210, 272, 389, 286, 295, 0, 0, + 340, 371, 219, 426, 390, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 190, 203, 291, 0, 360, + 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, + 193, 204, 212, 221, 233, 246, 254, 264, 268, 271, + 274, 275, 278, 283, 300, 305, 306, 307, 308, 324, + 325, 326, 329, 332, 333, 336, 338, 339, 342, 348, + 349, 350, 351, 352, 354, 361, 365, 373, 374, 375, + 376, 377, 378, 379, 383, 384, 385, 386, 394, 398, + 413, 414, 425, 437, 441, 265, 421, 442, 0, 299, + 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, + 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, + 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, + 402, 403, 405, 313, 238, 331, 0, 0, 0, 0, + 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, + 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, + 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, + 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 279, 225, 195, 328, 392, 255, 0, 0, 0, + 177, 178, 179, 0, 0, 1459, 0, 0, 1460, 0, + 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, + 243, 236, 407, 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, @@ -3151,13 +2992,13 @@ var yyAct = [...]int{ 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, 0, 0, 0, - 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, + 0, 0, 0, 241, 0, 1103, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, - 178, 179, 0, 1442, 0, 0, 0, 0, 0, 0, + 178, 179, 0, 1102, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3201,8 +3042,8 @@ var yyAct = [...]int{ 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 225, 195, 328, 392, 255, 0, 0, 0, 177, 178, - 179, 0, 1073, 0, 0, 0, 0, 0, 0, 217, + 225, 195, 328, 392, 255, 0, 0, 586, 177, 178, + 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3246,7 +3087,7 @@ var yyAct = [...]int{ 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, - 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, + 195, 328, 392, 255, 69, 0, 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3272,7 +3113,7 @@ var yyAct = [...]int{ 272, 389, 286, 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 190, 203, 291, 1345, 360, 256, 449, 433, 429, + 0, 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 204, 212, 221, @@ -3285,14 +3126,14 @@ var yyAct = [...]int{ 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, - 238, 331, 0, 1228, 0, 0, 0, 0, 0, 0, + 238, 331, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, 0, - 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, + 1441, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3330,13 +3171,13 @@ var yyAct = [...]int{ 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, - 331, 0, 1226, 0, 0, 0, 0, 0, 0, 241, + 331, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, - 392, 255, 0, 0, 0, 177, 178, 179, 0, 0, + 392, 255, 0, 0, 0, 177, 178, 179, 0, 1072, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3375,7 +3216,7 @@ var yyAct = [...]int{ 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, - 0, 1224, 0, 0, 0, 0, 0, 0, 241, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, @@ -3407,7 +3248,7 @@ var yyAct = [...]int{ 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, 203, - 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, + 291, 1344, 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 193, 204, 212, 221, 233, 246, 254, @@ -3420,7 +3261,7 @@ var yyAct = [...]int{ 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, - 1222, 0, 0, 0, 0, 0, 0, 241, 0, 0, + 1227, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, @@ -3464,7 +3305,7 @@ var yyAct = [...]int{ 0, 299, 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, - 381, 401, 402, 403, 405, 313, 238, 331, 0, 1220, + 381, 401, 402, 403, 405, 313, 238, 331, 0, 1225, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, @@ -3509,7 +3350,7 @@ var yyAct = [...]int{ 299, 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, - 401, 402, 403, 405, 313, 238, 331, 0, 1216, 0, + 401, 402, 403, 405, 313, 238, 331, 0, 1223, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, @@ -3554,7 +3395,7 @@ var yyAct = [...]int{ 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, - 402, 403, 405, 313, 238, 331, 0, 1214, 0, 0, + 402, 403, 405, 313, 238, 331, 0, 1221, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, @@ -3599,7 +3440,7 @@ var yyAct = [...]int{ 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, - 403, 405, 313, 238, 331, 0, 1212, 0, 0, 0, + 403, 405, 313, 238, 331, 0, 1219, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, @@ -3644,13 +3485,13 @@ var yyAct = [...]int{ 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, - 405, 313, 238, 331, 0, 0, 0, 0, 0, 0, + 405, 313, 238, 331, 0, 1215, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 225, 195, 328, 392, 255, 1187, 0, 0, 177, 178, + 225, 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3689,142 +3530,142 @@ var yyAct = [...]int{ 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, - 313, 238, 1086, 0, 0, 0, 0, 0, 0, 331, - 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, - 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, - 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, - 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, - 255, 0, 0, 0, 177, 178, 179, 0, 0, 0, - 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, - 0, 0, 237, 277, 243, 236, 407, 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, 263, - 0, 317, 0, 0, 0, 438, 0, 0, 0, 0, - 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, - 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, - 341, 424, 213, 253, 363, 346, 368, 0, 0, 369, - 294, 412, 358, 422, 439, 440, 235, 321, 430, 404, - 436, 448, 206, 232, 335, 397, 427, 388, 314, 408, - 409, 284, 387, 261, 194, 292, 198, 399, 420, 218, - 380, 0, 0, 0, 200, 418, 396, 311, 281, 282, - 199, 0, 362, 239, 259, 230, 330, 415, 416, 229, - 450, 208, 435, 202, 209, 434, 323, 411, 419, 312, - 303, 201, 417, 310, 302, 287, 249, 269, 356, 297, - 357, 270, 319, 318, 320, 0, 196, 0, 393, 428, - 451, 215, 0, 0, 406, 444, 447, 0, 359, 216, - 260, 248, 355, 258, 290, 443, 445, 446, 214, 353, - 266, 334, 423, 252, 431, 322, 210, 272, 389, 286, - 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 190, 203, - 291, 0, 360, 256, 449, 433, 429, 0, 0, 234, + 313, 238, 331, 0, 1213, 0, 0, 0, 0, 0, + 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, + 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, + 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, + 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, + 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, + 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, + 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 192, 193, 204, 212, 221, 233, 246, 254, - 264, 268, 271, 274, 275, 278, 283, 300, 305, 306, - 307, 308, 324, 325, 326, 329, 332, 333, 336, 338, - 339, 342, 348, 349, 350, 351, 352, 354, 361, 365, - 373, 374, 375, 376, 377, 378, 379, 383, 384, 385, - 386, 394, 398, 413, 414, 425, 437, 441, 265, 421, - 442, 0, 299, 0, 0, 301, 250, 267, 276, 0, - 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, - 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, - 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, - 0, 0, 0, 0, 0, 0, 1077, 241, 0, 0, - 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, - 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, - 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, - 0, 0, 0, 177, 178, 179, 0, 0, 0, 0, - 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, - 0, 237, 277, 243, 236, 407, 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, 263, 0, 317, 0, 0, 0, 438, 0, + 0, 0, 0, 0, 0, 0, 0, 288, 0, 285, + 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, + 228, 0, 370, 341, 424, 213, 253, 363, 346, 368, + 0, 0, 369, 294, 412, 358, 422, 439, 440, 235, + 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, + 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, + 399, 420, 218, 380, 0, 0, 0, 200, 418, 396, + 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, + 415, 416, 229, 450, 208, 435, 202, 209, 434, 323, + 411, 419, 312, 303, 201, 417, 310, 302, 287, 249, + 269, 356, 297, 357, 270, 319, 318, 320, 0, 196, + 0, 393, 428, 451, 215, 0, 0, 406, 444, 447, + 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, + 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, + 272, 389, 286, 295, 0, 0, 340, 371, 219, 426, + 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 190, 203, 291, 0, 360, 256, 449, 433, 429, + 0, 0, 234, 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, 263, 0, - 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, - 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, - 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, - 424, 213, 253, 363, 346, 368, 0, 0, 369, 294, - 412, 358, 422, 439, 440, 235, 321, 430, 404, 436, - 448, 206, 232, 335, 397, 427, 388, 314, 408, 409, - 284, 387, 261, 194, 292, 198, 399, 420, 218, 380, - 0, 0, 0, 200, 418, 396, 311, 281, 282, 199, - 0, 362, 239, 259, 230, 330, 415, 416, 229, 450, - 208, 435, 202, 209, 434, 323, 411, 419, 312, 303, - 201, 417, 310, 302, 287, 249, 269, 356, 297, 357, - 270, 319, 318, 320, 0, 196, 0, 393, 428, 451, - 215, 0, 0, 406, 444, 447, 0, 359, 216, 260, - 248, 355, 258, 290, 443, 445, 446, 214, 353, 266, - 334, 423, 252, 431, 322, 210, 272, 389, 286, 295, - 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, + 0, 0, 0, 0, 0, 192, 193, 204, 212, 221, + 233, 246, 254, 264, 268, 271, 274, 275, 278, 283, + 300, 305, 306, 307, 308, 324, 325, 326, 329, 332, + 333, 336, 338, 339, 342, 348, 349, 350, 351, 352, + 354, 361, 365, 373, 374, 375, 376, 377, 378, 379, + 383, 384, 385, 386, 394, 398, 413, 414, 425, 437, + 441, 265, 421, 442, 0, 299, 0, 0, 301, 250, + 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, + 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, + 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, + 238, 331, 0, 1211, 0, 0, 0, 0, 0, 0, + 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, + 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, + 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, + 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, + 328, 392, 255, 0, 0, 0, 177, 178, 179, 0, + 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, + 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 190, 203, 291, - 0, 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 192, 193, 204, 212, 221, 233, 246, 254, 264, - 268, 271, 274, 275, 278, 283, 300, 305, 306, 307, - 308, 324, 325, 326, 329, 332, 333, 336, 338, 339, - 342, 348, 349, 350, 351, 352, 354, 361, 365, 373, - 374, 375, 376, 377, 378, 379, 383, 384, 385, 386, - 394, 398, 413, 414, 425, 437, 441, 265, 421, 442, - 0, 299, 0, 0, 301, 250, 267, 276, 0, 432, - 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, - 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, - 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, - 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, - 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, - 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, - 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, - 0, 0, 177, 178, 179, 0, 935, 0, 0, 0, - 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, - 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 263, 0, 317, 0, 0, 0, 438, 0, 0, + 0, 0, 0, 0, 0, 0, 288, 0, 285, 191, + 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, + 0, 370, 341, 424, 213, 253, 363, 346, 368, 0, + 0, 369, 294, 412, 358, 422, 439, 440, 235, 321, + 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, + 314, 408, 409, 284, 387, 261, 194, 292, 198, 399, + 420, 218, 380, 0, 0, 0, 200, 418, 396, 311, + 281, 282, 199, 0, 362, 239, 259, 230, 330, 415, + 416, 229, 450, 208, 435, 202, 209, 434, 323, 411, + 419, 312, 303, 201, 417, 310, 302, 287, 249, 269, + 356, 297, 357, 270, 319, 318, 320, 0, 196, 0, + 393, 428, 451, 215, 0, 0, 406, 444, 447, 0, + 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, + 214, 353, 266, 334, 423, 252, 431, 322, 210, 272, + 389, 286, 295, 0, 0, 340, 371, 219, 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, + 0, 234, 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, 263, 0, 317, - 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, - 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, - 366, 372, 0, 0, 0, 228, 0, 370, 341, 424, - 213, 253, 363, 346, 368, 0, 0, 369, 294, 412, - 358, 422, 439, 440, 235, 321, 430, 404, 436, 448, - 206, 232, 335, 397, 427, 388, 314, 408, 409, 284, - 387, 261, 194, 292, 198, 399, 420, 218, 380, 0, - 0, 0, 200, 418, 396, 311, 281, 282, 199, 0, - 362, 239, 259, 230, 330, 415, 416, 229, 450, 208, - 435, 202, 209, 434, 323, 411, 419, 312, 303, 201, - 417, 310, 302, 287, 249, 269, 356, 297, 357, 270, - 319, 318, 320, 0, 196, 0, 393, 428, 451, 215, - 0, 0, 406, 444, 447, 0, 359, 216, 260, 248, - 355, 258, 290, 443, 445, 446, 214, 353, 266, 334, - 423, 252, 431, 322, 210, 272, 389, 286, 295, 0, - 0, 340, 371, 219, 426, 390, 0, 0, 0, 0, + 0, 0, 0, 0, 192, 193, 204, 212, 221, 233, + 246, 254, 264, 268, 271, 274, 275, 278, 283, 300, + 305, 306, 307, 308, 324, 325, 326, 329, 332, 333, + 336, 338, 339, 342, 348, 349, 350, 351, 352, 354, + 361, 365, 373, 374, 375, 376, 377, 378, 379, 383, + 384, 385, 386, 394, 398, 413, 414, 425, 437, 441, + 265, 421, 442, 0, 299, 0, 0, 301, 250, 267, + 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, + 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, + 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, + 331, 0, 0, 0, 0, 0, 0, 0, 0, 241, + 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, + 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, + 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, + 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, + 392, 255, 1186, 0, 0, 177, 178, 179, 0, 0, + 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, + 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 190, 203, 291, 0, - 360, 256, 449, 433, 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 192, 193, 204, 212, 221, 233, 246, 254, 264, 268, - 271, 274, 275, 278, 283, 300, 305, 306, 307, 308, - 324, 325, 326, 329, 332, 333, 336, 338, 339, 342, - 348, 349, 350, 351, 352, 354, 361, 365, 373, 374, - 375, 376, 377, 378, 379, 383, 384, 385, 386, 394, - 398, 413, 414, 425, 437, 441, 265, 421, 442, 0, - 299, 0, 0, 301, 250, 267, 276, 0, 432, 395, - 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, - 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, - 401, 402, 403, 405, 313, 238, 331, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 263, 0, 317, 0, 0, 0, 438, 0, 0, 0, + 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, + 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, + 370, 341, 424, 213, 253, 363, 346, 368, 0, 0, + 369, 294, 412, 358, 422, 439, 440, 235, 321, 430, + 404, 436, 448, 206, 232, 335, 397, 427, 388, 314, + 408, 409, 284, 387, 261, 194, 292, 198, 399, 420, + 218, 380, 0, 0, 0, 200, 418, 396, 311, 281, + 282, 199, 0, 362, 239, 259, 230, 330, 415, 416, + 229, 450, 208, 435, 202, 209, 434, 323, 411, 419, + 312, 303, 201, 417, 310, 302, 287, 249, 269, 356, + 297, 357, 270, 319, 318, 320, 0, 196, 0, 393, + 428, 451, 215, 0, 0, 406, 444, 447, 0, 359, + 216, 260, 248, 355, 258, 290, 443, 445, 446, 214, + 353, 266, 334, 423, 252, 431, 322, 210, 272, 389, + 286, 295, 0, 0, 340, 371, 219, 426, 390, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 190, + 203, 291, 0, 360, 256, 449, 433, 429, 0, 0, + 234, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 192, 193, 204, 212, 221, 233, 246, + 254, 264, 268, 271, 274, 275, 278, 283, 300, 305, + 306, 307, 308, 324, 325, 326, 329, 332, 333, 336, + 338, 339, 342, 348, 349, 350, 351, 352, 354, 361, + 365, 373, 374, 375, 376, 377, 378, 379, 383, 384, + 385, 386, 394, 398, 413, 414, 425, 437, 441, 265, + 421, 442, 0, 299, 0, 0, 301, 250, 267, 276, + 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, + 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, + 364, 220, 381, 401, 402, 403, 405, 313, 238, 1085, + 0, 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, @@ -3838,7 +3679,7 @@ var yyAct = [...]int{ 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, 499, 0, 263, 0, 317, 0, + 0, 0, 0, 0, 0, 0, 263, 0, 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, @@ -3865,12 +3706,12 @@ var yyAct = [...]int{ 325, 326, 329, 332, 333, 336, 338, 339, 342, 348, 349, 350, 351, 352, 354, 361, 365, 373, 374, 375, 376, 377, 378, 379, 383, 384, 385, 386, 394, 398, - 413, 414, 425, 437, 441, 498, 421, 442, 0, 299, + 413, 414, 425, 437, 441, 265, 421, 442, 0, 299, 0, 0, 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, 331, 0, 0, 0, 0, - 0, 0, 0, 0, 241, 0, 0, 0, 0, 0, + 0, 0, 0, 1076, 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, 391, 316, 0, 0, 0, 0, @@ -3883,7 +3724,7 @@ var yyAct = [...]int{ 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, 263, 0, 317, 0, 185, + 0, 0, 0, 0, 0, 263, 0, 317, 0, 0, 0, 438, 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, 0, 370, 341, 424, 213, 253, @@ -3921,7 +3762,7 @@ var yyAct = [...]int{ 293, 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, 328, 392, 255, 0, 0, 0, 177, - 178, 179, 0, 0, 0, 0, 0, 0, 0, 0, + 178, 179, 0, 934, 0, 0, 0, 0, 0, 0, 217, 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3959,29 +3800,163 @@ var yyAct = [...]int{ 301, 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, 222, 364, 220, 381, 401, 402, 403, - 405, 313, 238, + 405, 313, 238, 331, 0, 0, 0, 0, 0, 0, + 0, 0, 241, 0, 0, 0, 0, 0, 289, 0, + 0, 0, 345, 0, 382, 227, 298, 296, 410, 251, + 244, 240, 226, 273, 304, 343, 400, 337, 0, 293, + 0, 0, 391, 316, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 225, 195, 328, 392, 255, 0, 0, 0, 177, 178, + 179, 0, 0, 0, 0, 0, 0, 0, 0, 217, + 0, 223, 0, 0, 0, 0, 237, 277, 243, 236, + 407, 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, 499, 0, 263, 0, 317, 0, 0, 0, 438, + 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, + 285, 191, 205, 0, 0, 327, 366, 372, 0, 0, + 0, 228, 0, 370, 341, 424, 213, 253, 363, 346, + 368, 0, 0, 369, 294, 412, 358, 422, 439, 440, + 235, 321, 430, 404, 436, 448, 206, 232, 335, 397, + 427, 388, 314, 408, 409, 284, 387, 261, 194, 292, + 198, 399, 420, 218, 380, 0, 0, 0, 200, 418, + 396, 311, 281, 282, 199, 0, 362, 239, 259, 230, + 330, 415, 416, 229, 450, 208, 435, 202, 209, 434, + 323, 411, 419, 312, 303, 201, 417, 310, 302, 287, + 249, 269, 356, 297, 357, 270, 319, 318, 320, 0, + 196, 0, 393, 428, 451, 215, 0, 0, 406, 444, + 447, 0, 359, 216, 260, 248, 355, 258, 290, 443, + 445, 446, 214, 353, 266, 334, 423, 252, 431, 322, + 210, 272, 389, 286, 295, 0, 0, 340, 371, 219, + 426, 390, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 190, 203, 291, 0, 360, 256, 449, 433, + 429, 0, 0, 234, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 192, 193, 204, 212, + 221, 233, 246, 254, 264, 268, 271, 274, 275, 278, + 283, 300, 305, 306, 307, 308, 324, 325, 326, 329, + 332, 333, 336, 338, 339, 342, 348, 349, 350, 351, + 352, 354, 361, 365, 373, 374, 375, 376, 377, 378, + 379, 383, 384, 385, 386, 394, 398, 413, 414, 425, + 437, 441, 498, 421, 442, 0, 299, 0, 0, 301, + 250, 267, 276, 0, 432, 395, 207, 367, 257, 197, + 224, 211, 231, 245, 247, 280, 309, 315, 344, 347, + 262, 242, 222, 364, 220, 381, 401, 402, 403, 405, + 313, 238, 331, 0, 0, 0, 0, 0, 0, 0, + 0, 241, 0, 0, 0, 0, 0, 289, 0, 0, + 0, 345, 0, 382, 227, 298, 296, 410, 251, 244, + 240, 226, 273, 304, 343, 400, 337, 0, 293, 0, + 0, 391, 316, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 225, + 195, 328, 392, 255, 0, 0, 0, 177, 178, 179, + 0, 0, 0, 0, 0, 0, 0, 0, 217, 0, + 223, 0, 0, 0, 0, 237, 277, 243, 236, 407, + 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, 263, 0, 317, 0, 185, 0, 438, 0, + 0, 0, 0, 0, 0, 0, 0, 288, 0, 285, + 191, 205, 0, 0, 327, 366, 372, 0, 0, 0, + 228, 0, 370, 341, 424, 213, 253, 363, 346, 368, + 0, 0, 369, 294, 412, 358, 422, 439, 440, 235, + 321, 430, 404, 436, 448, 206, 232, 335, 397, 427, + 388, 314, 408, 409, 284, 387, 261, 194, 292, 198, + 399, 420, 218, 380, 0, 0, 0, 200, 418, 396, + 311, 281, 282, 199, 0, 362, 239, 259, 230, 330, + 415, 416, 229, 450, 208, 435, 202, 209, 434, 323, + 411, 419, 312, 303, 201, 417, 310, 302, 287, 249, + 269, 356, 297, 357, 270, 319, 318, 320, 0, 196, + 0, 393, 428, 451, 215, 0, 0, 406, 444, 447, + 0, 359, 216, 260, 248, 355, 258, 290, 443, 445, + 446, 214, 353, 266, 334, 423, 252, 431, 322, 210, + 272, 389, 286, 295, 0, 0, 340, 371, 219, 426, + 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 190, 203, 291, 0, 360, 256, 449, 433, 429, + 0, 0, 234, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 192, 193, 204, 212, 221, + 233, 246, 254, 264, 268, 271, 274, 275, 278, 283, + 300, 305, 306, 307, 308, 324, 325, 326, 329, 332, + 333, 336, 338, 339, 342, 348, 349, 350, 351, 352, + 354, 361, 365, 373, 374, 375, 376, 377, 378, 379, + 383, 384, 385, 386, 394, 398, 413, 414, 425, 437, + 441, 265, 421, 442, 0, 299, 0, 0, 301, 250, + 267, 276, 0, 432, 395, 207, 367, 257, 197, 224, + 211, 231, 245, 247, 280, 309, 315, 344, 347, 262, + 242, 222, 364, 220, 381, 401, 402, 403, 405, 313, + 238, 331, 0, 0, 0, 0, 0, 0, 0, 0, + 241, 0, 0, 0, 0, 0, 289, 0, 0, 0, + 345, 0, 382, 227, 298, 296, 410, 251, 244, 240, + 226, 273, 304, 343, 400, 337, 0, 293, 0, 0, + 391, 316, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 225, 195, + 328, 392, 255, 0, 0, 0, 177, 178, 179, 0, + 0, 0, 0, 0, 0, 0, 0, 217, 0, 223, + 0, 0, 0, 0, 237, 277, 243, 236, 407, 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, 263, 0, 317, 0, 0, 0, 438, 0, 0, + 0, 0, 0, 0, 0, 0, 288, 0, 285, 191, + 205, 0, 0, 327, 366, 372, 0, 0, 0, 228, + 0, 370, 341, 424, 213, 253, 363, 346, 368, 0, + 0, 369, 294, 412, 358, 422, 439, 440, 235, 321, + 430, 404, 436, 448, 206, 232, 335, 397, 427, 388, + 314, 408, 409, 284, 387, 261, 194, 292, 198, 399, + 420, 218, 380, 0, 0, 0, 200, 418, 396, 311, + 281, 282, 199, 0, 362, 239, 259, 230, 330, 415, + 416, 229, 450, 208, 435, 202, 209, 434, 323, 411, + 419, 312, 303, 201, 417, 310, 302, 287, 249, 269, + 356, 297, 357, 270, 319, 318, 320, 0, 196, 0, + 393, 428, 451, 215, 0, 0, 406, 444, 447, 0, + 359, 216, 260, 248, 355, 258, 290, 443, 445, 446, + 214, 353, 266, 334, 423, 252, 431, 322, 210, 272, + 389, 286, 295, 0, 0, 340, 371, 219, 426, 390, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 190, 203, 291, 0, 360, 256, 449, 433, 429, 0, + 0, 234, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 192, 193, 204, 212, 221, 233, + 246, 254, 264, 268, 271, 274, 275, 278, 283, 300, + 305, 306, 307, 308, 324, 325, 326, 329, 332, 333, + 336, 338, 339, 342, 348, 349, 350, 351, 352, 354, + 361, 365, 373, 374, 375, 376, 377, 378, 379, 383, + 384, 385, 386, 394, 398, 413, 414, 425, 437, 441, + 265, 421, 442, 0, 299, 0, 0, 301, 250, 267, + 276, 0, 432, 395, 207, 367, 257, 197, 224, 211, + 231, 245, 247, 280, 309, 315, 344, 347, 262, 242, + 222, 364, 220, 381, 401, 402, 403, 405, 313, 238, } var yyPact = [...]int{ - 2844, -1000, -339, 1580, -1000, -1000, -1000, -1000, -1000, -1000, + 3531, -1000, -341, 1618, -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, 1523, 1148, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 551, 1235, 165, 1436, 258, 181, 886, 390, 120, - 26886, 389, 2209, 27335, -1000, 118, -1000, 93, 27335, 102, - 26437, -1000, -1000, -279, 12485, 1410, 7, 5, 27335, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1224, 1499, 1506, - 1521, 1069, 1513, -1000, 10676, 10676, 298, 298, 298, 8880, - -1000, -1000, 16539, 27335, 27335, 1241, 386, 886, 376, 361, - 350, 300, -100, -1000, -1000, -1000, -1000, 1436, -1000, -1000, - 153, -1000, 234, 1165, -1000, 1162, -1000, 477, 415, 231, - 311, 303, 230, 229, 228, 227, 226, 225, 223, 213, - 241, -1000, 535, 535, -171, -175, 2362, 284, 284, 284, - 320, 1421, 1419, -1000, 515, -1000, 535, 535, 150, 535, - 535, 535, 535, 192, 186, 535, 535, 535, 535, 535, - 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, - 27335, -1000, 157, 485, 556, 1436, 182, -1000, -1000, -1000, - 27335, 384, 886, 295, 295, 27335, -1000, 461, -1000, -1000, + -1000, -1000, 1586, 1190, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 579, 1259, 181, 1495, 267, 162, 937, 421, 114, + 26643, 420, 2186, 27092, -1000, 85, -1000, 73, 27092, 84, + 26194, -1000, -1000, -278, 12242, 1456, 8, 6, 27092, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1228, 1552, 1557, + 1581, 1059, 1730, -1000, 10433, 10433, 368, 368, 368, 8637, + -1000, -1000, 16296, 27092, 27092, 1264, 419, 937, 404, 402, + 399, -1000, -95, -1000, -1000, -1000, -1000, 1495, -1000, -1000, + 144, -1000, 271, 1194, -1000, 1192, -1000, 361, 470, 266, + 324, 296, 265, 264, 239, 238, 236, 234, 231, 228, + 275, -1000, 576, 576, -161, -165, 2411, 332, 332, 332, + 379, 1474, 1472, -1000, 508, -1000, 576, 576, 138, 576, + 576, 576, 576, 176, 170, 576, 576, 576, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, + 27092, -1000, 118, 603, 609, 1495, 153, -1000, -1000, -1000, + 27092, 409, 937, 341, -1000, 27092, -1000, 473, -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, @@ -4008,23 +3983,23 @@ 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, 27335, 638, 638, 68, 638, 638, 638, 638, - 78, 412, -32, -1000, 50, 173, 171, 164, 618, 75, - 59, -1000, -1000, 161, 81, -1000, 638, 7028, 7028, 7028, - -1000, 1431, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 319, -1000, -1000, -1000, -1000, 27335, 25988, 236, 554, -1000, - -1000, -1000, 52, -1000, -1000, 1119, 766, -1000, 12485, 1285, - 1170, 1170, -1000, -1000, 431, -1000, -1000, 13832, 13832, 13832, - 13832, 13832, 13832, 13832, 13832, 13832, 13832, -1000, -1000, -1000, + -1000, -1000, 27092, 645, 645, 58, 645, 645, 645, 645, + 82, 472, 0, -1000, 80, 146, 125, 148, 641, 135, + 66, -1000, -1000, 139, 81, -1000, 645, 6785, 6785, 6785, + -1000, 1487, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 378, -1000, -1000, -1000, -1000, 27092, 25745, 259, 608, -1000, + -1000, -1000, 52, -1000, -1000, 1108, 776, -1000, 12242, 2109, + 1191, 1191, -1000, -1000, 438, -1000, -1000, 13589, 13589, 13589, + 13589, 13589, 13589, 13589, 13589, 13589, 13589, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 1170, 450, -1000, 12036, 1170, 1170, 1170, 1170, 1170, - 1170, 1170, 1170, 12485, 1170, 1170, 1170, 1170, 1170, 1170, - 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, - -1000, -1000, -1000, 27335, -1000, 1170, 1523, -1000, 1148, -1000, - -1000, -1000, 1439, 12485, 12485, 1523, -1000, 1294, 10676, -1000, - -1000, 1408, -1000, -1000, -1000, -1000, -1000, 634, 1555, -1000, - 15179, 447, 1554, 25539, -1000, 19246, 25090, 1161, 8417, -28, - -1000, -1000, -1000, 550, 18348, -1000, -1000, -1000, -1000, -1000, + -1000, 1191, 471, -1000, 11793, 1191, 1191, 1191, 1191, 1191, + 1191, 1191, 1191, 12242, 1191, 1191, 1191, 1191, 1191, 1191, + 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, 1191, + -1000, -1000, -1000, 27092, -1000, 1191, 1586, -1000, 1190, -1000, + -1000, -1000, 1494, 12242, 12242, 1586, -1000, 1394, 10433, -1000, + -1000, 1701, -1000, -1000, -1000, -1000, -1000, 678, 1601, -1000, + 14936, 466, 1599, 25296, -1000, 19003, 24847, 1187, 8174, -64, + -1000, -1000, -1000, 605, 18105, -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, @@ -4038,186 +4013,186 @@ 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, 1431, 1113, 27335, -1000, - -1000, 3379, 886, -1000, 1232, -1000, 1085, -1000, 1197, 157, - 300, 1260, 886, 886, 886, 886, 573, -1000, -1000, -1000, - 535, 535, 240, 258, 4145, -1000, -1000, -1000, 24634, 1230, - 886, -1000, 1227, -1000, 1462, 305, 507, 507, 886, -1000, - -1000, 27335, 886, 1456, 1453, 27335, 27335, -1000, 24185, -1000, - 23736, 23287, 846, 27335, 22838, 22389, 21940, 21491, 21042, -1000, - 1303, -1000, 1194, -1000, -1000, -1000, 27335, 27335, 27335, 22, - -1000, -1000, 27335, 886, -1000, -1000, 819, 818, 535, 535, - 803, 948, 938, 937, 535, 535, 790, 933, 924, 178, - 788, 782, 781, 926, 932, 111, 917, 842, 780, 27335, - 1225, -1000, 152, 541, 198, 237, 203, 27335, 177, 1436, - 1409, 1160, 310, 295, 1299, 27335, 1481, 886, -1000, 7491, - -1000, -1000, 928, 12485, -1000, 630, 618, 618, -1000, -1000, - -1000, -1000, -1000, -1000, 638, 27335, 630, -1000, -1000, -1000, - 618, 638, 27335, 638, 638, 638, 638, 618, 638, 27335, - 27335, 27335, 27335, 27335, 27335, 27335, 27335, 27335, 7028, 7028, - 7028, 499, -1000, 1295, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 94, -1000, -1000, -1000, -1000, -1000, 1580, -1000, -1000, - -1000, -108, 1159, 20593, -1000, -283, -284, -285, -286, -1000, - -1000, -1000, -287, -293, -1000, -1000, -1000, 12485, 12485, 12485, - 12485, 694, 501, 13832, 841, 622, 13832, 13832, 13832, 13832, - 13832, 13832, 13832, 13832, 13832, 13832, 13832, 13832, 13832, 13832, - 13832, 681, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 886, -1000, 1576, 967, 967, 469, 469, 469, 469, 469, - 469, 469, 469, 469, 14281, 9329, 7491, 1069, 1082, 1523, - 10676, 10676, 12485, 12485, 11574, 11125, 10676, 1430, 568, 766, - 27335, -1000, -1000, 13383, -1000, -1000, -1000, -1000, -1000, 954, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 27335, 27335, 10676, - 10676, 10676, 10676, 10676, -1000, 1155, -1000, -165, 16090, 12485, - 1506, 1069, 1408, 1470, 1570, 492, 867, 1154, -1000, 776, - 1506, 17899, 1136, -1000, 1408, -1000, -1000, -1000, 27335, -1000, - -1000, 20144, -1000, -1000, 6565, 27335, 212, 27335, -1000, 1166, - 1277, -1000, -1000, -1000, 1488, 17450, 27335, 1151, 1149, -1000, - -1000, 446, 7954, -28, -1000, 7954, 1139, -1000, -62, -38, - 9778, 422, -1000, -1000, -1000, 2362, 14730, 1009, -1000, 23, - -1000, -1000, -1000, 1197, -1000, 1197, 1197, 1197, 1197, 22, - 22, 22, 22, -1000, -1000, -1000, -1000, -1000, 1222, 1221, - -1000, 1197, 1197, 1197, 1197, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 1487, 1080, 27092, -1000, + -1000, 3407, 937, -1000, 1243, -1000, 1077, -1000, 1210, 118, + 359, 1294, 937, 937, 937, 359, -1000, -1000, -1000, 576, + 576, 273, 267, 3426, -1000, -1000, -1000, 24391, 1241, 937, + -1000, 1237, -1000, 1507, 354, 532, 532, 937, -1000, -1000, + 27092, 937, 1505, 1504, 27092, 27092, -1000, 23942, -1000, 23493, + 23044, 857, 27092, 22595, 22146, 21697, 21248, 20799, -1000, 1315, + -1000, 1148, -1000, -1000, -1000, 27092, 27092, 27092, 4, -1000, + -1000, 27092, 937, -1000, -1000, 818, 816, 576, 576, 808, + 975, 972, 971, 576, 576, 807, 968, 955, 160, 787, + 785, 784, 976, 966, 119, 847, 819, 780, 27092, 1236, + -1000, 107, 589, 195, 214, 164, 27092, 171, 1495, 1455, + 1182, 376, 341, 1334, 27092, 1538, 341, -1000, 7248, -1000, + -1000, 962, 12242, -1000, 659, 641, 641, -1000, -1000, -1000, + -1000, -1000, -1000, 645, 27092, 659, -1000, -1000, -1000, 641, + 645, 27092, 645, 645, 645, 645, 641, 645, 27092, 27092, + 27092, 27092, 27092, 27092, 27092, 27092, 27092, 6785, 6785, 6785, + 535, -1000, 1332, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 78, -1000, -1000, -1000, -1000, -1000, 1618, -1000, -1000, -1000, + -101, 1173, 20350, -1000, -282, -288, -289, -290, -1000, -1000, + -1000, -291, -293, -1000, -1000, -1000, 12242, 12242, 12242, 12242, + 772, 537, 13589, 810, 551, 13589, 13589, 13589, 13589, 13589, + 13589, 13589, 13589, 13589, 13589, 13589, 13589, 13589, 13589, 13589, + 663, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 937, + -1000, 1616, 1023, 1023, 496, 496, 496, 496, 496, 496, + 496, 496, 496, 14038, 9086, 7248, 1059, 1069, 1586, 10433, + 10433, 12242, 12242, 11331, 10882, 10433, 1485, 621, 776, 27092, + -1000, -1000, 13140, -1000, -1000, -1000, -1000, -1000, 983, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 27092, 27092, 10433, 10433, + 10433, 10433, 10433, -1000, 1154, -1000, -171, 15847, 12242, 1557, + 1059, 1701, 1518, 1611, 517, 738, 1153, -1000, 830, 1557, + 17656, 1186, -1000, 1701, -1000, -1000, -1000, 27092, -1000, -1000, + 19901, -1000, -1000, 6322, 27092, 221, 27092, -1000, 1171, 1402, + -1000, -1000, -1000, 1543, 17207, 27092, 1141, 1135, -1000, -1000, + 464, 7711, -64, -1000, 7711, 1126, -1000, -58, -46, 9535, + 494, -1000, -1000, -1000, 2411, 14487, 1056, -1000, 16, -1000, + -1000, -1000, 1210, -1000, 1210, 1210, 1210, 1210, 4, 4, + 4, 4, -1000, -1000, -1000, -1000, -1000, 1233, 1231, -1000, + 1210, 1210, 1210, 1210, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1219, 1219, 1219, 1200, 1200, 270, -1000, 12485, - 158, 27335, 1482, 763, 152, 27335, 1288, -1000, 27335, 1260, - 1260, 1260, -1000, 1479, 895, 875, -1000, 1153, -1000, -1000, - 1516, -1000, -1000, 552, 609, 608, 475, 27335, 127, 210, - -1000, 262, -1000, 27335, 1209, 1446, 507, 886, -1000, 886, - -1000, -1000, -1000, -1000, 441, -1000, -1000, 886, 1152, -1000, - 1186, 679, 594, 620, 592, 1152, -1000, -1000, -153, 1152, - -1000, 1152, -1000, 1152, -1000, 1152, -1000, 1152, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 544, 27335, 127, 681, - -1000, 306, -1000, -1000, 681, 681, -1000, -1000, -1000, -1000, - 925, 902, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1230, 1230, 1230, 1223, 1223, 311, -1000, 12242, 143, + 27092, 1528, 777, 107, 27092, 640, 1331, -1000, 27092, 1294, + 1294, 1294, 937, 929, 924, -1000, 1151, -1000, -1000, 1580, + -1000, -1000, 531, 664, 662, 528, 27092, 93, 206, -1000, + 302, -1000, 27092, 1229, 1503, 532, 937, -1000, 937, -1000, + -1000, -1000, -1000, 463, -1000, -1000, 937, 1149, -1000, 1150, + 721, 658, 715, 654, 1149, -1000, -1000, -116, 1149, -1000, + 1149, -1000, 1149, -1000, 1149, -1000, 1149, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 569, 27092, 93, 663, -1000, + 373, -1000, -1000, 663, 663, -1000, -1000, -1000, -1000, 959, + 956, -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, -328, 27335, - 340, 132, 149, 27335, 27335, 27335, 27335, 27335, 402, -1000, - -1000, -1000, 183, 27335, 27335, 27335, 27335, 425, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 766, 27335, -1000, -1000, 638, - 638, -1000, -1000, 27335, 638, -1000, -1000, -1000, -1000, -1000, - -1000, 638, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 897, 27335, 27335, -1000, - -1000, -1000, -1000, -1000, 92, -68, 162, -1000, -1000, -1000, - -1000, 1502, -1000, 766, 501, 663, 571, -1000, -1000, 722, - -1000, -1000, 2124, -1000, -1000, -1000, -1000, 841, 13832, 13832, - 13832, 864, 2124, 2759, 966, 991, 469, 526, 526, 530, - 530, 530, 530, 530, 644, 644, -1000, -1000, -1000, -1000, - 954, -1000, -1000, -1000, 954, 10676, 10676, 1150, 1170, 439, - -1000, 1224, -1000, -1000, 1506, 1053, 1053, 688, 910, 605, - 1539, 1053, 566, 1534, 1053, 1053, 10676, -1000, -1000, 562, - -1000, 12485, 954, -1000, 1748, 1146, 1140, 1053, 954, 954, - 1053, 1053, 27335, -1000, -276, -1000, -81, 451, 1170, -1000, - 19695, -1000, -1000, 954, 1119, 1439, -1000, -1000, 1399, -1000, - 1334, 12485, 12485, 12485, -1000, -1000, -1000, 1439, 1503, -1000, - 1347, 1346, 1531, 10676, 19246, 1408, -1000, -1000, -1000, 434, - 1531, 1196, 1170, -1000, 27335, 19246, 19246, 19246, 19246, 19246, - -1000, 1314, 1311, -1000, 1320, 1313, 1333, 27335, -1000, 1077, - 1069, 17450, 212, 1133, 19246, 27335, -1000, -1000, 19246, 27335, - 6102, -1000, 1139, -28, -57, -1000, -1000, -1000, -1000, 766, - -1000, 814, -1000, 290, -1000, 283, -1000, -1000, -1000, -1000, - 453, 14, -1000, -1000, 22, 22, -1000, -1000, 422, 549, - 422, 422, 422, 896, 896, -1000, -1000, -1000, -1000, -1000, - 743, -1000, -1000, -1000, 741, -1000, -1000, 821, 1292, 158, - -1000, -1000, 535, 890, 1411, -1000, -1000, 994, 312, -1000, - 27335, -1000, 1287, 1284, 1280, -1000, -1000, -1000, -1000, -1000, - 3912, 27335, 1064, -1000, 125, 27335, 988, 27335, -1000, 1061, - 27335, -1000, 886, -1000, -1000, 7491, -1000, 27335, 1170, -1000, - -1000, -1000, -1000, 383, 1434, 1433, 127, 125, 422, 886, - -1000, -1000, -1000, -1000, -1000, -331, 1059, 27335, 156, -1000, - 1201, 929, -1000, 1245, -1000, -1000, -1000, -1000, 112, 195, - 179, 304, -1000, 378, 1292, 27335, -1000, -1000, -1000, 618, - -1000, -1000, 618, -1000, -1000, -1000, -1000, -1000, -1000, 1428, - -72, -305, -1000, -302, -1000, -1000, -1000, -1000, 864, 2124, - 2634, -1000, 13832, 13832, -1000, -1000, 1053, 1053, 10676, 7491, - 1523, 1439, -1000, -1000, 294, 681, 294, 13832, 13832, -1000, - 13832, 13832, -1000, -115, 1057, 527, -1000, 12485, 817, -1000, - -1000, 13832, 13832, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 349, 348, 347, 27335, -1000, -1000, -1000, 768, - 885, 1330, 766, 766, -1000, -1000, 27335, -1000, -1000, -1000, - -1000, 1529, 12485, -1000, 1137, -1000, 5639, 1506, 1279, 27335, - 1170, 1580, 15641, 27335, 1157, -1000, 540, 1277, 1275, 1272, - 1262, -1000, -1000, -1000, -1000, 1310, -1000, 1302, -1000, -1000, - -1000, -1000, -1000, 1069, 1531, 19246, 1124, -1000, 1124, -1000, - 430, -1000, -1000, -1000, -77, -60, -1000, -1000, -1000, 2362, - -1000, -1000, -1000, 632, 13832, 1566, -1000, 880, 1445, -1000, - 1444, -1000, -1000, 422, 422, -1000, -1000, -1000, -1000, -1000, - -1000, 1035, -1000, 1033, 1132, 1031, 56, -1000, 1240, 1426, - 535, 535, -1000, 716, -1000, 886, -1000, 27335, -1000, 27335, - 27335, 27335, 1515, 1130, -1000, 27335, -1000, -1000, 27335, -1000, - -1000, 1340, 158, 1012, -1000, -1000, -1000, 210, 27335, -1000, - 967, 125, -1000, -1000, -1000, -1000, -1000, -1000, 1178, -1000, - -1000, -1000, 970, -1000, -154, 886, 27335, 27335, 27335, -1000, - 27335, -1000, -1000, -1000, 638, 638, -1000, 1425, -1000, 886, - -1000, 13832, 2124, 2124, -1000, -1000, 954, -1000, 1506, -1000, - 954, 1197, 1197, -1000, 1197, 1200, -1000, 1197, 85, 1197, - 80, 954, 954, 2578, 2473, 2302, 2104, 1170, -107, -1000, - 766, 12485, 2087, 708, 1170, 1170, 1170, 1000, 869, 22, - -1000, -1000, -1000, 1527, 1512, 766, -1000, -1000, -1000, 1466, - 1037, 1051, -1000, -1000, 10227, 1002, 1339, 427, 1000, 1523, - 27335, 12485, -1000, -1000, 12485, 1179, -1000, 12485, -1000, -1000, - -1000, 1523, 1523, 1124, -1000, -1000, 479, -1000, -1000, -1000, - -1000, -1000, 2124, -56, -1000, -1000, -1000, -1000, -1000, 22, - 865, 22, 666, -1000, 658, -1000, -1000, -214, -1000, -1000, - 1175, 1291, -1000, -1000, 1178, -1000, -1000, -1000, 27335, 27335, - -1000, -1000, 206, -1000, 249, 997, -1000, -172, -1000, -1000, - 1487, 27335, -1000, -1000, 7491, -1000, -1000, 1176, 1249, -1000, - -1000, -1000, -1000, -1000, -1000, 2124, -1000, 1439, -1000, -1000, - 256, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 13832, - 13832, 13832, 13832, 13832, 1506, 862, 766, 13832, 13832, 18797, - 27335, 27335, 16988, 22, 8, -1000, 12485, 12485, 1432, -1000, - 1170, -1000, 1198, 27335, 1170, 27335, -1000, 1506, -1000, 766, - 766, 27335, 766, 1506, -1000, -1000, 422, -1000, 422, 965, - 959, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1486, - 1130, -1000, 204, 27335, -1000, 210, -1000, -177, -180, 1148, - 984, 1129, -1000, 518, 27335, 27335, -1000, -1000, -1000, 1748, - 1748, 1748, 1748, 175, 954, -1000, 1748, 1748, 978, -1000, - 978, 978, 451, -266, -1000, 1405, 1400, 766, 1119, 1561, - -1000, 1170, 1580, 405, 1051, -1000, -1000, 964, -1000, -1000, - -1000, -1000, -1000, 1148, 1170, 1168, -1000, -1000, -1000, 180, - -1000, 7491, 5176, 962, -1000, -1000, -1000, -1000, -1000, 954, - 159, -163, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 8, - 297, -1000, 1374, 1357, 1511, 27335, 1051, 27335, -1000, 180, - 12934, 27335, -1000, -58, -1000, -1000, -1000, -1000, -1000, 1245, - -1000, 1326, -143, -168, 1381, 1388, 1388, 1400, 1510, 1398, - 1393, -1000, 860, 870, -1000, -1000, 1748, 954, 958, 268, - -1000, -1000, -154, -1000, 1325, -1000, 1376, 727, -1000, -1000, - -1000, -1000, 857, -1000, 1509, 1508, -1000, -1000, -1000, 1264, - 154, -1000, -157, -1000, 725, -1000, -1000, -1000, 853, 680, - 1202, -1000, 1552, -1000, -164, -1000, -1000, -1000, -1000, -1000, - 1560, 438, 438, -170, -1000, -1000, -1000, 263, 756, -1000, - -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -329, 27092, 383, + 97, 152, 27092, 27092, 27092, 27092, 27092, 430, -1000, -1000, + -1000, 161, 27092, 27092, 27092, 27092, 403, -1000, -1000, 937, + -1000, -1000, -1000, -1000, 776, 27092, -1000, -1000, 645, 645, + -1000, -1000, 27092, 645, -1000, -1000, -1000, -1000, -1000, -1000, + 645, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 954, 27092, 27092, -1000, -1000, + -1000, -1000, -1000, 76, -31, 177, -1000, -1000, -1000, -1000, + 1551, -1000, 776, 537, 729, 564, -1000, -1000, 842, -1000, + -1000, 2845, -1000, -1000, -1000, -1000, 810, 13589, 13589, 13589, + 1196, 2845, 2903, 1549, 1680, 496, 656, 656, 503, 503, + 503, 503, 503, 646, 646, -1000, -1000, -1000, -1000, 983, + -1000, -1000, -1000, 983, 10433, 10433, 1143, 1191, 462, -1000, + 1228, -1000, -1000, 1557, 1046, 1046, 727, 911, 626, 1598, + 1046, 615, 1597, 1046, 1046, 10433, -1000, -1000, 618, -1000, + 12242, 983, -1000, 1220, 1142, 1128, 1046, 983, 983, 1046, + 1046, 27092, -1000, -277, -1000, -75, 484, 1191, -1000, 19452, + -1000, -1000, 983, 1108, 1494, -1000, -1000, 1445, -1000, 1389, + 12242, 12242, 12242, -1000, -1000, -1000, 1494, 1564, -1000, 1405, + 1404, 1592, 10433, 19003, 1701, -1000, -1000, -1000, 455, 1592, + 1140, 1191, -1000, 27092, 19003, 19003, 19003, 19003, 19003, -1000, + 1368, 1367, -1000, 1381, 1380, 1345, 27092, -1000, 1062, 1059, + 17207, 221, 1067, 19003, 27092, -1000, -1000, 19003, 27092, 5859, + -1000, 1126, -64, -40, -1000, -1000, -1000, -1000, 776, -1000, + 917, -1000, 2509, -1000, 329, -1000, -1000, -1000, -1000, 500, + 13, -1000, -1000, 4, 4, -1000, -1000, 494, 581, 494, + 494, 494, 947, 947, -1000, -1000, -1000, -1000, -1000, 769, + -1000, -1000, -1000, 755, -1000, -1000, 717, 1269, 143, -1000, + -1000, 576, 942, 1466, -1000, -1000, 1052, 381, -1000, 1531, + 27092, -1000, 1330, 1323, 1322, -1000, -1000, -1000, -1000, -1000, + 291, 27092, 1055, -1000, 88, 27092, 1037, 27092, -1000, 1051, + 27092, -1000, 937, -1000, -1000, 7248, -1000, 27092, 1191, -1000, + -1000, -1000, -1000, 408, 1493, 1489, 93, 88, 494, 937, + -1000, -1000, -1000, -1000, -1000, -332, 1049, 27092, 105, -1000, + 1224, 914, -1000, 1290, -1000, -1000, -1000, -1000, 98, 180, + 145, 372, -1000, 387, 1269, 27092, -1000, -1000, -1000, -1000, + 641, -1000, -1000, 641, -1000, -1000, -1000, -1000, -1000, -1000, + 1484, -36, -307, -1000, -303, -1000, -1000, -1000, -1000, 1196, + 2845, 839, -1000, 13589, 13589, -1000, -1000, 1046, 1046, 10433, + 7248, 1586, 1494, -1000, -1000, 377, 663, 377, 13589, 13589, + -1000, 13589, 13589, -1000, -106, 1106, 580, -1000, 12242, 753, + -1000, -1000, 13589, 13589, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 398, 394, 389, 27092, -1000, -1000, -1000, + 940, 941, 1375, 776, 776, -1000, -1000, 27092, -1000, -1000, + -1000, -1000, 1590, 12242, -1000, 1124, -1000, 5396, 1557, 1321, + 27092, 1191, 1618, 15398, 27092, 1103, -1000, 582, 1402, 1288, + 1319, 1372, -1000, -1000, -1000, -1000, 1364, -1000, 1349, -1000, + -1000, -1000, -1000, -1000, 1059, 1592, 19003, 1094, -1000, 1094, + -1000, 453, -1000, -1000, -1000, -51, -59, -1000, -1000, -1000, + 2411, -1000, -1000, -1000, 667, 13589, 1610, -1000, 923, 1502, + -1000, 1501, -1000, -1000, 494, 494, -1000, -1000, -1000, -1000, + -1000, -1000, 1044, -1000, 1042, 1122, 1021, 65, -1000, 1145, + 1483, 576, 576, -1000, 754, -1000, 937, -1000, 27092, -1000, + -1000, 27092, 27092, 27092, 1578, 1121, -1000, 27092, -1000, -1000, + 27092, -1000, -1000, 1403, 143, 1018, -1000, -1000, -1000, 206, + 27092, -1000, 1023, 88, -1000, -1000, -1000, -1000, -1000, -1000, + 1207, -1000, -1000, -1000, 1026, -1000, -117, 937, 27092, 27092, + 27092, -1000, 27092, -1000, -1000, -1000, 645, 645, -1000, 1477, + -1000, 937, -1000, 13589, 2845, 2845, -1000, -1000, 983, -1000, + 1557, -1000, 983, 1210, 1210, -1000, 1210, 1223, -1000, 1210, + 64, 1210, 62, 983, 983, 2804, 2784, 2708, 2573, 1191, + -100, -1000, 776, 12242, 2299, 1285, 1191, 1191, 1191, 1011, + 896, 4, -1000, -1000, -1000, 1588, 1576, 776, -1000, -1000, + -1000, 1515, 1084, 1107, -1000, -1000, 9984, 1016, 1401, 452, + 1011, 1586, 27092, 12242, -1000, -1000, 12242, 1208, -1000, 12242, + -1000, -1000, -1000, 1586, 1586, 1094, -1000, -1000, 509, -1000, + -1000, -1000, -1000, -1000, 2845, -72, -1000, -1000, -1000, -1000, + -1000, 4, 879, 4, 752, -1000, 730, -1000, -1000, -205, + -1000, -1000, 1134, 1312, -1000, -1000, 1207, -1000, -1000, -1000, + 27092, 27092, -1000, -1000, 201, -1000, 290, 1005, -1000, -159, + -1000, -1000, 1542, 27092, -1000, -1000, 7248, -1000, -1000, 1197, + 1291, -1000, -1000, -1000, -1000, -1000, -1000, 2845, -1000, 1494, + -1000, -1000, 274, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 13589, 13589, 13589, 13589, 13589, 1557, 873, 776, 13589, + 13589, 18554, 27092, 27092, 16745, 4, -7, -1000, 12242, 12242, + 1499, -1000, 1191, -1000, 1166, 27092, 1191, 27092, -1000, 1557, + -1000, 776, 776, 27092, 776, 1557, -1000, -1000, 494, -1000, + 494, 1013, 993, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1540, 1121, -1000, 165, 27092, -1000, 206, -1000, -166, + -167, 1190, 1000, 1110, -1000, 557, 27092, 27092, -1000, -1000, + -1000, 1220, 1220, 1220, 1220, 277, 983, -1000, 1220, 1220, + 998, -1000, 998, 998, 484, -256, -1000, 1450, 1446, 776, + 1108, 1607, -1000, 1191, 1618, 447, 1107, -1000, -1000, 996, + -1000, -1000, -1000, -1000, -1000, 1190, 1191, 1167, -1000, -1000, + -1000, 213, -1000, 7248, 4933, 991, -1000, -1000, -1000, -1000, + -1000, 983, 159, -123, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -7, 263, -1000, 1409, 1407, 1573, 27092, 1107, 27092, + -1000, 213, 12691, 27092, -1000, -53, -1000, -1000, -1000, -1000, + -1000, 1290, -1000, 1374, -113, -156, 1406, 1433, 1433, 1446, + 1570, 1443, 1440, -1000, 872, 1085, -1000, -1000, 1220, 983, + 987, 308, -1000, -1000, -117, -1000, 1326, -1000, 1412, 756, + -1000, -1000, -1000, -1000, 863, -1000, 1565, 1560, -1000, -1000, + -1000, 1316, 106, -1000, -120, -1000, 739, -1000, -1000, -1000, + 862, 716, 1270, -1000, 1596, -1000, -154, -1000, -1000, -1000, + -1000, -1000, 1605, 476, 476, -169, -1000, -1000, -1000, 297, + 732, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1815, 1814, 26, 82, 87, 1813, 1812, 1811, 1810, - 133, 131, 130, 1809, 1808, 1807, 1805, 1804, 1803, 1799, - 1797, 1795, 1794, 1793, 1792, 74, 121, 37, 40, 125, - 1789, 1788, 52, 1786, 1785, 1784, 118, 117, 461, 1783, - 116, 1782, 1781, 1779, 1777, 1775, 1773, 1772, 1771, 1769, - 1768, 1767, 1766, 1765, 180, 1763, 1762, 7, 1761, 55, - 1760, 1759, 1755, 1754, 1753, 89, 1752, 1751, 1750, 112, - 1749, 1747, 49, 347, 47, 73, 1745, 1738, 75, 831, - 1737, 91, 119, 1736, 1976, 1735, 41, 76, 79, 1734, - 43, 1731, 1727, 106, 1726, 1725, 1722, 71, 1721, 1720, - 3267, 1719, 68, 80, 17, 31, 1718, 1716, 1715, 1713, - 36, 660, 1711, 1710, 20, 1709, 1705, 134, 1704, 88, - 18, 1703, 14, 12, 19, 1702, 86, 1701, 8, 62, - 44, 1700, 84, 1699, 1695, 1693, 1692, 33, 1691, 77, - 101, 30, 1690, 1689, 5, 13, 1688, 1687, 1686, 1685, - 1682, 1681, 3, 1678, 1676, 1674, 35, 1673, 6, 22, - 72, 46, 24, 9, 1672, 124, 1671, 23, 123, 65, - 109, 1670, 1669, 1668, 939, 50, 138, 1667, 1665, 60, - 1664, 115, 126, 1663, 1436, 1662, 1661, 63, 1261, 2691, - 15, 120, 1658, 1657, 2099, 57, 78, 21, 1656, 1655, - 1654, 128, 113, 64, 850, 45, 1653, 1652, 1651, 1648, - 1647, 1646, 1644, 39, 28, 16, 108, 32, 1625, 1623, - 1622, 58, 38, 1621, 103, 102, 70, 96, 1620, 114, - 92, 67, 1619, 42, 1618, 1617, 1616, 1614, 85, 1613, - 1612, 1611, 1610, 104, 97, 56, 29, 1609, 34, 99, - 107, 100, 1607, 25, 122, 11, 1605, 10, 0, 1604, - 4, 132, 1440, 111, 1603, 1602, 1, 1598, 2, 1597, - 1596, 81, 1594, 1592, 1591, 1590, 2649, 508, 110, 1589, - 127, + 0, 1935, 1934, 12, 80, 79, 1933, 1932, 1931, 1930, + 133, 132, 131, 1928, 1927, 1925, 1924, 1923, 1922, 1920, + 1918, 1916, 1915, 1914, 1913, 47, 116, 35, 37, 121, + 1912, 1911, 43, 1910, 1909, 1908, 122, 120, 473, 1890, + 118, 1889, 1888, 1887, 1885, 1884, 1883, 1882, 1879, 1878, + 1876, 1875, 1874, 1872, 129, 1871, 1869, 7, 1868, 46, + 1867, 1866, 1865, 1864, 1863, 85, 1862, 1860, 1859, 110, + 1858, 1857, 44, 305, 50, 75, 1855, 1854, 72, 851, + 1853, 102, 119, 1850, 440, 1847, 41, 66, 70, 1836, + 36, 1833, 1832, 114, 1831, 1830, 1829, 71, 1828, 1825, + 2718, 1824, 65, 78, 15, 32, 1822, 1807, 1806, 1805, + 33, 403, 1798, 1793, 24, 1789, 1787, 130, 1786, 84, + 18, 1785, 16, 19, 17, 1783, 87, 1781, 38, 60, + 27, 1779, 82, 1775, 1774, 1770, 1764, 40, 1760, 74, + 103, 58, 1757, 1756, 4, 9, 1755, 1754, 1753, 1750, + 1749, 1748, 5, 1746, 1745, 1744, 28, 1743, 11, 23, + 68, 148, 26, 8, 1742, 124, 1740, 25, 126, 67, + 108, 1739, 1737, 1736, 957, 45, 138, 1735, 1734, 92, + 1733, 115, 112, 1732, 1470, 1731, 1727, 56, 1089, 2268, + 10, 109, 1726, 1720, 1715, 49, 77, 21, 1719, 1717, + 1714, 128, 113, 63, 944, 39, 1713, 1709, 1706, 1705, + 1703, 1699, 1678, 125, 34, 20, 97, 30, 1677, 1675, + 1674, 57, 62, 1673, 105, 99, 64, 96, 1672, 111, + 101, 55, 1669, 42, 1666, 1664, 1662, 1660, 76, 1659, + 1658, 1656, 1655, 106, 88, 52, 31, 1654, 29, 91, + 86, 89, 1648, 22, 117, 14, 1647, 3, 0, 1645, + 6, 143, 1474, 104, 1643, 1641, 1, 1640, 2, 1639, + 1634, 81, 1632, 1631, 1630, 1629, 2834, 222, 107, 1624, + 123, } var yyR1 = [...]int{ @@ -4370,7 +4345,7 @@ var yyR2 = [...]int{ 4, 3, 5, 4, 1, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 6, 11, 2, 0, 2, 0, 2, 1, 0, 2, 1, 3, 3, - 5, 3, 6, 7, 7, 7, 4, 2, 1, 1, + 5, 3, 6, 7, 7, 7, 5, 2, 1, 1, 4, 0, 1, 1, 1, 2, 2, 0, 1, 4, 4, 4, 4, 2, 4, 1, 3, 1, 1, 3, 4, 3, 3, 3, 3, 0, 2, 3, 3, 4, @@ -4401,7 +4376,7 @@ var yyR2 = [...]int{ 9, 5, 3, 7, 4, 4, 4, 4, 3, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 2, 2, 1, 3, 8, 8, - 3, 3, 5, 6, 6, 5, 4, 3, 2, 3, + 3, 3, 5, 6, 6, 5, 5, 3, 2, 3, 3, 3, 7, 3, 3, 3, 3, 4, 7, 5, 2, 4, 4, 4, 4, 4, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, @@ -4576,152 +4551,152 @@ var yyChk = [...]int{ 169, 33, 10, 71, 74, 325, 326, 327, 54, 341, 114, 13, 371, 312, 108, 306, 254, -235, 126, -222, -226, -189, 179, -251, 175, -100, -244, -243, -189, -79, - 163, -258, 164, 164, 164, -182, 168, 328, -36, -37, - -165, 143, 196, 82, 82, -226, -225, -224, -263, 198, - 179, -250, -242, 171, 180, -232, 172, 173, -227, 164, - 29, -263, -227, 170, 180, 198, 198, 106, 198, 106, - 198, 198, 198, 198, 198, 198, 198, 198, 198, 195, - -233, 118, -233, 345, 345, -238, -263, -263, -263, 166, - 34, 34, -186, -227, 166, 23, -233, -233, -165, 143, - -233, -233, -233, -233, 206, 206, -233, -233, -233, -233, + 163, -258, 164, 164, 164, -54, 328, -36, -37, -165, + 143, 196, 82, 82, -226, -225, -224, -263, 198, 179, + -250, -242, 171, 180, -232, 172, 173, -227, 164, 29, + -263, -227, 170, 180, 198, 198, 106, 198, 106, 198, + 198, 198, 198, 198, 198, 198, 198, 198, 195, -233, + 118, -233, 345, 345, -238, -263, -263, -263, 166, 34, + 34, -186, -227, 166, 23, -233, -233, -165, 143, -233, + -233, -233, -233, 206, 206, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, -233, - -233, -100, -82, 213, 153, 155, 158, 73, 118, -38, - 208, -22, -100, 163, -258, -181, 168, -181, -100, 150, - -100, -179, 126, 13, -179, -176, 284, 288, 289, 290, - -179, -179, -179, -179, 209, 298, -228, 164, 34, 176, - 284, 209, 298, 209, 210, 209, 210, 209, -175, 12, - 128, 319, 303, 300, 202, 163, 203, 165, 304, -258, - 435, 210, 284, 205, -179, -202, -276, -190, -202, -202, - 31, 166, -189, -56, -189, 88, -7, -3, -11, -10, - -12, 118, -77, 284, -65, 144, 450, 436, 437, 438, - 435, 299, 443, 441, 439, 209, 440, 82, 109, 107, - 108, 125, -84, -108, 128, 110, 126, 127, 112, 130, - 129, 140, 133, 134, 135, 136, 137, 138, 139, 131, - 132, 143, 118, 119, 120, 121, 122, 123, 124, -173, - -276, -126, -276, 151, 152, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -111, -276, 150, -2, -120, -4, - -276, -276, -276, -276, -276, -276, -276, -276, -133, -84, - -276, -280, -117, -276, -280, -117, -280, -117, -280, -276, - -280, -117, -280, -117, -280, -280, -117, -276, -276, -276, - -276, -276, -276, -276, -201, -270, -271, -103, -100, -276, - -137, -3, -54, -156, 20, 32, -84, -138, -139, -84, - -137, 56, -73, -75, -78, 60, 61, 94, 12, -192, - -191, 23, -189, 88, 150, 12, -101, 27, -100, -86, - -87, -88, -89, -103, -127, -276, 12, -93, -94, -100, - -102, -194, 82, 228, -168, -204, -170, -169, 309, 311, - 118, -193, -189, 88, 30, 83, 82, -100, -206, -209, - -211, -210, -212, -207, -208, 251, 252, 144, 255, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 31, - 187, 247, 248, 249, 250, 267, 268, 269, 270, 271, - 272, 273, 274, 234, 253, 339, 235, 236, 237, 238, - 239, 240, 242, 243, 244, 245, 246, -261, -258, 81, - 83, 82, -213, 81, -82, -182, -249, -246, 74, -258, - -258, -258, -258, 110, -233, -233, 195, -29, -26, -254, - 16, -25, -26, 158, 102, 103, 155, 81, -222, 81, - -231, -261, -258, 81, 29, 170, 169, -230, -227, -230, - -231, -258, -128, -189, -194, -258, 29, 29, -161, -189, - -161, -161, 21, -161, 21, -161, 21, 89, -189, -161, - 21, -161, 21, -161, 21, -161, 21, -161, 21, 30, - 75, 76, 30, 78, 79, 80, -128, -128, -222, -165, - -100, -258, 89, 89, -233, -233, 89, 88, 88, 88, - -233, -233, 89, 88, -258, 88, -264, 181, 223, 225, - 89, 89, 89, 89, 30, 88, -265, 30, 457, 456, - 458, 459, 460, 89, 30, 89, 30, 89, -189, 81, - -81, 215, 118, 204, 204, 163, 163, 217, -100, 216, - 218, 220, 41, 82, 166, -181, 73, -95, -100, 24, - -258, -195, -194, -187, 88, -84, -229, 12, 128, -175, - -175, -179, -100, -229, -175, -179, -100, -179, -179, -179, - -179, -175, -179, -194, -194, -100, -100, -100, -100, -100, - -100, -100, -202, -202, -202, -180, 126, 73, -200, 231, - 265, 429, 430, 431, 82, 341, -93, 435, 435, 435, - 435, 435, 435, -84, -84, -84, -84, -118, 98, 110, - 99, 100, -111, -119, -123, -126, 93, 128, 126, 127, - 112, -111, -111, -111, -111, -111, -111, -111, -111, -111, - -111, -111, -111, -111, -111, -111, -203, -258, 88, 144, - -258, -110, -110, -189, -74, 22, 37, -73, -190, -195, - -187, -69, -277, -277, -137, -73, -73, -84, -84, -128, - 88, -73, -128, 88, -73, -73, -68, 22, 37, -131, - -132, 114, -128, -277, -111, -189, -189, -73, -74, -74, - -73, -73, 82, -272, 311, 312, 433, -197, 198, -196, - 23, -194, 88, -121, -120, -141, -277, -142, 27, 10, - 128, 82, 19, 82, -140, 25, 26, -141, -112, -189, - 89, 92, -85, 82, 12, -78, -100, -191, 135, -195, - -100, -160, 198, -100, 31, 82, -96, -98, -97, -99, - 63, 67, 69, 64, 65, 66, 70, -198, 23, -86, - -3, -276, -100, -93, -278, 82, 12, 74, -278, 82, - 150, -168, -170, 82, 310, 312, 313, 73, 101, -84, - -215, 143, -240, -239, -238, -222, -224, -225, -226, 83, - -143, -218, 279, -213, -213, -213, -213, -213, -214, -165, - -214, -214, -214, 81, 81, -213, -213, -213, -213, -216, - 81, -216, -216, -217, 81, -217, -251, -84, -248, -247, - -245, -246, 174, 95, 341, -243, -140, 89, -81, -100, - 73, -189, -249, -249, -249, 24, -258, 88, -258, 88, + -100, -82, 213, 153, 155, 158, 73, 118, -38, 208, + -22, -100, 163, -258, -181, 168, -54, -100, 150, -100, + -179, 126, 13, -179, -176, 284, 288, 289, 290, -179, + -179, -179, -179, 209, 298, -228, 164, 34, 176, 284, + 209, 298, 209, 210, 209, 210, 209, -175, 12, 128, + 319, 303, 300, 202, 163, 203, 165, 304, -258, 435, + 210, 284, 205, -179, -202, -276, -190, -202, -202, 31, + 166, -189, -56, -189, 88, -7, -3, -11, -10, -12, + 118, -77, 284, -65, 144, 450, 436, 437, 438, 435, + 299, 443, 441, 439, 209, 440, 82, 109, 107, 108, + 125, -84, -108, 128, 110, 126, 127, 112, 130, 129, + 140, 133, 134, 135, 136, 137, 138, 139, 131, 132, + 143, 118, 119, 120, 121, 122, 123, 124, -173, -276, + -126, -276, 151, 152, -111, -111, -111, -111, -111, -111, + -111, -111, -111, -111, -276, 150, -2, -120, -4, -276, + -276, -276, -276, -276, -276, -276, -276, -133, -84, -276, + -280, -117, -276, -280, -117, -280, -117, -280, -276, -280, + -117, -280, -117, -280, -280, -117, -276, -276, -276, -276, + -276, -276, -276, -201, -270, -271, -103, -100, -276, -137, + -3, -54, -156, 20, 32, -84, -138, -139, -84, -137, + 56, -73, -75, -78, 60, 61, 94, 12, -192, -191, + 23, -189, 88, 150, 12, -101, 27, -100, -86, -87, + -88, -89, -103, -127, -276, 12, -93, -94, -100, -102, + -194, 82, 228, -168, -204, -170, -169, 309, 311, 118, + -193, -189, 88, 30, 83, 82, -100, -206, -209, -211, + -210, -212, -207, -208, 251, 252, 144, 255, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 31, 187, + 247, 248, 249, 250, 267, 268, 269, 270, 271, 272, + 273, 274, 234, 253, 339, 235, 236, 237, 238, 239, + 240, 242, 243, 244, 245, 246, -261, -258, 81, 83, + 82, -213, 81, -82, -182, 168, -249, -246, 74, -258, + -258, -258, -182, -233, -233, 195, -29, -26, -254, 16, + -25, -26, 158, 102, 103, 155, 81, -222, 81, -231, + -261, -258, 81, 29, 170, 169, -230, -227, -230, -231, + -258, -128, -189, -194, -258, 29, 29, -161, -189, -161, + -161, 21, -161, 21, -161, 21, 89, -189, -161, 21, + -161, 21, -161, 21, -161, 21, -161, 21, 30, 75, + 76, 30, 78, 79, 80, -128, -128, -222, -165, -100, + -258, 89, 89, -233, -233, 89, 88, 88, 88, -233, + -233, 89, 88, -258, 88, -264, 181, 223, 225, 89, + 89, 89, 89, 30, 88, -265, 30, 457, 456, 458, + 459, 460, 89, 30, 89, 30, 89, -189, 81, -81, + 215, 118, 204, 204, 163, 163, 217, -100, 216, 218, + 220, 41, 82, 166, -181, 73, -95, -100, 24, -181, + -195, -194, -187, 88, -84, -229, 12, 128, -175, -175, + -179, -100, -229, -175, -179, -100, -179, -179, -179, -179, + -175, -179, -194, -194, -100, -100, -100, -100, -100, -100, + -100, -202, -202, -202, -180, 126, 73, -200, 231, 265, + 429, 430, 431, 82, 341, -93, 435, 435, 435, 435, + 435, 435, -84, -84, -84, -84, -118, 98, 110, 99, + 100, -111, -119, -123, -126, 93, 128, 126, 127, 112, + -111, -111, -111, -111, -111, -111, -111, -111, -111, -111, + -111, -111, -111, -111, -111, -203, -258, 88, 144, -258, + -110, -110, -189, -74, 22, 37, -73, -190, -195, -187, + -69, -277, -277, -137, -73, -73, -84, -84, -128, 88, + -73, -128, 88, -73, -73, -68, 22, 37, -131, -132, + 114, -128, -277, -111, -189, -189, -73, -74, -74, -73, + -73, 82, -272, 311, 312, 433, -197, 198, -196, 23, + -194, 88, -121, -120, -141, -277, -142, 27, 10, 128, + 82, 19, 82, -140, 25, 26, -141, -112, -189, 89, + 92, -85, 82, 12, -78, -100, -191, 135, -195, -100, + -160, 198, -100, 31, 82, -96, -98, -97, -99, 63, + 67, 69, 64, 65, 66, 70, -198, 23, -86, -3, + -276, -100, -93, -278, 82, 12, 74, -278, 82, 150, + -168, -170, 82, 310, 312, 313, 73, 101, -84, -215, + 143, -240, -239, -238, -222, -224, -225, -226, 83, -143, + -218, 279, -213, -213, -213, -213, -213, -214, -165, -214, + -214, -214, 81, 81, -213, -213, -213, -213, -216, 81, + -216, -216, -217, 81, -217, -251, -84, -248, -247, -245, + -246, 174, 95, 341, -243, -140, 89, -81, -100, 110, + 73, -189, -249, -249, -249, -258, -258, 88, -258, 88, 82, 17, -223, -222, -129, 223, -253, 198, -250, -244, 81, 29, -230, -231, -231, 150, -258, 82, 27, 106, 106, 106, 106, 341, 155, 31, -222, -129, -203, 166, -203, -203, 88, 88, -178, 465, -93, 165, 222, -83, 324, 88, 84, -100, -100, -100, -100, -100, 158, 155, - 206, -100, -100, -93, -100, 82, -59, 183, 178, -100, - -179, -179, -100, -179, -179, 88, -100, -189, -65, 311, - 341, 20, -66, 20, 98, 99, 100, -119, -111, -111, - -111, -72, 188, 109, -277, -277, -73, -73, -276, 150, - -5, -141, -277, -277, 82, 74, 23, 12, 12, -277, - 12, 12, -277, -277, -73, -134, -132, 116, -84, -277, - -277, 82, 82, -277, -277, -277, -277, -277, -271, 432, - 312, -104, 71, 167, 72, -276, -196, -277, -156, 39, - 47, 58, -84, -84, -139, -156, -172, 20, 12, 54, - 54, -105, 13, -75, -86, -78, 150, -105, -109, 31, - 54, -3, -276, -276, -163, -167, -128, -87, -88, -88, - -87, -88, 63, 63, 63, 68, 63, 68, 63, -97, - -194, -277, -277, -3, -160, 74, -86, -100, -86, -102, - -194, 135, -169, -171, 314, 311, 317, -258, 88, 82, - -238, -226, 98, 110, 30, 73, 276, 95, 170, 29, - 169, -219, 280, -214, -214, -215, -258, 144, -215, -215, - -215, -221, 88, -221, 89, 89, 83, -32, -27, -28, - 32, 77, -245, -233, 88, 38, 83, 165, -100, 73, - 73, 73, 16, -158, -189, 82, 83, -130, 224, -128, - 83, -189, 83, -158, -231, -190, -189, -276, 163, 30, - 30, -129, -130, -215, -258, 467, 466, 83, -100, -80, - 213, 221, 81, 85, -260, 74, 204, 276, 204, 207, - 166, -59, -32, -100, -175, -175, 32, 311, 444, 442, - -72, 109, -111, -111, -277, -277, -74, -190, -137, -156, - -205, 144, 251, 187, 249, 245, 265, 256, 278, 247, - 279, -203, -205, -111, -111, -111, -111, 338, -137, 117, - -84, 115, -111, -111, 164, 164, 164, -161, 40, 88, - 88, 59, -100, -135, 14, -84, 135, -141, -162, 73, - -163, -122, -124, -123, -276, -157, -277, -189, -161, -105, - 82, 118, -91, -90, 73, 74, -92, 73, -90, 63, - 63, -277, -105, -86, -105, -105, 150, 311, 315, 316, - -238, 98, -111, 10, 88, 29, 29, -215, -215, 83, - 82, 83, 82, 83, 82, -183, 378, 110, -28, -27, - -233, -233, 89, -258, -100, -100, -100, -100, 17, 82, - -222, -128, 54, -248, 83, -252, -253, -100, -110, -130, - -159, 81, 83, -257, 341, -259, -258, -189, -189, -189, - -100, -179, -179, 32, -258, -111, -277, -141, -277, -213, - -213, -213, -217, -213, 239, -213, 239, -277, -277, 20, - 20, 20, 20, -276, -64, 334, -84, 82, 82, -276, - -276, -276, -277, 88, -214, -136, 15, 17, 28, -162, - 82, -277, -277, 82, 54, 150, -277, -137, -167, -84, - -84, 81, -84, -137, -105, -114, -214, 88, -214, 89, - 89, 378, 30, 78, 79, 80, 30, 75, 76, -159, - -158, -189, 200, 182, -277, 82, -220, 341, 344, 23, - -158, -256, -255, -190, 81, 74, -156, -214, -258, -111, - -111, -111, -111, -111, -141, 88, -111, -111, -158, -277, - -158, -158, -197, -214, -145, -150, -176, -84, -120, 29, - -124, 54, -3, -189, -122, -189, -141, -158, -141, -215, - -215, 83, 83, 23, 201, -100, -253, 345, 345, -3, - 83, 82, 118, -158, -100, -277, -277, -277, -277, -67, - 128, 341, -277, -277, -277, -277, -277, -277, -104, -148, - 428, -151, 43, -152, 44, 10, -122, 150, 83, -3, - -276, 81, -57, 341, -255, -237, -190, 88, 89, 83, - -277, 339, 70, 342, -145, 48, 257, -153, 52, -154, - -149, 53, 17, -163, -189, -57, -111, 197, -158, -58, - 212, 432, -260, 59, 340, 343, -146, 50, -144, 49, - -144, -152, 17, -155, 45, 46, 88, -277, -277, 83, - 175, -257, 59, -147, 51, 73, 101, 88, 17, 17, - -267, -268, 73, 214, 341, 73, 101, 88, 88, -268, - 73, 11, 10, 342, -266, 183, 178, 181, 31, -266, - 343, 177, 30, 98, + 206, -100, -100, -93, -100, 82, -59, 183, 178, -258, + -100, -179, -179, -100, -179, -179, 88, -100, -189, -65, + 311, 341, 20, -66, 20, 98, 99, 100, -119, -111, + -111, -111, -72, 188, 109, -277, -277, -73, -73, -276, + 150, -5, -141, -277, -277, 82, 74, 23, 12, 12, + -277, 12, 12, -277, -277, -73, -134, -132, 116, -84, + -277, -277, 82, 82, -277, -277, -277, -277, -277, -271, + 432, 312, -104, 71, 167, 72, -276, -196, -277, -156, + 39, 47, 58, -84, -84, -139, -156, -172, 20, 12, + 54, 54, -105, 13, -75, -86, -78, 150, -105, -109, + 31, 54, -3, -276, -276, -163, -167, -128, -87, -88, + -88, -87, -88, 63, 63, 63, 68, 63, 68, 63, + -97, -194, -277, -277, -3, -160, 74, -86, -100, -86, + -102, -194, 135, -169, -171, 314, 311, 317, -258, 88, + 82, -238, -226, 98, 110, 30, 73, 276, 95, 170, + 29, 169, -219, 280, -214, -214, -215, -258, 144, -215, + -215, -215, -221, 88, -221, 89, 89, 83, -32, -27, + -28, 32, 77, -245, -233, 88, 38, 83, 165, 24, + -100, 73, 73, 73, 16, -158, -189, 82, 83, -130, + 224, -128, 83, -189, 83, -158, -231, -190, -189, -276, + 163, 30, 30, -129, -130, -215, -258, 467, 466, 83, + -100, -80, 213, 221, 81, 85, -260, 74, 204, 276, + 204, 207, 166, -59, -32, -100, -175, -175, 32, 311, + 444, 442, -72, 109, -111, -111, -277, -277, -74, -190, + -137, -156, -205, 144, 251, 187, 249, 245, 265, 256, + 278, 247, 279, -203, -205, -111, -111, -111, -111, 338, + -137, 117, -84, 115, -111, -111, 164, 164, 164, -161, + 40, 88, 88, 59, -100, -135, 14, -84, 135, -141, + -162, 73, -163, -122, -124, -123, -276, -157, -277, -189, + -161, -105, 82, 118, -91, -90, 73, 74, -92, 73, + -90, 63, 63, -277, -105, -86, -105, -105, 150, 311, + 315, 316, -238, 98, -111, 10, 88, 29, 29, -215, + -215, 83, 82, 83, 82, 83, 82, -183, 378, 110, + -28, -27, -233, -233, 89, -258, -100, -100, -100, -100, + 17, 82, -222, -128, 54, -248, 83, -252, -253, -100, + -110, -130, -159, 81, 83, -257, 341, -259, -258, -189, + -189, -189, -100, -179, -179, 32, -258, -111, -277, -141, + -277, -213, -213, -213, -217, -213, 239, -213, 239, -277, + -277, 20, 20, 20, 20, -276, -64, 334, -84, 82, + 82, -276, -276, -276, -277, 88, -214, -136, 15, 17, + 28, -162, 82, -277, -277, 82, 54, 150, -277, -137, + -167, -84, -84, 81, -84, -137, -105, -114, -214, 88, + -214, 89, 89, 378, 30, 78, 79, 80, 30, 75, + 76, -159, -158, -189, 200, 182, -277, 82, -220, 341, + 344, 23, -158, -256, -255, -190, 81, 74, -156, -214, + -258, -111, -111, -111, -111, -111, -141, 88, -111, -111, + -158, -277, -158, -158, -197, -214, -145, -150, -176, -84, + -120, 29, -124, 54, -3, -189, -122, -189, -141, -158, + -141, -215, -215, 83, 83, 23, 201, -100, -253, 345, + 345, -3, 83, 82, 118, -158, -100, -277, -277, -277, + -277, -67, 128, 341, -277, -277, -277, -277, -277, -277, + -104, -148, 428, -151, 43, -152, 44, 10, -122, 150, + 83, -3, -276, 81, -57, 341, -255, -237, -190, 88, + 89, 83, -277, 339, 70, 342, -145, 48, 257, -153, + 52, -154, -149, 53, 17, -163, -189, -57, -111, 197, + -158, -58, 212, 432, -260, 59, 340, 343, -146, 50, + -144, 49, -144, -152, 17, -155, 45, 46, 88, -277, + -277, 83, 175, -257, 59, -147, 51, 73, 101, 88, + 17, 17, -267, -268, 73, 214, 341, 73, 101, 88, + 88, -268, 73, 11, 10, 342, -266, 183, 178, 181, + 31, -266, 343, 177, 30, 98, } var yyDef = [...]int{ @@ -4735,7 +4710,7 @@ var yyDef = [...]int{ 54, 55, 501, 502, 503, 1, 3, 0, 553, 820, 0, 0, -2, 551, 0, 0, 930, 930, 930, 0, 85, 86, 0, 0, 0, 836, 0, 0, 0, 0, - 0, 928, 0, 925, 108, 109, 89, -2, 113, 114, + 0, 549, 0, 925, 108, 109, 89, -2, 113, 114, 0, 118, 366, 327, 369, 325, 355, -2, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 222, 222, 0, 0, -2, 318, 318, 318, @@ -4743,7 +4718,7 @@ var yyDef = [...]int{ 222, 222, 222, 0, 0, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 222, 0, 107, 849, 0, 0, 117, 38, 34, 35, 36, - 0, 0, 0, 926, 926, 0, 418, 634, 945, 946, + 0, 0, 0, 926, 549, 0, 418, 634, 945, 946, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, @@ -4802,152 +4777,152 @@ var yyDef = [...]int{ 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, -2, 1104, 0, 0, 127, 128, 0, 37, 248, 0, 123, 0, 242, 196, 849, - 928, 938, 0, 0, 0, 0, 0, 91, 115, 116, - 222, 222, 0, 117, 117, 334, 335, 336, 0, 0, - -2, 246, 0, 319, 0, 0, 236, 236, 240, 238, - 239, 0, 0, 0, 0, 0, 0, 346, 0, 347, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, - 0, 223, 0, 364, 365, 273, 0, 0, 0, 0, - 344, 345, 0, 0, 933, 934, 0, 0, 222, 222, - 0, 0, 0, 0, 222, 222, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 101, 840, 0, 0, 0, 0, 0, 0, -2, - 0, 410, 0, 926, 0, 0, 0, 0, 417, 0, - 419, 420, 0, 0, 421, 0, 471, 471, 469, 470, - 423, 424, 425, 426, 474, 0, 0, 231, 232, 233, - 471, 474, 0, 474, 474, 474, 474, 471, 474, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1350, 1350, - 1350, 477, 455, 456, 459, 460, 1351, 1352, 461, 462, - 916, 491, 494, 511, 509, 510, 512, 504, 505, 506, - 507, 0, 524, 525, 530, 0, 0, 0, 0, 536, - 537, 538, 0, 0, 541, 542, 543, 0, 0, 0, - 0, 0, 648, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 672, 673, 674, 675, 676, 677, 678, 651, - 0, 665, 0, 0, 0, 707, 708, 709, 710, 711, - 712, 713, 714, 715, 0, 562, 0, 0, 0, 812, - 0, 0, 0, 0, 0, 0, 0, 559, 0, 786, - 0, 738, 746, 0, 739, 747, 740, 748, 741, 0, - 742, 749, 743, 750, 744, 745, 751, 0, 0, 0, - 562, 562, 0, 0, 40, 515, 516, 0, 617, 936, - 820, 0, 564, 858, 0, 0, 821, 813, 814, 817, - 820, 0, 587, 576, 566, 569, 570, 552, 0, 579, - 583, 0, 585, 586, 0, 0, 69, 0, 633, 0, - 589, 591, 592, 593, 615, 0, 0, 0, 0, 65, - 67, 634, 0, 1315, 914, 0, 73, 74, 0, 0, - 0, 210, 919, 920, 921, -2, 229, 0, 135, 203, - 147, 148, 149, 196, 151, 196, 196, 196, 196, 207, - 207, 207, 207, 179, 180, 181, 182, 183, 0, 0, - 166, 196, 196, 196, 196, 186, 187, 188, 189, 190, - 191, 192, 193, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 198, 198, 198, 200, 200, 0, 38, 0, - 214, 0, 817, 0, 840, 0, 0, 939, 0, 938, - 938, 938, 106, 0, 0, 0, 367, 328, 356, 368, - 0, 331, 332, -2, 0, 0, 318, 0, 320, 0, - 230, 0, -2, 0, 0, 0, 236, 240, 237, 240, - 228, 241, 348, 794, 0, 349, 350, 0, 382, 603, - 0, 0, 0, 0, 0, 388, 389, 390, 0, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 401, 357, - 358, 359, 360, 361, 362, 363, 0, 0, 320, 0, - 353, 0, 274, 275, 0, 0, 278, 279, 280, 281, - 0, 0, 284, 285, 286, 287, 288, 312, 313, 314, - 289, 290, 291, 292, 293, 294, 295, 306, 307, 308, - 309, 310, 311, 296, 297, 298, 299, 300, 303, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 837, - 838, 839, 0, 0, 0, 0, 0, 261, 63, 927, - 416, 635, 947, 948, 475, 476, 0, 234, 235, 474, - 474, 427, 450, 0, 474, 431, 452, 432, 434, 433, - 435, 474, 438, 472, 473, 439, 440, 441, 442, 443, - 444, 445, 446, 447, 448, 454, 0, 0, 0, 492, - 496, 497, 498, 499, 0, 0, 527, 532, 533, 534, - 535, 547, 540, 686, 645, 646, 647, 649, 666, 0, - 668, 670, 656, 657, 681, 682, 683, 0, 0, 0, - 0, 679, 661, 0, 692, 693, 694, 695, 696, 697, - 698, 699, 700, 701, 702, 703, 706, 769, 770, 771, - 0, 704, 705, 716, 0, 0, 0, 563, 795, 0, - -2, 0, 684, 903, 820, 0, 0, 0, 0, 689, - 797, 0, 689, 797, 0, 0, 0, 560, 561, 792, - 789, 0, 0, 755, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 518, 519, 521, 0, 637, 0, 618, - 0, 620, 621, 0, 937, 855, 51, 41, 0, 856, - 0, 0, 0, 0, 816, 818, 819, 855, 0, 805, - 0, 0, 642, 0, 0, 567, 47, 584, 580, 0, - 642, 0, 0, 632, 0, 0, 0, 0, 0, 0, - 622, 0, 0, 625, 0, 0, 0, 0, 616, 0, - 0, 0, -2, 0, 0, 0, 61, 62, 0, 0, - 0, 909, 72, 0, 0, 77, 78, 910, 911, 912, - 913, 0, 110, -2, 269, 129, 131, 132, 133, 124, - 134, 205, 204, 150, 207, 207, 173, 174, 210, 0, - 210, 210, 210, 0, 0, 167, 168, 169, 170, 161, - 0, 162, 163, 164, 0, 165, 247, 0, 824, 215, - 216, 218, 222, 0, 0, 243, 244, 0, 0, 100, - 0, 940, 0, 0, 0, 929, 119, 120, 121, 122, + 928, 938, 0, 0, 0, 928, 91, 115, 116, 222, + 222, 0, 117, 117, 334, 335, 336, 0, 0, -2, + 246, 0, 319, 0, 0, 236, 236, 240, 238, 239, + 0, 0, 0, 0, 0, 0, 346, 0, 347, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, + 223, 0, 364, 365, 273, 0, 0, 0, 0, 344, + 345, 0, 0, 933, 934, 0, 0, 222, 222, 0, + 0, 0, 0, 222, 222, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 840, 0, 0, 0, 0, 0, 0, -2, 0, + 410, 0, 926, 0, 0, 0, 926, 417, 0, 419, + 420, 0, 0, 421, 0, 471, 471, 469, 470, 423, + 424, 425, 426, 474, 0, 0, 231, 232, 233, 471, + 474, 0, 474, 474, 474, 474, 471, 474, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1350, 1350, 1350, + 477, 455, 456, 459, 460, 1351, 1352, 461, 462, 916, + 491, 494, 511, 509, 510, 512, 504, 505, 506, 507, + 0, 524, 525, 530, 0, 0, 0, 0, 536, 537, + 538, 0, 0, 541, 542, 543, 0, 0, 0, 0, + 0, 648, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 672, 673, 674, 675, 676, 677, 678, 651, 0, + 665, 0, 0, 0, 707, 708, 709, 710, 711, 712, + 713, 714, 715, 0, 562, 0, 0, 0, 812, 0, + 0, 0, 0, 0, 0, 0, 559, 0, 786, 0, + 738, 746, 0, 739, 747, 740, 748, 741, 0, 742, + 749, 743, 750, 744, 745, 751, 0, 0, 0, 562, + 562, 0, 0, 40, 515, 516, 0, 617, 936, 820, + 0, 564, 858, 0, 0, 821, 813, 814, 817, 820, + 0, 587, 576, 566, 569, 570, 552, 0, 579, 583, + 0, 585, 586, 0, 0, 69, 0, 633, 0, 589, + 591, 592, 593, 615, 0, 0, 0, 0, 65, 67, + 634, 0, 1315, 914, 0, 73, 74, 0, 0, 0, + 210, 919, 920, 921, -2, 229, 0, 135, 203, 147, + 148, 149, 196, 151, 196, 196, 196, 196, 207, 207, + 207, 207, 179, 180, 181, 182, 183, 0, 0, 166, + 196, 196, 196, 196, 186, 187, 188, 189, 190, 191, + 192, 193, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 198, 198, 198, 200, 200, 0, 38, 0, 214, + 0, 817, 0, 840, 0, 0, 0, 939, 0, 938, + 938, 938, 0, 0, 0, 367, 328, 356, 368, 0, + 331, 332, -2, 0, 0, 318, 0, 320, 0, 230, + 0, -2, 0, 0, 0, 236, 240, 237, 240, 228, + 241, 348, 794, 0, 349, 350, 0, 382, 603, 0, + 0, 0, 0, 0, 388, 389, 390, 0, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 357, 358, + 359, 360, 361, 362, 363, 0, 0, 320, 0, 353, + 0, 274, 275, 0, 0, 278, 279, 280, 281, 0, + 0, 284, 285, 286, 287, 288, 312, 313, 314, 289, + 290, 291, 292, 293, 294, 295, 306, 307, 308, 309, + 310, 311, 296, 297, 298, 299, 300, 303, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 837, 838, + 839, 0, 0, 0, 0, 0, 261, 63, 927, 0, + 635, 947, 948, 475, 476, 0, 234, 235, 474, 474, + 427, 450, 0, 474, 431, 452, 432, 434, 433, 435, + 474, 438, 472, 473, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 454, 0, 0, 0, 492, 496, + 497, 498, 499, 0, 0, 527, 532, 533, 534, 535, + 547, 540, 686, 645, 646, 647, 649, 666, 0, 668, + 670, 656, 657, 681, 682, 683, 0, 0, 0, 0, + 679, 661, 0, 692, 693, 694, 695, 696, 697, 698, + 699, 700, 701, 702, 703, 706, 769, 770, 771, 0, + 704, 705, 716, 0, 0, 0, 563, 795, 0, -2, + 0, 684, 903, 820, 0, 0, 0, 0, 689, 797, + 0, 689, 797, 0, 0, 0, 560, 561, 792, 789, + 0, 0, 755, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 518, 519, 521, 0, 637, 0, 618, 0, + 620, 621, 0, 937, 855, 51, 41, 0, 856, 0, + 0, 0, 0, 816, 818, 819, 855, 0, 805, 0, + 0, 642, 0, 0, 567, 47, 584, 580, 0, 642, + 0, 0, 632, 0, 0, 0, 0, 0, 0, 622, + 0, 0, 625, 0, 0, 0, 0, 616, 0, 0, + 0, -2, 0, 0, 0, 61, 62, 0, 0, 0, + 909, 72, 0, 0, 77, 78, 910, 911, 912, 913, + 0, 110, -2, 269, 129, 131, 132, 133, 124, 134, + 205, 204, 150, 207, 207, 173, 174, 210, 0, 210, + 210, 210, 0, 0, 167, 168, 169, 170, 161, 0, + 162, 163, 164, 0, 165, 247, 0, 824, 215, 216, + 218, 222, 0, 0, 243, 244, 0, 0, 100, 0, + 0, 940, 0, 0, 0, 106, 119, 120, 121, 122, 117, 0, 0, 125, 322, 0, 0, 0, 245, 0, 0, 224, 240, 225, 226, 0, 351, 0, 0, 384, 385, 386, 387, 0, 0, 0, 320, 322, 210, 0, 276, 277, 282, 283, 301, 0, 0, 0, 0, 850, 851, 0, 854, 92, 374, 376, 375, 379, 0, 0, - 0, 0, 411, 261, 824, 0, 415, 262, 263, 471, - 437, 453, 471, 429, 436, 478, 457, 488, 531, 0, - 0, 0, 539, 0, 667, 669, 671, 658, 679, 662, - 0, 659, 0, 0, 653, 721, 0, 0, 562, 0, - 812, 855, 725, 726, 0, 0, 0, 0, 0, 762, - 0, 0, 763, 0, 812, 0, 790, 0, 0, 737, - 756, 0, 0, 757, 758, 759, 760, 761, 517, 520, - 522, 597, 0, 0, 0, 0, 619, 935, 43, 0, - 0, 0, 822, 823, 815, 42, 0, 922, 923, 806, - 807, 808, 0, 577, 588, 568, 0, 820, 897, 0, - 0, 889, 0, 0, 642, 905, 0, 590, 611, 613, - 0, 608, 623, 624, 626, 0, 628, 0, 630, 631, - 594, 595, 596, 0, 642, 0, 642, 66, 642, 68, - 0, 636, 75, 76, 0, 0, 82, 211, 212, 117, - 271, 130, 136, 0, 0, 0, 140, 0, 0, 143, - 145, 146, 206, 210, 210, 175, 208, 209, 176, 177, - 178, 0, 194, 0, 0, 0, 264, 87, 828, 827, - 222, 222, 217, 0, 220, 0, 197, 0, 102, 0, - 0, 0, 0, 326, 601, 0, 337, 338, 0, 321, - 381, 0, 214, 0, 227, 795, 604, 0, 0, 339, - 0, 322, 342, 343, 354, 304, 305, 302, 599, 841, - 842, 843, 0, 853, 95, 0, 0, 0, 0, 372, - 0, 413, 414, 64, 474, 474, 526, 0, 529, 0, - 660, 0, 680, 663, 722, 723, 0, 796, 820, 45, - 0, 196, 196, 775, 196, 200, 778, 196, 780, 196, - 783, 0, 0, 0, 0, 0, 0, 0, 787, 736, - 793, 0, 0, 0, 0, 0, 0, 0, 0, 207, - 860, 857, 44, 810, 0, 643, 581, 48, 52, 0, - 897, 888, 899, 901, 0, 0, 0, 893, 0, 812, - 0, 0, 605, 612, 0, 0, 606, 0, 607, 627, - 629, -2, 812, 642, 59, 60, 0, 79, 80, 81, - 270, 137, 138, 0, 141, 142, 144, 171, 172, 207, - 0, 207, 0, 201, 0, 253, 265, 0, 825, 826, - 0, 0, 219, 221, 599, 103, 104, 105, 0, 0, - 126, 323, 0, 213, 0, 0, 406, 403, 340, 341, - 0, 0, 852, 373, 0, 93, 94, 0, 0, 378, - 412, 422, 428, 528, 548, 664, 724, 855, 727, 772, - 207, 776, 777, 779, 781, 782, 784, 729, 728, 0, - 0, 0, 0, 0, 820, 0, 791, 0, 0, 0, - 0, 0, 617, 207, 880, 49, 0, 0, 0, 53, - 0, 902, 0, 0, 0, 0, 70, 820, 906, 907, - 609, 0, 614, 820, 58, 139, 210, 195, 210, 0, - 0, 266, 829, 830, 831, 832, 833, 834, 835, 0, - 329, 602, 0, 0, 383, 0, 391, 0, 0, 0, - 0, 96, 97, 0, 0, 0, 46, 773, 774, 0, - 0, 0, 0, 764, 0, 788, 0, 0, 0, 639, - 0, 0, 637, 862, 861, 874, 878, 811, 809, 0, - 900, 0, 892, 895, 891, 894, 56, 0, 57, 184, - 185, 199, 202, 0, 0, 0, 407, 404, 405, 844, - 600, 0, 0, 0, 380, 730, 732, 731, 733, 0, - 0, 0, 735, 752, 753, 638, 640, 641, 598, 880, - 0, 873, 876, -2, 0, 0, 890, 0, 610, 844, - 0, 0, 370, 846, 98, 99, 315, 316, 317, 92, - 734, 0, 0, 0, 867, 865, 865, 878, 0, 882, - 0, 887, 0, 898, 896, 88, 0, 0, 0, 0, - 847, 848, 95, 765, 0, 768, 870, 0, 863, 866, - 864, 875, 0, 881, 0, 0, 879, 408, 409, 249, - 0, 377, 766, 859, 0, 868, 869, 877, 0, 0, - 250, 251, 0, 845, 0, 871, 872, 883, 885, 252, - 0, 0, 0, 0, 254, 256, 257, 0, 0, 255, - 767, 258, 259, 260, + 0, 0, 411, 261, 824, 0, 415, 262, 263, 416, + 471, 437, 453, 471, 429, 436, 478, 457, 488, 531, + 0, 0, 0, 539, 0, 667, 669, 671, 658, 679, + 662, 0, 659, 0, 0, 653, 721, 0, 0, 562, + 0, 812, 855, 725, 726, 0, 0, 0, 0, 0, + 762, 0, 0, 763, 0, 812, 0, 790, 0, 0, + 737, 756, 0, 0, 757, 758, 759, 760, 761, 517, + 520, 522, 597, 0, 0, 0, 0, 619, 935, 43, + 0, 0, 0, 822, 823, 815, 42, 0, 922, 923, + 806, 807, 808, 0, 577, 588, 568, 0, 820, 897, + 0, 0, 889, 0, 0, 642, 905, 0, 590, 611, + 613, 0, 608, 623, 624, 626, 0, 628, 0, 630, + 631, 594, 595, 596, 0, 642, 0, 642, 66, 642, + 68, 0, 636, 75, 76, 0, 0, 82, 211, 212, + 117, 271, 130, 136, 0, 0, 0, 140, 0, 0, + 143, 145, 146, 206, 210, 210, 175, 208, 209, 176, + 177, 178, 0, 194, 0, 0, 0, 264, 87, 828, + 827, 222, 222, 217, 0, 220, 0, 197, 0, 929, + 102, 0, 0, 0, 0, 326, 601, 0, 337, 338, + 0, 321, 381, 0, 214, 0, 227, 795, 604, 0, + 0, 339, 0, 322, 342, 343, 354, 304, 305, 302, + 599, 841, 842, 843, 0, 853, 95, 0, 0, 0, + 0, 372, 0, 413, 414, 64, 474, 474, 526, 0, + 529, 0, 660, 0, 680, 663, 722, 723, 0, 796, + 820, 45, 0, 196, 196, 775, 196, 200, 778, 196, + 780, 196, 783, 0, 0, 0, 0, 0, 0, 0, + 787, 736, 793, 0, 0, 0, 0, 0, 0, 0, + 0, 207, 860, 857, 44, 810, 0, 643, 581, 48, + 52, 0, 897, 888, 899, 901, 0, 0, 0, 893, + 0, 812, 0, 0, 605, 612, 0, 0, 606, 0, + 607, 627, 629, -2, 812, 642, 59, 60, 0, 79, + 80, 81, 270, 137, 138, 0, 141, 142, 144, 171, + 172, 207, 0, 207, 0, 201, 0, 253, 265, 0, + 825, 826, 0, 0, 219, 221, 599, 103, 104, 105, + 0, 0, 126, 323, 0, 213, 0, 0, 406, 403, + 340, 341, 0, 0, 852, 373, 0, 93, 94, 0, + 0, 378, 412, 422, 428, 528, 548, 664, 724, 855, + 727, 772, 207, 776, 777, 779, 781, 782, 784, 729, + 728, 0, 0, 0, 0, 0, 820, 0, 791, 0, + 0, 0, 0, 0, 617, 207, 880, 49, 0, 0, + 0, 53, 0, 902, 0, 0, 0, 0, 70, 820, + 906, 907, 609, 0, 614, 820, 58, 139, 210, 195, + 210, 0, 0, 266, 829, 830, 831, 832, 833, 834, + 835, 0, 329, 602, 0, 0, 383, 0, 391, 0, + 0, 0, 0, 96, 97, 0, 0, 0, 46, 773, + 774, 0, 0, 0, 0, 764, 0, 788, 0, 0, + 0, 639, 0, 0, 637, 862, 861, 874, 878, 811, + 809, 0, 900, 0, 892, 895, 891, 894, 56, 0, + 57, 184, 185, 199, 202, 0, 0, 0, 407, 404, + 405, 844, 600, 0, 0, 0, 380, 730, 732, 731, + 733, 0, 0, 0, 735, 752, 753, 638, 640, 641, + 598, 880, 0, 873, 876, -2, 0, 0, 890, 0, + 610, 844, 0, 0, 370, 846, 98, 99, 315, 316, + 317, 92, 734, 0, 0, 0, 867, 865, 865, 878, + 0, 882, 0, 887, 0, 898, 896, 88, 0, 0, + 0, 0, 847, 848, 95, 765, 0, 768, 870, 0, + 863, 866, 864, 875, 0, 881, 0, 0, 879, 408, + 409, 249, 0, 377, 766, 859, 0, 868, 869, 877, + 0, 0, 250, 251, 0, 845, 0, 871, 872, 883, + 885, 252, 0, 0, 0, 0, 254, 256, 257, 0, + 0, 255, 767, 258, 259, 260, } var yyTok1 = [...]int{ @@ -5876,10 +5851,10 @@ yydefault: setDDL(yylex, yyVAL.alterTable) } case 106: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] //line sql.y:867 { - yyVAL.createDatabase = &CreateDatabase{DBName: string(yyDollar[4].colIdent.String()), IfNotExists: yyDollar[3].boolean} + yyVAL.createDatabase = &CreateDatabase{Comments: Comments(yyDollar[3].bytes2), DBName: string(yyDollar[5].colIdent.String()), IfNotExists: yyDollar[4].boolean} setDDL(yylex, yyVAL.createDatabase) } case 107: @@ -7743,10 +7718,10 @@ yydefault: yyVAL.statement = &DropView{FromTables: yyDollar[4].tableNames, IfExists: yyDollar[3].boolean} } case 416: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] //line sql.y:2295 { - yyVAL.statement = &DropDatabase{DBName: string(yyDollar[4].colIdent.String()), IfExists: yyDollar[3].boolean} + yyVAL.statement = &DropDatabase{Comments: Comments(yyDollar[3].bytes2), DBName: string(yyDollar[5].colIdent.String()), IfExists: yyDollar[4].boolean} } case 417: yyDollar = yyS[yypt-3 : yypt+1] diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index e96ec9cb4d7..55d596b5729 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -863,9 +863,9 @@ create_index_prefix: } create_database_prefix: - CREATE database_or_schema not_exists_opt id_or_var + CREATE database_or_schema comment_opt not_exists_opt id_or_var { - $$ = &CreateDatabase{DBName: string($4.String()), IfNotExists: $3} + $$ = &CreateDatabase{Comments: Comments($3), DBName: string($5.String()), IfNotExists: $4} setDDL(yylex,$$) } @@ -2291,9 +2291,9 @@ drop_statement: { $$ = &DropView{FromTables: $4, IfExists: $3} } -| DROP database_or_schema exists_opt id_or_var +| DROP database_or_schema comment_opt exists_opt id_or_var { - $$ = &DropDatabase{DBName: string($4.String()), IfExists: $3} + $$ = &DropDatabase{Comments: Comments($3), DBName: string($5.String()), IfExists: $4} } truncate_statement: From 10daa0eddc8d0b7b3a5c254f961ebae7bf34a430 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 4 Mar 2021 21:16:59 +0530 Subject: [PATCH 16/23] added comments directive to set query timeout in db ddl primitive Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/cached_size.go | 2 +- go/vt/vtgate/engine/dbddl.go | 16 +++++++++++----- go/vt/vtgate/planbuilder/builder.go | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index ed8431cafdd..18e3a530d19 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -78,7 +78,7 @@ func (cached *DBDDL) CachedSize(alloc bool) int64 { } size := int64(0) if alloc { - size += int64(17) + size += int64(32) } // field name string size += int64(len(cached.name)) diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index aa6d7e41589..45071dbf947 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -58,8 +58,9 @@ type DBDDLPlugin interface { // DBDDL is just a container around custom database provisioning plugins // The default behaviour is to just return an error type DBDDL struct { - name string - create bool + name string + create bool + queryTimeout int noInputs noTxNeeded @@ -67,10 +68,11 @@ type DBDDL struct { // NewDBDDL creates the engine primitive // `create` will be true for CREATE, and false for DROP -func NewDBDDL(dbName string, create bool) *DBDDL { +func NewDBDDL(dbName string, create bool, timeout int) *DBDDL { return &DBDDL{ - name: dbName, - create: create, + name: dbName, + create: create, + queryTimeout: timeout, } } @@ -100,6 +102,10 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b log.Errorf("'%s' database ddl plugin is not registered. Falling back to default plugin", name) plugin = databaseCreatorPlugins[defaultDBDDLPlugin] } + if c.queryTimeout != 0 { + cancel := vcursor.SetContextTimeout(time.Duration(c.queryTimeout) * time.Millisecond) + defer cancel() + } ctx := vcursor.Context() if c.create { diff --git a/go/vt/vtgate/planbuilder/builder.go b/go/vt/vtgate/planbuilder/builder.go index dacb2491fcb..020a7f3f7f0 100644 --- a/go/vt/vtgate/planbuilder/builder.go +++ b/go/vt/vtgate/planbuilder/builder.go @@ -205,7 +205,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_NOT_FOUND, vterrors.DbDropExists, "Can't drop database '%s'; database doesn't exists", ksName) } - return engine.NewDBDDL(ksName, false), nil + return engine.NewDBDDL(ksName, false, queryTimeout(sqlparser.ExtractCommentDirectives(dbDDL.Comments))), nil case *sqlparser.AlterDatabase: if !ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_NOT_FOUND, vterrors.BadDb, "Can't alter database '%s'; unknown database", ksName) @@ -218,7 +218,7 @@ func buildDBDDLPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.Pr if !dbDDL.IfNotExists && ksExists { return nil, vterrors.NewErrorf(vtrpcpb.Code_ALREADY_EXISTS, vterrors.DbCreateExists, "Can't create database '%s'; database exists", ksName) } - return engine.NewDBDDL(ksName, true), nil + return engine.NewDBDDL(ksName, true, queryTimeout(sqlparser.ExtractCommentDirectives(dbDDL.Comments))), nil } return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] database ddl not recognized: %s", sqlparser.String(dbDDLstmt)) } From 131c5f97d8819a851bf37a064ef35b36479f1108 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 5 Mar 2021 16:38:18 +0530 Subject: [PATCH 17/23] added timeout test Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/dbddl.go | 4 +- go/vt/vtgate/engine/dbddl_test.go | 26 ++++++ go/vt/vtgate/engine/fake_vcursor_test.go | 105 ++++++++++++----------- go/vt/vtgate/engine/join_test.go | 14 +-- go/vt/vtgate/engine/memory_sort_test.go | 10 +-- go/vt/vtgate/engine/merge_sort_test.go | 2 +- 6 files changed, 97 insertions(+), 64 deletions(-) diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 45071dbf947..0e252e3a71e 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -120,7 +120,7 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b if err == nil { break } - log.Errorf("waiting for db create, step1: %s", err.Error()) + log.Errorf("waiting for topo to be updated after create db: %s", err.Error()) select { case <-ctx.Done(): //context cancelled return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") @@ -142,7 +142,7 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b for _, err := range errors { if err != nil { noErr = false - log.Errorf("waiting for db create, step2: %s", err.Error()) + log.Errorf("waiting for healthy tablets to be available after create db: %s", err.Error()) select { case <-ctx.Done(): //context cancelled return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") diff --git a/go/vt/vtgate/engine/dbddl_test.go b/go/vt/vtgate/engine/dbddl_test.go index bffaa79f720..52d3bb1f215 100644 --- a/go/vt/vtgate/engine/dbddl_test.go +++ b/go/vt/vtgate/engine/dbddl_test.go @@ -2,21 +2,30 @@ package engine import ( "context" + "fmt" "testing" + "time" "github.com/stretchr/testify/require" ) type dbddlTestFake struct { createCalled, dropCalled bool + sleep int } func (d *dbddlTestFake) CreateDatabase(ctx context.Context, name string) error { + if d.sleep > 0 { + time.Sleep(time.Duration(d.sleep) * time.Second) + } d.createCalled = true return nil } func (d *dbddlTestFake) DropDatabase(ctx context.Context, name string) error { + if d.sleep > 0 { + time.Sleep(time.Duration(d.sleep) * time.Second) + } d.dropCalled = true return nil } @@ -55,3 +64,20 @@ func TestDBDDLDropExecute(t *testing.T) { require.False(t, plugin.createCalled) require.True(t, plugin.dropCalled) } + +func TestDBDDLTimeout(t *testing.T) { + pluginName := "timeoutFake" + plugin := &dbddlTestFake{sleep: 2} + DBDDLRegister(pluginName, plugin) + + primitive := &DBDDL{ + name: "ks", + create: true, + queryTimeout: 100, + } + + vc := &loggingVCursor{dbDDLPlugin: pluginName, shardErr: fmt.Errorf("db not available")} + + _, err := primitive.Execute(vc, nil, false) + require.EqualError(t, err, "could not validate created database") +} diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index e5b8917c770..424438b15f4 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -57,185 +57,187 @@ type noopVCursor struct { ctx context.Context } -func (t noopVCursor) SetDDLStrategy(strategy string) { +func (t *noopVCursor) SetDDLStrategy(strategy string) { panic("implement me") } -func (t noopVCursor) GetDDLStrategy() string { +func (t *noopVCursor) GetDDLStrategy() string { panic("implement me") } -func (t noopVCursor) GetSessionUUID() string { +func (t *noopVCursor) GetSessionUUID() string { panic("implement me") } -func (t noopVCursor) SetReadAfterWriteGTID(s string) { +func (t *noopVCursor) SetReadAfterWriteGTID(s string) { panic("implement me") } -func (t noopVCursor) SetSessionEnableSystemSettings(allow bool) error { +func (t *noopVCursor) SetSessionEnableSystemSettings(allow bool) error { panic("implement me") } -func (t noopVCursor) GetSessionEnableSystemSettings() bool { +func (t *noopVCursor) GetSessionEnableSystemSettings() bool { panic("implement me") } -func (t noopVCursor) SetReadAfterWriteTimeout(f float64) { +func (t *noopVCursor) SetReadAfterWriteTimeout(f float64) { panic("implement me") } -func (t noopVCursor) SetSessionTrackGTIDs(b bool) { +func (t *noopVCursor) SetSessionTrackGTIDs(b bool) { panic("implement me") } -func (t noopVCursor) HasCreatedTempTable() { +func (t *noopVCursor) HasCreatedTempTable() { panic("implement me") } -func (t noopVCursor) LookupRowLockShardSession() vtgatepb.CommitOrder { +func (t *noopVCursor) LookupRowLockShardSession() vtgatepb.CommitOrder { panic("implement me") } -func (t noopVCursor) SetFoundRows(u uint64) { +func (t *noopVCursor) SetFoundRows(u uint64) { panic("implement me") } -func (t noopVCursor) InTransactionAndIsDML() bool { +func (t *noopVCursor) InTransactionAndIsDML() bool { panic("implement me") } -func (t noopVCursor) FindRoutedTable(sqlparser.TableName) (*vindexes.Table, error) { +func (t *noopVCursor) FindRoutedTable(sqlparser.TableName) (*vindexes.Table, error) { panic("implement me") } -func (t noopVCursor) ExecuteLock(rs *srvtopo.ResolvedShard, query *querypb.BoundQuery) (*sqltypes.Result, error) { +func (t *noopVCursor) ExecuteLock(rs *srvtopo.ResolvedShard, query *querypb.BoundQuery) (*sqltypes.Result, error) { panic("implement me") } -func (t noopVCursor) NeedsReservedConn() { +func (t *noopVCursor) NeedsReservedConn() { } -func (t noopVCursor) SetUDV(key string, value interface{}) error { +func (t *noopVCursor) SetUDV(key string, value interface{}) error { panic("implement me") } -func (t noopVCursor) SetSysVar(name string, expr string) { +func (t *noopVCursor) SetSysVar(name string, expr string) { //panic("implement me") } -func (t noopVCursor) InReservedConn() bool { +func (t *noopVCursor) InReservedConn() bool { panic("implement me") } -func (t noopVCursor) ShardSession() []*srvtopo.ResolvedShard { +func (t *noopVCursor) ShardSession() []*srvtopo.ResolvedShard { panic("implement me") } -func (t noopVCursor) ExecuteVSchema(keyspace string, vschemaDDL *sqlparser.AlterVschema) error { +func (t *noopVCursor) ExecuteVSchema(keyspace string, vschemaDDL *sqlparser.AlterVschema) error { panic("implement me") } -func (t noopVCursor) Session() SessionActions { +func (t *noopVCursor) Session() SessionActions { return t } -func (t noopVCursor) SetAutocommit(bool) error { +func (t *noopVCursor) SetAutocommit(bool) error { panic("implement me") } -func (t noopVCursor) SetClientFoundRows(bool) error { +func (t *noopVCursor) SetClientFoundRows(bool) error { panic("implement me") } -func (t noopVCursor) SetSkipQueryPlanCache(bool) error { +func (t *noopVCursor) SetSkipQueryPlanCache(bool) error { panic("implement me") } -func (t noopVCursor) SetSQLSelectLimit(int64) error { +func (t *noopVCursor) SetSQLSelectLimit(int64) error { panic("implement me") } -func (t noopVCursor) SetTransactionMode(vtgatepb.TransactionMode) { +func (t *noopVCursor) SetTransactionMode(vtgatepb.TransactionMode) { panic("implement me") } -func (t noopVCursor) SetWorkload(querypb.ExecuteOptions_Workload) { +func (t *noopVCursor) SetWorkload(querypb.ExecuteOptions_Workload) { panic("implement me") } -func (t noopVCursor) SetPlannerVersion(querypb.ExecuteOptions_PlannerVersion) { +func (t *noopVCursor) SetPlannerVersion(querypb.ExecuteOptions_PlannerVersion) { panic("implement me") } -func (t noopVCursor) SetTarget(string) error { +func (t *noopVCursor) SetTarget(string) error { panic("implement me") } -func (t noopVCursor) Context() context.Context { +func (t *noopVCursor) Context() context.Context { if t.ctx == nil { return context.Background() } return t.ctx } -func (t noopVCursor) MaxMemoryRows() int { +func (t *noopVCursor) MaxMemoryRows() int { return testMaxMemoryRows } -func (t noopVCursor) ExceedsMaxMemoryRows(numRows int) bool { +func (t *noopVCursor) ExceedsMaxMemoryRows(numRows int) bool { return !testIgnoreMaxMemoryRows && numRows > testMaxMemoryRows } -func (t noopVCursor) GetKeyspace() string { +func (t *noopVCursor) GetKeyspace() string { return "" } -func (t noopVCursor) SetContextTimeout(timeout time.Duration) context.CancelFunc { - return func() {} +func (t *noopVCursor) SetContextTimeout(timeout time.Duration) context.CancelFunc { + ctx, cancel := context.WithTimeout(t.Context(), timeout) + t.ctx = ctx + return cancel } -func (t noopVCursor) ErrorGroupCancellableContext() (*errgroup.Group, func()) { +func (t *noopVCursor) ErrorGroupCancellableContext() (*errgroup.Group, func()) { g, ctx := errgroup.WithContext(t.ctx) t.ctx = ctx return g, func() {} } -func (t noopVCursor) RecordWarning(warning *querypb.QueryWarning) { +func (t *noopVCursor) RecordWarning(warning *querypb.QueryWarning) { } -func (t noopVCursor) Execute(method string, query string, bindvars map[string]*querypb.BindVariable, rollbackOnError bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) { +func (t *noopVCursor) Execute(method string, query string, bindvars map[string]*querypb.BindVariable, rollbackOnError bool, co vtgatepb.CommitOrder) (*sqltypes.Result, error) { panic("unimplemented") } -func (t noopVCursor) ExecuteMultiShard(rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { +func (t *noopVCursor) ExecuteMultiShard(rss []*srvtopo.ResolvedShard, queries []*querypb.BoundQuery, rollbackOnError, canAutocommit bool) (*sqltypes.Result, []error) { panic("unimplemented") } -func (t noopVCursor) AutocommitApproval() bool { +func (t *noopVCursor) AutocommitApproval() bool { panic("unimplemented") } -func (t noopVCursor) ExecuteStandalone(query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { +func (t *noopVCursor) ExecuteStandalone(query string, bindvars map[string]*querypb.BindVariable, rs *srvtopo.ResolvedShard) (*sqltypes.Result, error) { panic("unimplemented") } -func (t noopVCursor) StreamExecuteMulti(query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, callback func(reply *sqltypes.Result) error) error { +func (t *noopVCursor) StreamExecuteMulti(query string, rss []*srvtopo.ResolvedShard, bindVars []map[string]*querypb.BindVariable, callback func(reply *sqltypes.Result) error) error { panic("unimplemented") } -func (t noopVCursor) ExecuteKeyspaceID(keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError, autocommit bool) (*sqltypes.Result, error) { +func (t *noopVCursor) ExecuteKeyspaceID(keyspace string, ksid []byte, query string, bindVars map[string]*querypb.BindVariable, rollbackOnError, autocommit bool) (*sqltypes.Result, error) { panic("unimplemented") } -func (t noopVCursor) ResolveDestinations(keyspace string, ids []*querypb.Value, destinations []key.Destination) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { +func (t *noopVCursor) ResolveDestinations(keyspace string, ids []*querypb.Value, destinations []key.Destination) ([]*srvtopo.ResolvedShard, [][]*querypb.Value, error) { panic("unimplemented") } -func (t noopVCursor) SubmitOnlineDDL(onlineDDl *schema.OnlineDDL) error { +func (t *noopVCursor) SubmitOnlineDDL(onlineDDl *schema.OnlineDDL) error { panic("unimplemented") } -func (t noopVCursor) GetDBDDLPluginName() string { +func (t *noopVCursor) GetDBDDLPluginName() string { panic("unimplemented") } @@ -320,11 +322,16 @@ func (f *loggingVCursor) SetTarget(target string) error { } func (f *loggingVCursor) Context() context.Context { - return context.Background() + if f.ctx == nil { + return context.Background() + } + return f.ctx } -func (f *loggingVCursor) SetContextTimeout(time.Duration) context.CancelFunc { - return func() {} +func (f *loggingVCursor) SetContextTimeout(timeout time.Duration) context.CancelFunc { + ctx, cancel := context.WithTimeout(f.Context(), timeout) + f.ctx = ctx + return cancel } func (f *loggingVCursor) ErrorGroupCancellableContext() (*errgroup.Group, func()) { diff --git a/go/vt/vtgate/engine/join_test.go b/go/vt/vtgate/engine/join_test.go index cd352cb9bbe..3c18bfc2361 100644 --- a/go/vt/vtgate/engine/join_test.go +++ b/go/vt/vtgate/engine/join_test.go @@ -76,7 +76,7 @@ func TestJoinExecute(t *testing.T) { "bv": 1, }, } - r, err := jn.Execute(noopVCursor{}, bv, true) + r, err := jn.Execute(&noopVCursor{}, bv, true) if err != nil { t.Fatal(err) } @@ -103,7 +103,7 @@ func TestJoinExecute(t *testing.T) { leftPrim.rewind() rightPrim.rewind() jn.Opcode = LeftJoin - r, err = jn.Execute(noopVCursor{}, bv, true) + r, err = jn.Execute(&noopVCursor{}, bv, true) if err != nil { t.Fatal(err) } @@ -194,7 +194,7 @@ func TestJoinExecuteMaxMemoryRows(t *testing.T) { }, } testIgnoreMaxMemoryRows = test.ignoreMaxMemoryRows - _, err := jn.Execute(noopVCursor{}, bv, true) + _, err := jn.Execute(&noopVCursor{}, bv, true) if testIgnoreMaxMemoryRows { require.NoError(t, err) } else { @@ -235,7 +235,7 @@ func TestJoinExecuteNoResult(t *testing.T) { "bv": 1, }, } - r, err := jn.Execute(noopVCursor{}, map[string]*querypb.BindVariable{}, true) + r, err := jn.Execute(&noopVCursor{}, map[string]*querypb.BindVariable{}, true) if err != nil { t.Fatal(err) } @@ -265,7 +265,7 @@ func TestJoinExecuteErrors(t *testing.T) { Opcode: NormalJoin, Left: leftPrim, } - _, err := jn.Execute(noopVCursor{}, map[string]*querypb.BindVariable{}, true) + _, err := jn.Execute(&noopVCursor{}, map[string]*querypb.BindVariable{}, true) require.EqualError(t, err, "left err") // Error on right query @@ -295,7 +295,7 @@ func TestJoinExecuteErrors(t *testing.T) { "bv": 1, }, } - _, err = jn.Execute(noopVCursor{}, map[string]*querypb.BindVariable{}, true) + _, err = jn.Execute(&noopVCursor{}, map[string]*querypb.BindVariable{}, true) require.EqualError(t, err, "right err") // Error on right getfields @@ -322,7 +322,7 @@ func TestJoinExecuteErrors(t *testing.T) { "bv": 1, }, } - _, err = jn.Execute(noopVCursor{}, map[string]*querypb.BindVariable{}, true) + _, err = jn.Execute(&noopVCursor{}, map[string]*querypb.BindVariable{}, true) require.EqualError(t, err, "right err") } diff --git a/go/vt/vtgate/engine/memory_sort_test.go b/go/vt/vtgate/engine/memory_sort_test.go index 0ffda4cb002..66f564eb8a0 100644 --- a/go/vt/vtgate/engine/memory_sort_test.go +++ b/go/vt/vtgate/engine/memory_sort_test.go @@ -116,7 +116,7 @@ func TestMemorySortStreamExecute(t *testing.T) { } var results []*sqltypes.Result - err := ms.StreamExecute(noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { + err := ms.StreamExecute(&noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -145,7 +145,7 @@ func TestMemorySortStreamExecute(t *testing.T) { bv := map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)} results = nil - err = ms.StreamExecute(noopVCursor{}, bv, false, func(qr *sqltypes.Result) error { + err = ms.StreamExecute(&noopVCursor{}, bv, false, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -253,7 +253,7 @@ func TestMemorySortStreamExecuteTruncate(t *testing.T) { } var results []*sqltypes.Result - err := ms.StreamExecute(noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { + err := ms.StreamExecute(&noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { results = append(results, qr) return nil }) @@ -381,7 +381,7 @@ func TestMemorySortMaxMemoryRows(t *testing.T) { } testIgnoreMaxMemoryRows = test.ignoreMaxMemoryRows - err := ms.StreamExecute(noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { + err := ms.StreamExecute(&noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { return nil }) if testIgnoreMaxMemoryRows { @@ -422,7 +422,7 @@ func TestMemorySortExecuteNoVarChar(t *testing.T) { } fp.rewind() - err = ms.StreamExecute(noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { + err = ms.StreamExecute(&noopVCursor{}, nil, false, func(qr *sqltypes.Result) error { return nil }) if err == nil || err.Error() != want { diff --git a/go/vt/vtgate/engine/merge_sort_test.go b/go/vt/vtgate/engine/merge_sort_test.go index 4351d732889..1b37af94fa0 100644 --- a/go/vt/vtgate/engine/merge_sort_test.go +++ b/go/vt/vtgate/engine/merge_sort_test.go @@ -286,7 +286,7 @@ func testMergeSort(shardResults []*shardResult, orderBy []OrderbyParams, callbac Primitives: prims, OrderBy: orderBy, } - return ms.StreamExecute(noopVCursor{}, nil, true, callback) + return ms.StreamExecute(&noopVCursor{}, nil, true, callback) } type shardResult struct { From 9a33429cee29eb780a6ca930566aa255e3ad0b07 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 00:02:37 +0530 Subject: [PATCH 18/23] drop database to wait for vschema to be updated Signed-off-by: Harshit Gangal --- .../vtgate/createdb_plugin/main_test.go | 19 +++- go/vt/vtgate/engine/dbddl.go | 100 ++++++++++-------- go/vt/vtgate/engine/fake_vcursor_test.go | 8 ++ go/vt/vtgate/engine/primitive.go | 2 + go/vt/vtgate/vcursor_impl.go | 5 + 5 files changed, 86 insertions(+), 48 deletions(-) diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 64fac6ed2f6..74c65683bba 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -23,6 +23,7 @@ import ( "os" "sync" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" @@ -78,7 +79,7 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -func TestDBDDLPluginSync(t *testing.T) { +func TestDBDDLPlugin(t *testing.T) { defer cluster.PanicHandler(t) ctx := context.Background() vtParams := mysql.ConnParams{ @@ -96,21 +97,28 @@ func TestDBDDLPluginSync(t *testing.T) { qr := exec(t, conn, `create database aaa`) require.EqualValues(t, 1, qr.RowsAffected) }() - + time.Sleep(300 * time.Millisecond) start(t, "aaa") // wait until the create database query has returned wg.Wait() - exec(t, conn, `use aaa`) + exec(t, conn, `use aaa`) exec(t, conn, `create table t (id bigint primary key)`) exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`) assertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`) - exec(t, conn, `drop database aaa`) - + wg.Add(1) + go func() { + defer wg.Done() + _ = exec(t, conn, `drop database aaa`) + }() + time.Sleep(300 * time.Millisecond) shutdown("aaa") + // wait until the drop database query has returned + wg.Wait() + _, err = conn.ExecuteFetch(`select count(*) from t`, 1000, true) require.Error(t, err) } @@ -141,6 +149,7 @@ func shutdown(ksName string) { } } } + _ = clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteKeyspace", "-recursive", ksName) } func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 0e252e3a71e..be1a164a139 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -79,9 +79,9 @@ func NewDBDDL(dbName string, create bool, timeout int) *DBDDL { // RouteType implements the Primitive interface func (c *DBDDL) RouteType() string { if c.create { - return "create database" + return "CreateDB" } - return "drop database" + return "DropDB" } // GetKeyspaceName implements the Primitive interface @@ -107,61 +107,75 @@ func (c *DBDDL) Execute(vcursor VCursor, _ map[string]*querypb.BindVariable, _ b defer cancel() } - ctx := vcursor.Context() if c.create { - err := plugin.CreateDatabase(ctx, c.name) - if err != nil { - return nil, err - } - var destinations []*srvtopo.ResolvedShard - for { - // loop until we have found a valid shard - destinations, _, err = vcursor.ResolveDestinations(c.name, nil, []key.Destination{key.DestinationAllShards{}}) - if err == nil { - break - } - log.Errorf("waiting for topo to be updated after create db: %s", err.Error()) - select { - case <-ctx.Done(): //context cancelled - return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") - case <-time.After(500 * time.Millisecond): //timeout - } + return c.createDatabase(vcursor, plugin) + } + + return c.dropDatabase(vcursor, plugin) +} + +func (c *DBDDL) createDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.Result, error) { + ctx := vcursor.Context() + err := plugin.CreateDatabase(ctx, c.name) + if err != nil { + return nil, err + } + var destinations []*srvtopo.ResolvedShard + for { + // loop until we have found a valid shard + destinations, _, err = vcursor.ResolveDestinations(c.name, nil, []key.Destination{key.DestinationAllShards{}}) + if err == nil { + break } - var queries []*querypb.BoundQuery - for range destinations { - queries = append(queries, &querypb.BoundQuery{ - Sql: "select 42 from dual where null", - BindVariables: nil, - }) + select { + case <-ctx.Done(): //context cancelled + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") + case <-time.After(500 * time.Millisecond): //timeout } + } + var queries []*querypb.BoundQuery + for range destinations { + queries = append(queries, &querypb.BoundQuery{ + Sql: "select 42 from dual where null", + BindVariables: nil, + }) + } - for { - _, errors := vcursor.ExecuteMultiShard(destinations, queries, false, true) - - noErr := true - for _, err := range errors { - if err != nil { - noErr = false - log.Errorf("waiting for healthy tablets to be available after create db: %s", err.Error()) - select { - case <-ctx.Done(): //context cancelled - return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") - case <-time.After(500 * time.Millisecond): //timeout - } - break + for { + _, errors := vcursor.ExecuteMultiShard(destinations, queries, false, true) + + noErr := true + for _, err := range errors { + if err != nil { + noErr = false + select { + case <-ctx.Done(): //context cancelled + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") + case <-time.After(500 * time.Millisecond): //timeout } - } - if noErr { break } } - return &sqltypes.Result{RowsAffected: 1}, nil + if noErr { + break + } } + return &sqltypes.Result{RowsAffected: 1}, nil +} +func (c *DBDDL) dropDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.Result, error) { + ctx := vcursor.Context() err := plugin.DropDatabase(ctx, c.name) if err != nil { return nil, err } + for vcursor.FindKeyspace(c.name) { + select { + case <-ctx.Done(): //context cancelled + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate drop database") + case <-time.After(500 * time.Millisecond): //timeout + } + } return &sqltypes.Result{StatusFlags: sqltypes.ServerStatusDbDropped}, err } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 424438b15f4..6bf79902f18 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -57,6 +57,10 @@ type noopVCursor struct { ctx context.Context } +func (t *noopVCursor) FindKeyspace(ks string) bool { + panic("implement me") +} + func (t *noopVCursor) SetDDLStrategy(strategy string) { panic("implement me") } @@ -272,6 +276,10 @@ type loggingVCursor struct { dbDDLPlugin string } +func (f *loggingVCursor) FindKeyspace(ks string) bool { + return len(f.shards) > 0 +} + type tableRoutes struct { tbl *vindexes.Table } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index f77449847d3..44a75e4d3b8 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -101,6 +101,8 @@ type ( // GetDBDDLPlugin gets the configured plugin for DROP/CREATE DATABASE GetDBDDLPluginName() string + + FindKeyspace(ks string) bool } //SessionActions gives primitives ability to interact with the session state diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 742b24bcd8c..45c2f4b6140 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -698,6 +698,11 @@ func (vc *vcursorImpl) GetDBDDLPluginName() string { return *dbDDLPlugin } +func (vc *vcursorImpl) FindKeyspace(ks string) bool { + _, err := vc.topoServer.GetKeyspace(vc.ctx, ks) + return err == nil +} + // ParseDestinationTarget parses destination target string and sets default keyspace if possible. func parseDestinationTarget(targetString string, vschema *vindexes.VSchema) (string, topodatapb.TabletType, key.Destination, error) { destKeyspace, destTabletType, dest, err := topoprotopb.ParseDestination(targetString, defaultTabletType) From afd6e57e00c4940ad7db4ee79800d043ca6e2c2b Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 19:37:15 +0530 Subject: [PATCH 19/23] fix plan test Signed-off-by: Harshit Gangal --- go/vt/vtgate/planbuilder/testdata/ddl_cases.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt b/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt index fcd0e991312..091f0bc8dd2 100644 --- a/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/ddl_cases.txt @@ -102,7 +102,7 @@ "QueryType": "DDL", "Original": "create database foo", "Instructions": { - "OperatorType": "CREATE DATABASE", + "OperatorType": "CREATEDB", "Keyspace": { "Name": "foo", "Sharded": false @@ -142,7 +142,7 @@ "QueryType": "DDL", "Original": "drop database main", "Instructions": { - "OperatorType": "DROP DATABASE", + "OperatorType": "DROPDB", "Keyspace": { "Name": "main", "Sharded": false @@ -156,7 +156,7 @@ "QueryType": "DDL", "Original": "drop database if exists main", "Instructions": { - "OperatorType": "DROP DATABASE", + "OperatorType": "DROPDB", "Keyspace": { "Name": "main", "Sharded": false From 6a92f2d883b954de7b81fcd7fe17dc633e083611 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 10 Mar 2021 00:08:35 +0530 Subject: [PATCH 20/23] on drop database call, check if keyspace is removed from vschema Signed-off-by: Harshit Gangal --- go/vt/vtgate/vcursor_impl.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 45c2f4b6140..b8241f9b513 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -699,8 +699,7 @@ func (vc *vcursorImpl) GetDBDDLPluginName() string { } func (vc *vcursorImpl) FindKeyspace(ks string) bool { - _, err := vc.topoServer.GetKeyspace(vc.ctx, ks) - return err == nil + return vc.KeyspaceExists(ks) } // ParseDestinationTarget parses destination target string and sets default keyspace if possible. From 06da2d7e228e45763b11946df5369ff710a37779 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 11 Mar 2021 01:07:00 +0530 Subject: [PATCH 21/23] check resolve destination for drop database to see if keyspace is not available Signed-off-by: Harshit Gangal --- .../vtgate/createdb_plugin/main_test.go | 25 ++++--------------- go/vt/vtgate/engine/dbddl.go | 8 +++++- go/vt/vtgate/engine/fake_vcursor_test.go | 8 ------ go/vt/vtgate/engine/primitive.go | 2 -- go/vt/vtgate/vcursor_impl.go | 4 --- 5 files changed, 12 insertions(+), 35 deletions(-) diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 74c65683bba..93b678b368e 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -63,7 +63,7 @@ func TestMain(m *testing.M) { } // Start vtgate - clusterInstance.VtGateExtraArgs = []string{"-dbddl_plugin", "noop"} + clusterInstance.VtGateExtraArgs = []string{"-dbddl_plugin", "noop", "-mysql_server_query_timeout", "60s"} vtgateProcess := clusterInstance.NewVtgateInstance() vtgateProcess.SysVarSetEnabled = true if err := vtgateProcess.Setup(); err != nil { @@ -114,7 +114,7 @@ func TestDBDDLPlugin(t *testing.T) { _ = exec(t, conn, `drop database aaa`) }() time.Sleep(300 * time.Millisecond) - shutdown("aaa") + shutdown(t, "aaa") // wait until the drop database query has returned wg.Wait() @@ -132,24 +132,9 @@ func start(t *testing.T, ksName string) { "new database creation failed") } -func shutdown(ksName string) { - for _, ks := range clusterInstance.Keyspaces { - if ks.Name != ksName { - continue - } - for _, shard := range ks.Shards { - for _, tablet := range shard.Vttablets { - if tablet.MysqlctlProcess.TabletUID > 0 { - tablet.MysqlctlProcess.StopProcess() - } - if tablet.MysqlctldProcess.TabletUID > 0 { - tablet.MysqlctldProcess.Stop() - } - tablet.VttabletProcess.TearDown() - } - } - } - _ = clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteKeyspace", "-recursive", ksName) +func shutdown(t *testing.T, ksName string) { + require.NoError(t, + clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteKeyspace", "-recursive", ksName)) } func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index be1a164a139..405a064422b 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -169,7 +169,13 @@ func (c *DBDDL) dropDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.Res if err != nil { return nil, err } - for vcursor.FindKeyspace(c.name) { + for { + // loop until we do not find the keyspace to resolve. + _, _, err = vcursor.ResolveDestinations(c.name, nil, []key.Destination{}) + if err != nil && strings.Contains(err.Error(), "node doesn't exist") { + break + } + select { case <-ctx.Done(): //context cancelled return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate drop database") diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 6bf79902f18..424438b15f4 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -57,10 +57,6 @@ type noopVCursor struct { ctx context.Context } -func (t *noopVCursor) FindKeyspace(ks string) bool { - panic("implement me") -} - func (t *noopVCursor) SetDDLStrategy(strategy string) { panic("implement me") } @@ -276,10 +272,6 @@ type loggingVCursor struct { dbDDLPlugin string } -func (f *loggingVCursor) FindKeyspace(ks string) bool { - return len(f.shards) > 0 -} - type tableRoutes struct { tbl *vindexes.Table } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index 44a75e4d3b8..f77449847d3 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -101,8 +101,6 @@ type ( // GetDBDDLPlugin gets the configured plugin for DROP/CREATE DATABASE GetDBDDLPluginName() string - - FindKeyspace(ks string) bool } //SessionActions gives primitives ability to interact with the session state diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index b8241f9b513..742b24bcd8c 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -698,10 +698,6 @@ func (vc *vcursorImpl) GetDBDDLPluginName() string { return *dbDDLPlugin } -func (vc *vcursorImpl) FindKeyspace(ks string) bool { - return vc.KeyspaceExists(ks) -} - // ParseDestinationTarget parses destination target string and sets default keyspace if possible. func parseDestinationTarget(targetString string, vschema *vindexes.VSchema) (string, topodatapb.TabletType, key.Destination, error) { destKeyspace, destTabletType, dest, err := topoprotopb.ParseDestination(targetString, defaultTabletType) From e762d58b006c4c4a6d89a757cfc2ab6ad23bfa77 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 11 Mar 2021 07:11:52 +0100 Subject: [PATCH 22/23] make sure to not return error when things worked Signed-off-by: Andres Taylor --- go/vt/vtgate/engine/dbddl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index 405a064422b..e5f16af1735 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -182,7 +182,7 @@ func (c *DBDDL) dropDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.Res case <-time.After(500 * time.Millisecond): //timeout } } - return &sqltypes.Result{StatusFlags: sqltypes.ServerStatusDbDropped}, err + return &sqltypes.Result{StatusFlags: sqltypes.ServerStatusDbDropped}, nil } // StreamExecute implements the Primitive interface From 6a7f295fd393e6c5afd1c08321fa951117b3581e Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 11 Mar 2021 17:29:49 +0530 Subject: [PATCH 23/23] watch vschema in drop database to confirm that the keyspace is no longer available to be served Signed-off-by: Harshit Gangal --- .../vtgate/createdb_plugin/main_test.go | 96 +++++++++++++------ go/vt/vtgate/engine/dbddl.go | 15 +-- go/vt/vtgate/engine/dbddl_test.go | 19 ++-- go/vt/vtgate/engine/fake_vcursor_test.go | 9 ++ go/vt/vtgate/engine/primitive.go | 3 + go/vt/vtgate/vcursor_impl.go | 8 ++ 6 files changed, 100 insertions(+), 50 deletions(-) diff --git a/go/test/endtoend/vtgate/createdb_plugin/main_test.go b/go/test/endtoend/vtgate/createdb_plugin/main_test.go index 93b678b368e..bf1677f7330 100644 --- a/go/test/endtoend/vtgate/createdb_plugin/main_test.go +++ b/go/test/endtoend/vtgate/createdb_plugin/main_test.go @@ -25,6 +25,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" @@ -90,37 +92,47 @@ func TestDBDDLPlugin(t *testing.T) { require.NoError(t, err) defer conn.Close() - wg := sync.WaitGroup{} - wg.Add(1) - go func() { - defer wg.Done() - qr := exec(t, conn, `create database aaa`) - require.EqualValues(t, 1, qr.RowsAffected) - }() - time.Sleep(300 * time.Millisecond) - start(t, "aaa") - - // wait until the create database query has returned - wg.Wait() - - exec(t, conn, `use aaa`) - exec(t, conn, `create table t (id bigint primary key)`) - exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`) - assertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`) - - wg.Add(1) - go func() { - defer wg.Done() - _ = exec(t, conn, `drop database aaa`) - }() - time.Sleep(300 * time.Millisecond) - shutdown(t, "aaa") - - // wait until the drop database query has returned - wg.Wait() - - _, err = conn.ExecuteFetch(`select count(*) from t`, 1000, true) - require.Error(t, err) + createAndDrop := func(t *testing.T) { + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + qr := exec(t, conn, `create database aaa`) + require.EqualValues(t, 1, qr.RowsAffected) + }() + time.Sleep(300 * time.Millisecond) + start(t, "aaa") + + // wait until the create database query has returned + wg.Wait() + + exec(t, conn, `use aaa`) + exec(t, conn, `create table t (id bigint primary key)`) + exec(t, conn, `insert into t(id) values (1),(2),(3),(4),(5)`) + assertMatches(t, conn, "select count(*) from t", `[[INT64(5)]]`) + + wg.Add(1) + go func() { + defer wg.Done() + _ = exec(t, conn, `drop database aaa`) + }() + time.Sleep(300 * time.Millisecond) + shutdown(t, "aaa") + + // wait until the drop database query has returned + wg.Wait() + + _, err = conn.ExecuteFetch(`select count(*) from t`, 1000, true) + require.Error(t, err) + } + t.Run("first try", func(t *testing.T) { + createAndDrop(t) + }) + if !t.Failed() { + t.Run("second try", func(t *testing.T) { + createAndDrop(t) + }) + } } func start(t *testing.T, ksName string) { @@ -133,8 +145,30 @@ func start(t *testing.T, ksName string) { } func shutdown(t *testing.T, ksName string) { + for _, ks := range clusterInstance.Keyspaces { + if ks.Name != ksName { + continue + } + for _, shard := range ks.Shards { + for _, tablet := range shard.Vttablets { + if tablet.MysqlctlProcess.TabletUID > 0 { + _, err := tablet.MysqlctlProcess.StopProcess() + assert.NoError(t, err) + } + if tablet.MysqlctldProcess.TabletUID > 0 { + err := tablet.MysqlctldProcess.Stop() + assert.NoError(t, err) + } + _ = tablet.VttabletProcess.TearDown() + } + } + } + require.NoError(t, clusterInstance.VtctlclientProcess.ExecuteCommand("DeleteKeyspace", "-recursive", ksName)) + + require.NoError(t, + clusterInstance.VtctlclientProcess.ExecuteCommand("RebuildVSchemaGraph")) } func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { diff --git a/go/vt/vtgate/engine/dbddl.go b/go/vt/vtgate/engine/dbddl.go index e5f16af1735..f06c8150c2b 100644 --- a/go/vt/vtgate/engine/dbddl.go +++ b/go/vt/vtgate/engine/dbddl.go @@ -129,7 +129,7 @@ func (c *DBDDL) createDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.R } select { case <-ctx.Done(): //context cancelled - return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate create database: destination not resolved") case <-time.After(500 * time.Millisecond): //timeout } } @@ -150,7 +150,7 @@ func (c *DBDDL) createDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.R noErr = false select { case <-ctx.Done(): //context cancelled - return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate created database") + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate create database: tablets not healthy") case <-time.After(500 * time.Millisecond): //timeout } break @@ -169,19 +169,14 @@ func (c *DBDDL) dropDatabase(vcursor VCursor, plugin DBDDLPlugin) (*sqltypes.Res if err != nil { return nil, err } - for { - // loop until we do not find the keyspace to resolve. - _, _, err = vcursor.ResolveDestinations(c.name, nil, []key.Destination{}) - if err != nil && strings.Contains(err.Error(), "node doesn't exist") { - break - } - + for vcursor.KeyspaceAvailable(c.name) { select { case <-ctx.Done(): //context cancelled - return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate drop database") + return nil, vterrors.Errorf(vtrpc.Code_DEADLINE_EXCEEDED, "could not validate drop database: keyspace still available in vschema") case <-time.After(500 * time.Millisecond): //timeout } } + return &sqltypes.Result{StatusFlags: sqltypes.ServerStatusDbDropped}, nil } diff --git a/go/vt/vtgate/engine/dbddl_test.go b/go/vt/vtgate/engine/dbddl_test.go index 52d3bb1f215..dac22baeeb1 100644 --- a/go/vt/vtgate/engine/dbddl_test.go +++ b/go/vt/vtgate/engine/dbddl_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) @@ -57,7 +59,7 @@ func TestDBDDLDropExecute(t *testing.T) { primitive := &DBDDL{name: "ks"} - vc := &loggingVCursor{dbDDLPlugin: pluginName} + vc := &loggingVCursor{dbDDLPlugin: pluginName, ksAvailable: false} _, err := primitive.Execute(vc, nil, false) require.NoError(t, err) @@ -70,14 +72,13 @@ func TestDBDDLTimeout(t *testing.T) { plugin := &dbddlTestFake{sleep: 2} DBDDLRegister(pluginName, plugin) - primitive := &DBDDL{ - name: "ks", - create: true, - queryTimeout: 100, - } - + primitive := &DBDDL{name: "ks", create: true, queryTimeout: 100} vc := &loggingVCursor{dbDDLPlugin: pluginName, shardErr: fmt.Errorf("db not available")} - _, err := primitive.Execute(vc, nil, false) - require.EqualError(t, err, "could not validate created database") + assert.EqualError(t, err, "could not validate create database: destination not resolved") + + primitive = &DBDDL{name: "ks", queryTimeout: 100} + vc = &loggingVCursor{dbDDLPlugin: pluginName, ksAvailable: true} + _, err = primitive.Execute(vc, nil, false) + assert.EqualError(t, err, "could not validate drop database: keyspace still available in vschema") } diff --git a/go/vt/vtgate/engine/fake_vcursor_test.go b/go/vt/vtgate/engine/fake_vcursor_test.go index 424438b15f4..bccb8394813 100644 --- a/go/vt/vtgate/engine/fake_vcursor_test.go +++ b/go/vt/vtgate/engine/fake_vcursor_test.go @@ -57,6 +57,10 @@ type noopVCursor struct { ctx context.Context } +func (t *noopVCursor) KeyspaceAvailable(ks string) bool { + panic("implement me") +} + func (t *noopVCursor) SetDDLStrategy(strategy string) { panic("implement me") } @@ -270,12 +274,17 @@ type loggingVCursor struct { tableRoutes tableRoutes dbDDLPlugin string + ksAvailable bool } type tableRoutes struct { tbl *vindexes.Table } +func (f *loggingVCursor) KeyspaceAvailable(ks string) bool { + return f.ksAvailable +} + func (f *loggingVCursor) SetFoundRows(u uint64) { panic("implement me") } diff --git a/go/vt/vtgate/engine/primitive.go b/go/vt/vtgate/engine/primitive.go index f77449847d3..f07e24028c9 100644 --- a/go/vt/vtgate/engine/primitive.go +++ b/go/vt/vtgate/engine/primitive.go @@ -101,6 +101,9 @@ type ( // GetDBDDLPlugin gets the configured plugin for DROP/CREATE DATABASE GetDBDDLPluginName() string + + // KeyspaceAvailable returns true when a keyspace is visible from vtgate + KeyspaceAvailable(ks string) bool } //SessionActions gives primitives ability to interact with the session state diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 742b24bcd8c..942e3bc792e 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -70,6 +70,7 @@ type iExecute interface { // TODO: remove when resolver is gone ParseDestinationTarget(targetString string) (string, topodatapb.TabletType, key.Destination, error) + VSchema() *vindexes.VSchema } //VSchemaOperator is an interface to Vschema Operations @@ -694,10 +695,17 @@ func (vc *vcursorImpl) HasCreatedTempTable() { vc.safeSession.GetOrCreateOptions().HasCreatedTempTables = true } +// GetDBDDLPluginName implements the VCursor interface func (vc *vcursorImpl) GetDBDDLPluginName() string { return *dbDDLPlugin } +// KeyspaceAvailable implements the VCursor interface +func (vc *vcursorImpl) KeyspaceAvailable(ks string) bool { + _, exists := vc.executor.VSchema().Keyspaces[ks] + return exists +} + // ParseDestinationTarget parses destination target string and sets default keyspace if possible. func parseDestinationTarget(targetString string, vschema *vindexes.VSchema) (string, topodatapb.TabletType, key.Destination, error) { destKeyspace, destTabletType, dest, err := topoprotopb.ParseDestination(targetString, defaultTabletType)