From fb968416d71ed4a335862ffae3a336a175152f57 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Mon, 28 Sep 2020 07:25:59 +0300 Subject: [PATCH 001/310] 8_0_0 Release Notes Signed-off-by: Alkin Tezuysal --- doc/releasenotes/8_0_0_release_notes.md | 45 +++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 doc/releasenotes/8_0_0_release_notes.md diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md new file mode 100644 index 00000000000..18790aa803a --- /dev/null +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -0,0 +1,45 @@ +## Incompatible Changes + +*This release includes the following changes which may result in incompatibilities when upgrading from a previous release*. *It is important that Vitess components are* _[upgraded in the recommended order](https://vitess.io/docs/user-guides/upgrading/#upgrade-order)_. *This will change in the next release as documented in* *[VEP-3](https://github.com/vitessio/enhancements/blob/master/veps/vep-3.md).* + +## Deprecations + +## Bugs Fixed + +* set workload = 'olap'; can not repeat, but set workload = 'oltp' can; #4086 +* Fix where clause in information schema with correct database name #6599 + + +### VTGate / MySQL compatibility + + +## Functionality Added or Changed + +* Emergency Reparent Refactor #6449 + * Make emergency reparents more robust. #6206 +* vttablet: create database if not present #6490 + +### VReplication + +* VReplication: _vt.vreplication source column VARBINARY->BLOB #6421 + +### Point-in-time Recovery + +### Healthcheck + +### Examples / Tutorials + +## Documentation + +## Build Environment Changes + +## Functionality Neutral Changes + +* SET planning #6487 +* Settings tweak backport #6488 +* Add more system settings #6486 + +### Other + +* add skip flag that can skip comparing source & destination schema when run splitdiff #6477 +* [java] bump java version to 8.0.0-SNAPSHOT for next release #6478 From dcc63753525e5dc797312dea12422d53ad5054f3 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 8 Oct 2020 07:46:28 +0300 Subject: [PATCH 002/310] online-DDL: migration uses low priority throttling Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/executor.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 1d6b3406a21..f8483dea36e 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -467,7 +467,7 @@ curl -s 'http://localhost:%d/schema-migration/report-status?uuid=%s&status=%s&dr fmt.Sprintf("--serve-socket-file=%s", serveSocketFile), fmt.Sprintf("--hooks-path=%s", tempDir), fmt.Sprintf(`--hooks-hint-token=%s`, onlineDDL.UUID), - fmt.Sprintf(`--throttle-http=http://localhost:%d/throttler/check`, *servenv.Port), + fmt.Sprintf(`--throttle-http=http://localhost:%d/throttler/check?p=low`, *servenv.Port), fmt.Sprintf(`--database=%s`, e.dbName), fmt.Sprintf(`--table=%s`, onlineDDL.Table), fmt.Sprintf(`--alter=%s`, alterOptions), @@ -601,7 +601,7 @@ export MYSQL_PWD my ($self, %args) = @_; return sub { - if (head("http://localhost:{{VTTABLET_PORT}}/throttler/check")) { + if (head("http://localhost:{{VTTABLET_PORT}}/throttler/check?p=low")) { # Got HTTP 200 OK, means throttler is happy return 0; } else { From c6a7b27e51375cc99718ef33f0ac382860826189 Mon Sep 17 00:00:00 2001 From: deepthi Date: Mon, 12 Oct 2020 15:13:22 -0700 Subject: [PATCH 003/310] download zookeeper 3.4.14 from archive site Signed-off-by: deepthi --- bootstrap.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap.sh b/bootstrap.sh index a2f7891dd0b..c539809bc8e 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -119,7 +119,7 @@ function install_zookeeper() { local dist="$2" zk="zookeeper-$version" - wget "https://apache.org/dist/zookeeper/$zk/$zk.tar.gz" + wget "https://archive.apache.org/dist/zookeeper/$zk/$zk.tar.gz" tar -xzf "$zk.tar.gz" ant -f "$zk/build.xml" package ant -f "$zk/zookeeper-contrib/zookeeper-contrib-fatjar/build.xml" jar From 7aa7c4b56bf819b76226f29adb80c46dc400b2be Mon Sep 17 00:00:00 2001 From: deepthi Date: Sat, 10 Oct 2020 11:25:57 -0700 Subject: [PATCH 004/310] healthcheck: should receive healthcheck updates from all tablets in cells_to_watch Signed-off-by: deepthi --- go/vt/discovery/healthcheck.go | 29 +++--- go/vt/discovery/healthcheck_test.go | 149 ++++++++++++++++++++++------ 2 files changed, 132 insertions(+), 46 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 67f1199b548..c9ce887067d 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -313,10 +313,6 @@ func NewHealthCheck(ctx context.Context, retryDelay, healthCheckTimeout time.Dur // It does not block on making connection. // name is an optional tag for the tablet, e.g. an alternative address. func (hc *HealthCheckImpl) AddTablet(tablet *topodata.Tablet) { - // check whether we should really add this tablet - if !hc.isIncluded(tablet) { - return - } // check whether grpc port is present on tablet, if not return if tablet.PortMap["grpc"] == 0 { return @@ -368,9 +364,6 @@ func (hc *HealthCheckImpl) AddTablet(tablet *topodata.Tablet) { // RemoveTablet removes the tablet, and stops the health check. // It does not block. func (hc *HealthCheckImpl) RemoveTablet(tablet *topodata.Tablet) { - if !hc.isIncluded(tablet) { - return - } hc.deleteTablet(tablet) } @@ -453,7 +446,10 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, shr *query.StreamHealt all := hc.healthData[targetKey] allArray := make([]*TabletHealth, 0, len(all)) for _, s := range all { - allArray = append(allArray, s) + // only tablets in same cell / cellAlias are included in healthy list + if hc.isIncluded(shr) { + allArray = append(allArray, s) + } } hc.healthy[targetKey] = FilterStatsByReplicationLag(allArray) } @@ -462,7 +458,10 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, shr *query.StreamHealt all := hc.healthData[oldTargetKey] allArray := make([]*TabletHealth, 0, len(all)) for _, s := range all { - allArray = append(allArray, s) + // only tablets in same cell / cellAlias are included in healthy list + if hc.isIncluded(shr) { + allArray = append(allArray, s) + } } hc.healthy[oldTargetKey] = FilterStatsByReplicationLag(allArray) } @@ -703,10 +702,8 @@ func (hc *HealthCheckImpl) keyFromTablet(tablet *topodata.Tablet) keyspaceShardT return keyspaceShardTabletType(fmt.Sprintf("%s.%s.%s", tablet.Keyspace, tablet.Shard, topoproto.TabletTypeLString(tablet.Type))) } +// getAliasByCell should only be called while holding hc.mu func (hc *HealthCheckImpl) getAliasByCell(cell string) string { - hc.mu.Lock() - defer hc.mu.Unlock() - if alias, ok := hc.cellAliases[cell]; ok { return alias } @@ -719,14 +716,14 @@ func (hc *HealthCheckImpl) getAliasByCell(cell string) string { return alias } -func (hc *HealthCheckImpl) isIncluded(tablet *topodata.Tablet) bool { - if tablet.Type == topodata.TabletType_MASTER { +func (hc *HealthCheckImpl) isIncluded(shr *query.StreamHealthResponse) bool { + if shr.Target.TabletType == topodata.TabletType_MASTER { return true } - if tablet.Alias.Cell == hc.cell { + if shr.TabletAlias.Cell == hc.cell { return true } - if hc.getAliasByCell(tablet.Alias.Cell) == hc.getAliasByCell(hc.cell) { + if hc.getAliasByCell(shr.TabletAlias.Cell) == hc.getAliasByCell(hc.cell) { return true } return false diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index a4b2483d47a..d32b943cff9 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -701,31 +701,77 @@ func TestGetHealthyTablets(t *testing.T) { mustMatch(t, want, a, "unexpected result") } -func TestAliases(t *testing.T) { - ts := memorytopo.NewServer("cell", "cell1", "cell2") - hc := createTestHc(ts) +func TestMasterInOtherCell(t *testing.T) { + ts := memorytopo.NewServer("cell1", "cell2") + hc := NewHealthCheck(context.Background(), 1*time.Millisecond, time.Hour, ts, "cell1", "cell1, cell2") defer hc.Close() - cellsAlias := &topodatapb.CellsAlias{ - Cells: []string{"cell", "cell1"}, + // add a tablet as master in different cell + tablet := createTestTablet(1, "cell2", "host1") + tablet.Type = topodatapb.TabletType_MASTER + input := make(chan *querypb.StreamHealthResponse) + fc := createFakeConn(tablet, input) + // create a channel and subscribe to healthcheck + resultChan := hc.Subscribe() + hc.AddTablet(tablet) + // should get a result, but this will hang if multi-cell logic is broken + // so wait and timeout + ticker := time.NewTicker(1 * time.Second) + select { + case err := <-fc.cbErrCh: + require.Fail(t, "Unexpected error: %v", err) + case <-resultChan: + case <-ticker.C: + require.Fail(t, "Timed out waiting for HealthCheck update") } - assert.Nil(t, ts.CreateCellsAlias(context.Background(), "region1", cellsAlias), "failed to create cell alias") - defer ts.DeleteCellsAlias(context.Background(), "region1") - cellsAlias = &topodatapb.CellsAlias{ - Cells: []string{"cell2"}, + + shr := &querypb.StreamHealthResponse{ + TabletAlias: tablet.Alias, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + TabletExternallyReparentedTimestamp: 20, + RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 0, CpuUsage: 0.2}, + } + want := &TabletHealth{ + Tablet: tablet, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 0, CpuUsage: 0.2}, + MasterTermStartTime: 20, } - assert.Nil(t, ts.CreateCellsAlias(context.Background(), "region2", cellsAlias), "failed to create cell alias") - defer ts.DeleteCellsAlias(context.Background(), "region2") - // add a tablet as replica in diff cell, same region - tablet := createTestTablet(1, "cell1", "host3") + input <- shr + ticker = time.NewTicker(1 * time.Second) + select { + case err := <-fc.cbErrCh: + require.Fail(t, "Unexpected error: %v", err) + case got := <-resultChan: + // check that we DO receive health check update for MASTER in other cell + mustMatch(t, want, got, "Wrong TabletHealth data") + case <-ticker.C: + require.Fail(t, "Timed out waiting for HealthCheck update") + } + + // check that MASTER tablet from other cell IS in healthy tablet list + a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}) + assert.Len(t, a, 1, "") + mustMatch(t, want, a[0], "Expecting healthy master") +} + +func TestReplicaInOtherCell(t *testing.T) { + ts := memorytopo.NewServer("cell1", "cell2") + hc := NewHealthCheck(context.Background(), 1*time.Millisecond, time.Hour, ts, "cell1", "cell1, cell2") + defer hc.Close() + + // add a tablet as replica in different cell + tablet := createTestTablet(1, "cell2", "host1") tablet.Type = topodatapb.TabletType_REPLICA input := make(chan *querypb.StreamHealthResponse) fc := createFakeConn(tablet, input) // create a channel and subscribe to healthcheck resultChan := hc.Subscribe() hc.AddTablet(tablet) - // should get a result, but this will hang if cell alias logic is broken + // should get a result, but this will hang if multi-cell logic is broken // so wait and timeout ticker := time.NewTicker(1 * time.Second) select { @@ -743,46 +789,89 @@ func TestAliases(t *testing.T) { TabletExternallyReparentedTimestamp: 0, RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 10, CpuUsage: 0.2}, } - want := []*TabletHealth{{ + want := &TabletHealth{ Tablet: tablet, Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}, Serving: true, Stats: &querypb.RealtimeStats{SecondsBehindMaster: 10, CpuUsage: 0.2}, MasterTermStartTime: 0, - }} + } input <- shr ticker = time.NewTicker(1 * time.Second) select { case err := <-fc.cbErrCh: require.Fail(t, "Unexpected error: %v", err) - case <-resultChan: + case got := <-resultChan: + // check that we DO receive health check update for REPLICA in other cell + mustMatch(t, want, got, "Wrong TabletHealth data") case <-ticker.C: require.Fail(t, "Timed out waiting for HealthCheck update") } - // check it's there + // check that REPLICA tablet from other cell is NOT in healthy tablet list a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}) - mustMatch(t, want, a, "Wrong TabletHealth data") + assert.Empty(t, a) - // add another tablet in a diff cell, diff region - tablet2 := createTestTablet(2, "cell2", "host4") - tablet2.Type = topodatapb.TabletType_REPLICA - input2 := make(chan *querypb.StreamHealthResponse) - fc = createFakeConn(tablet2, input2) - hc.AddTablet(tablet2) - // we should NOT get a result because this tablet is not of interest to us +} + +func TestCellAliases(t *testing.T) { + ts := memorytopo.NewServer("cell1", "cell2") + hc := NewHealthCheck(context.Background(), 1*time.Millisecond, time.Hour, ts, "cell1", "cell1, cell2") + defer hc.Close() + + cellsAlias := &topodatapb.CellsAlias{ + Cells: []string{"cell1", "cell2"}, + } + assert.Nil(t, ts.CreateCellsAlias(context.Background(), "region1", cellsAlias), "failed to create cell alias") + defer ts.DeleteCellsAlias(context.Background(), "region1") + + // add a tablet as replica in diff cell, same region + tablet := createTestTablet(1, "cell2", "host2") + tablet.Type = topodatapb.TabletType_REPLICA + input := make(chan *querypb.StreamHealthResponse) + fc := createFakeConn(tablet, input) + // create a channel and subscribe to healthcheck + resultChan := hc.Subscribe() + hc.AddTablet(tablet) + // should get a result, but this will hang if cell alias logic is broken + // so wait and timeout + ticker := time.NewTicker(1 * time.Second) + select { + case err := <-fc.cbErrCh: + require.Fail(t, "Unexpected error: %v", err) + case <-resultChan: + case <-ticker.C: + require.Fail(t, "Timed out waiting for HealthCheck update") + } + + shr := &querypb.StreamHealthResponse{ + TabletAlias: tablet.Alias, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}, + Serving: true, + TabletExternallyReparentedTimestamp: 0, + RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 10, CpuUsage: 0.2}, + } + want := []*TabletHealth{{ + Tablet: tablet, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}, + Serving: true, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 10, CpuUsage: 0.2}, + MasterTermStartTime: 0, + }} + + input <- shr ticker = time.NewTicker(1 * time.Second) select { case err := <-fc.cbErrCh: require.Fail(t, "Unexpected error: %v", err) - case result := <-resultChan: - require.Fail(t, "Unexpected result: %v", result) + case <-resultChan: case <-ticker.C: + require.Fail(t, "Timed out waiting for HealthCheck update") } - // check that we still have only tablet in healthy list - a = hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}) + // check it's there + a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}) mustMatch(t, want, a, "Wrong TabletHealth data") } From d8a64d92ea46af48055f918fc571151eef89d15c Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 14 Oct 2020 17:45:39 +0200 Subject: [PATCH 005/310] No need to fail the whole query here Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/select.go | 7 ++++++- .../vtgate/planbuilder/testdata/from_cases.txt | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go index 24e72e731f0..496c06d1e2b 100644 --- a/go/vt/vtgate/planbuilder/select.go +++ b/go/vt/vtgate/planbuilder/select.go @@ -332,12 +332,17 @@ func (r *rewriter) rewriteTableSchema(cursor *sqlparser.Cursor) bool { switch parent := cursor.Parent().(type) { case *sqlparser.ComparisonExpr: if parent.Operator == sqlparser.EqualOp && shouldRewrite(parent.Right) { - evalExpr, err := sqlparser.Convert(parent.Right) if err != nil { + if err == sqlparser.ErrExprNotSupported { + // This just means we can't rewrite this particular expression, + // not that we have to exit altogether + return true + } r.err = err return false } + r.tableNameExpressions = append(r.tableNameExpressions, evalExpr) parent.Right = sqlparser.NewArgument([]byte(":" + sqltypes.BvSchemaName)) } diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.txt b/go/vt/vtgate/planbuilder/testdata/from_cases.txt index bdf90d1151b..0a76fe74543 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.txt @@ -2115,3 +2115,20 @@ # non-existent table on right of join "select c from user join t" "table t not found" + +# information schema query that uses table_schema +"select column_name from information_schema.columns where table_schema = (select schema())" +{ + "QueryType": "SELECT", + "Original": "select column_name from information_schema.columns where table_schema = (select schema())", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select column_name from information_schema.`columns` where 1 != 1", + "Query": "select column_name from information_schema.`columns` where table_schema = (select schema() from dual)" + } +} From 916754e260f1d3a0055377bd0f94e34b30702466 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 12 Oct 2020 15:51:24 +0200 Subject: [PATCH 006/310] disable reserved connections by default Signed-off-by: Andres Taylor --- go/vt/vtgate/vtgate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index f3287900d37..d644ffba39e 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -71,7 +71,7 @@ var ( warnPayloadSize = flag.Int("warn_payload_size", 0, "The warning threshold for query payloads in bytes. A payload greater than this threshold will cause the VtGateWarnings.WarnPayloadSizeExceeded counter to be incremented.") // Put set-passthrough under a flag. - sysVarSetEnabled = flag.Bool("enable_system_settings", true, "This will enable the system settings to be changed per session at the database connection level") + sysVarSetEnabled = flag.Bool("enable_system_settings", false, "This will enable the system settings to be changed per session at the database connection level") // lockHeartbeatTime is used to set the next heartbeat time. lockHeartbeatTime = flag.Duration("lock_heartbeat_time", 5*time.Second, "If there is lock function used. This will keep the lock connection active by using this heartbeat") ) From 4a939c5f6f4affdf79f4712d712bf2d155759be8 Mon Sep 17 00:00:00 2001 From: Guido Iaquinti Date: Thu, 15 Oct 2020 19:30:00 +0200 Subject: [PATCH 007/310] Docker - upgrade to Debian Buster Signed-off-by: Guido Iaquinti --- docker/bootstrap/Dockerfile.common | 23 +++++------------------ docker/bootstrap/Dockerfile.mariadb | 2 +- docker/bootstrap/Dockerfile.mariadb103 | 2 +- docker/bootstrap/Dockerfile.mysql56 | 8 +++++++- docker/bootstrap/Dockerfile.mysql57 | 4 ++-- docker/bootstrap/Dockerfile.mysql80 | 4 ++-- docker/bootstrap/Dockerfile.percona | 14 +++++++++++++- docker/bootstrap/Dockerfile.percona57 | 4 ++-- docker/bootstrap/Dockerfile.percona80 | 4 ++-- docker/lite/Dockerfile.mariadb | 2 +- docker/lite/Dockerfile.mariadb103 | 2 +- docker/lite/Dockerfile.mysql56 | 2 +- docker/lite/Dockerfile.mysql57 | 2 +- docker/lite/Dockerfile.mysql80 | 2 +- docker/lite/Dockerfile.percona | 2 +- docker/lite/Dockerfile.percona57 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/lite/Dockerfile.testing | 2 +- docker/lite/install_dependencies.sh | 16 ++++++++-------- docker/orchestrator/build.sh | 2 +- 20 files changed, 53 insertions(+), 48 deletions(-) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 92ca899f712..54402e358ef 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,35 +1,22 @@ -FROM golang:1.13-stretch +FROM golang:1.13-buster # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ # TODO(mberlin): Group these to make it easier to understand which library actually requires them. - automake \ - bison \ - bzip2 \ + ant \ chromium \ curl \ + default-jdk \ + etcd \ g++ \ git \ - libgconf-2-4 \ - libtool \ make \ - openjdk-8-jdk \ + maven \ software-properties-common \ - virtualenv \ unzip \ - xvfb \ zip \ - libz-dev \ - ant \ && rm -rf /var/lib/apt/lists/* -# Install Maven 3.1+ -RUN mkdir -p /vt/src/vitess.io/vitess/dist && \ - cd /vt/src/vitess.io/vitess/dist && \ - curl -sL --connect-timeout 10 --retry 3 \ - http://www-us.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz | tar -xz && \ - mv apache-maven-3.3.9 maven - # Set up Vitess environment (equivalent to '. dev.env') ENV VTROOT /vt/src/vitess.io/vitess ENV VTDATAROOT /vt/vtdataroot diff --git a/docker/bootstrap/Dockerfile.mariadb b/docker/bootstrap/Dockerfile.mariadb index 19d5c9973d0..90d9dd1e201 100644 --- a/docker/bootstrap/Dockerfile.mariadb +++ b/docker/bootstrap/Dockerfile.mariadb @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install MariaDB 10 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ + add-apt-repository 'deb http://repo.percona.com/apt buster main' && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mariadb103 b/docker/bootstrap/Dockerfile.mariadb103 index c2828ddd25d..5d15356f419 100644 --- a/docker/bootstrap/Dockerfile.mariadb103 +++ b/docker/bootstrap/Dockerfile.mariadb103 @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install MariaDB 10.3 RUN apt-key adv --no-tty --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8 \ - && add-apt-repository 'deb [arch=amd64] http://ftp.osuosl.org/pub/mariadb/repo/10.3/debian stretch main' \ + && add-apt-repository 'deb [arch=amd64] http://ftp.osuosl.org/pub/mariadb/repo/10.3/debian buster main' \ && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ mariadb-server-10.3 \ libmariadb-dev \ diff --git a/docker/bootstrap/Dockerfile.mysql56 b/docker/bootstrap/Dockerfile.mysql56 index 0cdb5ae84f2..46ee7b8553a 100644 --- a/docker/bootstrap/Dockerfile.mysql56 +++ b/docker/bootstrap/Dockerfile.mysql56 @@ -1,10 +1,16 @@ FROM vitess/bootstrap:common # Install MySQL 5.6 +# +# Unfortunately we need to keep the 'stretch' repo from Oracle as there's no official support +# for MySQL 5.6 for Debian Buster: https://bugs.mysql.com/bug.php?id=101055 +# +# I think it's fine as MySQL 5.6 will be EOL pretty soon (February 5, 2021) +# RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6' && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.6 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mysql57 b/docker/bootstrap/Dockerfile.mysql57 index 7e0c5f99f96..4889e74f4e1 100644 --- a/docker/bootstrap/Dockerfile.mysql57 +++ b/docker/bootstrap/Dockerfile.mysql57 @@ -3,9 +3,9 @@ FROM vitess/bootstrap:common # Install MySQL 5.7 RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gnupg dirmngr ca-certificates && \ for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver ha.pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ - add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.7' && \ + add-apt-repository 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.7' && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mysql80 b/docker/bootstrap/Dockerfile.mysql80 index 0523a7847cc..543453e911a 100644 --- a/docker/bootstrap/Dockerfile.mysql80 +++ b/docker/bootstrap/Dockerfile.mysql80 @@ -2,9 +2,9 @@ FROM vitess/bootstrap:common # Install MySQL 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver ha.pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ - add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-8.0' && \ + add-apt-repository 'deb http://repo.mysql.com/apt/debian/ buster mysql-8.0' && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.percona b/docker/bootstrap/Dockerfile.percona index 910d3be10b1..d2666c6b137 100644 --- a/docker/bootstrap/Dockerfile.percona +++ b/docker/bootstrap/Dockerfile.percona @@ -1,8 +1,19 @@ FROM vitess/bootstrap:common # Install Percona 5.6 +# +# Unfortunately we need to keep the 'stretch' repo from Percona as there's no official support +# for MySQL 5.6 for Debian Buster +# +# I think it's fine as MySQL 5.6 will be EOL pretty soon (February 5, 2021) +# +# Also, for the 'percona-xtrabackup-24' package we need to specificly target the +# 'buster' repository as the 'stretch' package requires 'libcurl3' that is not present +# in Debian Buster. +# RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ + add-apt-repository 'deb http://repo.percona.com/apt buster main' && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.6 percona-server-server/root_password password 'unused'; \ @@ -10,7 +21,8 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r } | debconf-set-selections && \ apt-get update && \ apt-get install -y --no-install-recommends \ - percona-server-server-5.6 libperconaserverclient18.1-dev rsync libev4 percona-xtrabackup-24 && \ + percona-server-server-5.6 libperconaserverclient18.1-dev rsync libev4 && \ + apt-get install -y -t buster percona-xtrabackup-24 && \ rm -rf /var/lib/apt/lists/* # Bootstrap Vitess diff --git a/docker/bootstrap/Dockerfile.percona57 b/docker/bootstrap/Dockerfile.percona57 index 54c8477ffb6..4bac477d764 100644 --- a/docker/bootstrap/Dockerfile.percona57 +++ b/docker/bootstrap/Dockerfile.percona57 @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install Percona 5.7 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ + add-apt-repository 'deb http://repo.percona.com/apt buster main' && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ @@ -11,7 +11,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r apt-get update && \ apt-get install -y --no-install-recommends \ percona-server-server-5.7 \ - libperconaserverclient18.1-dev percona-xtrabackup-24 && \ + libperconaserverclient20-dev percona-xtrabackup-24 && \ rm -rf /var/lib/apt/lists/* # Bootstrap Vitess diff --git a/docker/bootstrap/Dockerfile.percona80 b/docker/bootstrap/Dockerfile.percona80 index 1ce9c52103f..d649416a6b6 100644 --- a/docker/bootstrap/Dockerfile.percona80 +++ b/docker/bootstrap/Dockerfile.percona80 @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install Percona 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done \ - && echo 'deb http://repo.percona.com/ps-80/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ + && echo 'deb http://repo.percona.com/ps-80/apt buster main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ @@ -19,7 +19,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r rsync \ libev4 \ # && rm -f /etc/apt/sources.list.d/percona.list \ - && echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list \ + && echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list \ # { \ # echo debconf debconf/frontend select Noninteractive; \ # echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ diff --git a/docker/lite/Dockerfile.mariadb b/docker/lite/Dockerfile.mariadb index 2299fa0866f..1617d899fe2 100644 --- a/docker/lite/Dockerfile.mariadb +++ b/docker/lite/Dockerfile.mariadb @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mariadb103 b/docker/lite/Dockerfile.mariadb103 index 825035a66a6..079ab6ff4a7 100644 --- a/docker/lite/Dockerfile.mariadb103 +++ b/docker/lite/Dockerfile.mariadb103 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mysql56 b/docker/lite/Dockerfile.mysql56 index a8d5a76de68..ec361bec520 100644 --- a/docker/lite/Dockerfile.mysql56 +++ b/docker/lite/Dockerfile.mysql56 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mysql57 b/docker/lite/Dockerfile.mysql57 index 11013292b49..5ff2d21514d 100644 --- a/docker/lite/Dockerfile.mysql57 +++ b/docker/lite/Dockerfile.mysql57 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mysql80 b/docker/lite/Dockerfile.mysql80 index 99752bf11b7..c395d24f37a 100644 --- a/docker/lite/Dockerfile.mysql80 +++ b/docker/lite/Dockerfile.mysql80 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.percona b/docker/lite/Dockerfile.percona index b93f0dffe4a..e0c5eac8a78 100644 --- a/docker/lite/Dockerfile.percona +++ b/docker/lite/Dockerfile.percona @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.percona57 b/docker/lite/Dockerfile.percona57 index a1091434a88..e8cc430475c 100644 --- a/docker/lite/Dockerfile.percona57 +++ b/docker/lite/Dockerfile.percona57 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index dfa875a51db..0bb057d6ed2 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.testing b/docker/lite/Dockerfile.testing index 19214800013..523d50e3c77 100644 --- a/docker/lite/Dockerfile.testing +++ b/docker/lite/Dockerfile.testing @@ -30,7 +30,7 @@ USER vitess RUN make install-testing PREFIX=/vt/install # Start over and build the final image. -FROM debian:stretch-slim +FROM debian:buster-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/install_dependencies.sh b/docker/lite/install_dependencies.sh index 61e1451a851..b9a05da3aa5 100755 --- a/docker/lite/install_dependencies.sh +++ b/docker/lite/install_dependencies.sh @@ -126,30 +126,30 @@ add_apt_key 9334A25F8507EFA5 # Add extra apt repositories for MySQL. case "${FLAVOR}" in mysql56) - echo 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.6' > /etc/apt/sources.list.d/mysql.list ;; mysql57) - echo 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.7' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list ;; mysql80) - echo 'deb http://repo.mysql.com/apt/debian/ stretch mysql-8.0' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-8.0' > /etc/apt/sources.list.d/mysql.list ;; mariadb) - echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.2/debian stretch main' > /etc/apt/sources.list.d/mariadb.list + echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.2/debian buster main' > /etc/apt/sources.list.d/mariadb.list ;; mariadb103) - echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/debian stretch main' > /etc/apt/sources.list.d/mariadb.list + echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/debian buster main' > /etc/apt/sources.list.d/mariadb.list ;; esac # Add extra apt repositories for Percona Server and/or Percona XtraBackup. case "${FLAVOR}" in mysql56|mysql57|mysql80|percona|percona57) - echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list + echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list ;; percona80) - echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list - echo 'deb http://repo.percona.com/ps-80/apt stretch main' > /etc/apt/sources.list.d/percona80.list + echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list + echo 'deb http://repo.percona.com/ps-80/apt buster main' > /etc/apt/sources.list.d/percona80.list ;; esac diff --git a/docker/orchestrator/build.sh b/docker/orchestrator/build.sh index dbc8dfc464b..933854a664a 100755 --- a/docker/orchestrator/build.sh +++ b/docker/orchestrator/build.sh @@ -23,7 +23,7 @@ script="go get vitess.io/vitess/go/cmd/vtctlclient && \ go install github.com/openark/orchestrator/go/cmd/orchestrator" echo "Building orchestrator..." -docker run -ti --name=vt_orc_build golang:1.14.4-stretch bash -c "$script" +docker run -ti --name=vt_orc_build golang:1.14.4-buster bash -c "$script" docker cp vt_orc_build:/go/bin/orchestrator $tmpdir docker cp vt_orc_build:/go/bin/vtctlclient $tmpdir docker cp vt_orc_build:/go/src/github.com/openark/orchestrator/resources $tmpdir From 61c52420a837d2c71619091a0249efb7bbca1798 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Wed, 14 Oct 2020 19:28:01 +0200 Subject: [PATCH 008/310] Stabilize test The test code was assuming that configuration had not had a chance to be reloaded, but sometimes magnetic red shift lead to this happening. Signed-off-by: Andres Taylor --- go/mysql/auth_server_static_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go/mysql/auth_server_static_test.go b/go/mysql/auth_server_static_test.go index 2586da2f60b..f195b4c72d1 100644 --- a/go/mysql/auth_server_static_test.go +++ b/go/mysql/auth_server_static_test.go @@ -207,10 +207,6 @@ func hupTestWithRotation(t *testing.T, aStatic *AuthServerStatic, tmpFile *os.Fi t.Fatalf("couldn't overwrite temp file: %v", err) } - if aStatic.getEntries()[oldStr][0].Password != oldStr { - t.Fatalf("%s's Password should still be '%s'", oldStr, oldStr) - } - time.Sleep(20 * time.Millisecond) // wait for signal handler if aStatic.getEntries()[oldStr] != nil { From dbd7ab6b1d733f993f65792e4fc20996aa8816a6 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 14 Oct 2020 09:17:07 +0300 Subject: [PATCH 009/310] Fixing flaky tests Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/key/destination.go | 5 +++++ go/vt/key/key.go | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/go/vt/key/destination.go b/go/vt/key/destination.go index 66946504978..235f561c2d7 100644 --- a/go/vt/key/destination.go +++ b/go/vt/key/destination.go @@ -20,6 +20,7 @@ import ( "bytes" "encoding/hex" "math/rand" + "sort" "strings" "vitess.io/vitess/go/vt/vterrors" @@ -149,6 +150,10 @@ func (d DestinationExactKeyRange) String() string { } func processExactKeyRange(allShards []*topodatapb.ShardReference, kr *topodatapb.KeyRange, addShard func(shard string) error) error { + sort.SliceStable(allShards, func(i, j int) bool { + return KeyRangeStartSmaller(allShards[i].GetKeyRange(), allShards[j].GetKeyRange()) + }) + shardnum := 0 for shardnum < len(allShards) { if KeyRangeStartEqual(kr, allShards[shardnum].KeyRange) { diff --git a/go/vt/key/key.go b/go/vt/key/key.go index 0bd7f137a34..98143a1ff13 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -185,6 +185,17 @@ func KeyRangeEqual(left, right *topodatapb.KeyRange) bool { bytes.Equal(left.End, right.End) } +// KeyRangeStartEqual returns true if right's keyrange start is _after_ left's start +func KeyRangeStartSmaller(left, right *topodatapb.KeyRange) bool { + if left == nil { + return right != nil + } + if right == nil { + return false + } + return bytes.Compare(left.Start, right.Start) < 0 +} + // KeyRangeStartEqual returns true if both key ranges have the same start func KeyRangeStartEqual(left, right *topodatapb.KeyRange) bool { if left == nil { From e98892b72ba8cf54e16d928616273100dbc9956c Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Wed, 14 Oct 2020 16:02:41 +0200 Subject: [PATCH 010/310] Attempt to fix flaky TestConnection Signed-off-by: Rohit Nayak --- go/test/endtoend/messaging/message_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/test/endtoend/messaging/message_test.go b/go/test/endtoend/messaging/message_test.go index e5ada917cbf..b93b9c7c5e2 100644 --- a/go/test/endtoend/messaging/message_test.go +++ b/go/test/endtoend/messaging/message_test.go @@ -331,6 +331,7 @@ func TestConnection(t *testing.T) { _, err = stream.MessageStream(userKeyspace, "", nil, name) require.Nil(t, err) // validate client count of vttablet + time.Sleep(time.Second) assert.Equal(t, 1, getClientCount(shard0Master)) assert.Equal(t, 1, getClientCount(shard1Master)) // second connection with vtgate, secont connection @@ -340,6 +341,7 @@ func TestConnection(t *testing.T) { _, err = stream1.MessageStream(userKeyspace, "", nil, name) require.Nil(t, err) // validate client count of vttablet + time.Sleep(time.Second) assert.Equal(t, 2, getClientCount(shard0Master)) assert.Equal(t, 2, getClientCount(shard1Master)) From 6e2bd84dac4c602a4a4da497ccdeb85c39cc8bd9 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 19 Oct 2020 14:34:31 +0300 Subject: [PATCH 011/310] Fix parsing of online-ddl command line options Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/executor.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index f8483dea36e..c1ce21782c5 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -49,6 +49,8 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + + "github.com/google/shlex" ) var ( @@ -474,7 +476,8 @@ curl -s 'http://localhost:%d/schema-migration/report-status?uuid=%s&status=%s&dr fmt.Sprintf(`--panic-flag-file=%s`, e.ghostPanicFlagFileName(onlineDDL.UUID)), fmt.Sprintf(`--execute=%t`, execute), } - args = append(args, strings.Fields(onlineDDL.Options)...) + opts, _ := shlex.Split(onlineDDL.Options) + args = append(args, opts...) _, err := execCmd("bash", args, os.Environ(), "/tmp", nil, nil) return err } @@ -701,7 +704,8 @@ export MYSQL_PWD `--no-drop-old-table`, ) } - args = append(args, strings.Fields(onlineDDL.Options)...) + opts, _ := shlex.Split(onlineDDL.Options) + args = append(args, opts...) _, err = execCmd("bash", args, os.Environ(), "/tmp", nil, nil) return err } From 71f4cfb459d8203382c564b7f8d3c7aad3fbfc2e Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 20 Oct 2020 09:49:39 +0530 Subject: [PATCH 012/310] java: Update version to 8.0.0 for release Signed-off-by: Harshit Gangal --- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/client/pom.xml b/java/client/pom.xml index 69d2bf8b121..69e923603d0 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 8.0.0-SNAPSHOT + 8.0.0 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index da0487e8bf0..73d5e3b76ba 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 8.0.0-SNAPSHOT + 8.0.0 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 0984783dd2a..5760b6e9797 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 8.0.0-SNAPSHOT + 8.0.0 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 8a8126cdcd2..c38d54611f7 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 8.0.0-SNAPSHOT + 8.0.0 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index efa45f90885..5ab01f48964 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 8.0.0-SNAPSHOT + 8.0.0 pom Vitess Java Client libraries [Parent] From e5d1fc96187807c2a6459e9cf7dab3c08f6f0071 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 20 Oct 2020 10:09:52 +0300 Subject: [PATCH 013/310] OnlineDDL bugfix: make sure schema is applied on tablet Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/constants.go | 17 ++++++++++++++ go/vt/vttablet/onlineddl/executor.go | 33 +++++++++++++++++++++++----- go/vt/vttablet/onlineddl/schema.go | 7 ++---- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/go/mysql/constants.go b/go/mysql/constants.go index 50d6bca7f3d..bb9953b8676 100644 --- a/go/mysql/constants.go +++ b/go/mysql/constants.go @@ -579,3 +579,20 @@ func IsConnErr(err error) bool { } return false } + +// IsSchemaApplyError returns true when given error is a MySQL error applying schema change +func IsSchemaApplyError(err error) bool { + merr, isSQLErr := err.(*SQLError) + if !isSQLErr { + return false + } + switch merr.Num { + case + ERDupKeyName, + ERCantDropFieldOrKey, + ERTableExists, + ERDupFieldName: + return true + } + return false +} diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index c1ce21782c5..3eb6bb3f23e 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -32,6 +32,7 @@ import ( "syscall" "time" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/textutil" "vitess.io/vitess/go/timer" @@ -119,8 +120,9 @@ type Executor struct { migrationRunning int64 lastMigrationUUID string - ticks *timer.Timer - isOpen bool + ticks *timer.Timer + isOpen bool + schemaInitialized bool } // GhostBinaryFileName returns the full path+name of the gh-ost binary @@ -167,6 +169,13 @@ func (e *Executor) execQuery(ctx context.Context, query string) (result *sqltype } func (e *Executor) initSchema(ctx context.Context) error { + e.initMutex.Lock() + defer e.initMutex.Unlock() + + if e.schemaInitialized { + return nil + } + defer e.env.LogError() conn, err := e.pool.Get(ctx) @@ -174,9 +183,18 @@ func (e *Executor) initSchema(ctx context.Context) error { return err } defer conn.Recycle() - parsed := sqlparser.BuildParsedQuery(sqlValidationQuery, "_vt") - _, err = withDDL.Exec(ctx, parsed.Query, conn.Exec) - return err + + for _, ddl := range applyDDL { + _, err := conn.Exec(ctx, ddl, math.MaxInt32, false) + if mysql.IsSchemaApplyError(err) { + continue + } + if err != nil { + return err + } + } + e.schemaInitialized = true + return nil } // InitDBConfig initializes keysapce @@ -194,7 +212,6 @@ func (e *Executor) Open() error { return nil } e.pool.Open(e.env.Config().DB.AppWithDB(), e.env.Config().DB.DbaWithDB(), e.env.Config().DB.AppDebugWithDB()) - e.initSchema(context.Background()) e.ticks.Start(e.onMigrationCheckTick) if _, err := sqlparser.QueryMatchesTemplates("select 1 from dual", vexecUpdateTemplates); err != nil { @@ -1140,6 +1157,10 @@ func (e *Executor) onMigrationCheckTick() { } ctx := context.Background() + if err := e.initSchema(ctx); err != nil { + log.Error(err) + return + } if err := e.scheduleNextMigration(ctx); err != nil { log.Error(err) } diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index ef145320ffd..24602cb6b30 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -18,8 +18,6 @@ package onlineddl import ( "fmt" - - "vitess.io/vitess/go/vt/withddl" ) const ( @@ -52,7 +50,6 @@ const ( KEY status_idx (migration_status, liveness_timestamp), KEY cleanup_status_idx (cleanup_timestamp, migration_status) ) engine=InnoDB DEFAULT CHARSET=utf8mb4` - sqlValidationQuery = `select 1 from %s.schema_migrations limit 1` sqlScheduleSingleMigration = `UPDATE %s.schema_migrations SET migration_status='ready', @@ -201,7 +198,7 @@ var ( sqlDropOnlineDDLUser = `DROP USER IF EXISTS %s` ) -var withDDL = withddl.New([]string{ +var applyDDL = []string{ fmt.Sprintf(sqlCreateSidecarDB, "_vt"), fmt.Sprintf(sqlCreateSchemaMigrationsTable, "_vt"), -}) +} From 5eaa7d40a6f1fa87d682acccff79aceecc50e1cc Mon Sep 17 00:00:00 2001 From: deepthi Date: Mon, 19 Oct 2020 17:12:06 -0700 Subject: [PATCH 014/310] healthcheck: use isIncluded correctly to fix replica/rdonly routing bug Signed-off-by: deepthi --- go.mod | 1 + go.sum | 2 ++ go/vt/discovery/healthcheck.go | 19 +++++++++++-------- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/go.mod b/go.mod index 3f20e4a8295..b313293d348 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/golang/protobuf v1.3.2 github.com/golang/snappy v0.0.1 github.com/google/go-cmp v0.4.0 + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.1.1 github.com/googleapis/gnostic v0.2.0 // indirect github.com/gorilla/websocket v1.4.0 diff --git a/go.sum b/go.sum index 017ce039aa5..30a2cd1dc83 100644 --- a/go.sum +++ b/go.sum @@ -257,6 +257,8 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index c9ce887067d..18f1e77bc2e 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -442,24 +442,27 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, shr *query.StreamHealt } } if !trivialNonMasterUpdate { - if shr.Target.TabletType != topodata.TabletType_MASTER { + // we re-sort the healthy tablet list whenever we get a health update for tablets we can route to + // tablets from other cells for non-master targets should not trigger a re-sort + // they should also be excluded from healthy list + if shr.Target.TabletType != topodata.TabletType_MASTER && hc.isIncluded(shr.Target.TabletType, shr.TabletAlias) { all := hc.healthData[targetKey] allArray := make([]*TabletHealth, 0, len(all)) for _, s := range all { // only tablets in same cell / cellAlias are included in healthy list - if hc.isIncluded(shr) { + if hc.isIncluded(s.Tablet.Type, s.Tablet.Alias) { allArray = append(allArray, s) } } hc.healthy[targetKey] = FilterStatsByReplicationLag(allArray) } - if targetChanged && currentTarget.TabletType != topodata.TabletType_MASTER { // also recompute old target's healthy list + if targetChanged && currentTarget.TabletType != topodata.TabletType_MASTER && hc.isIncluded(shr.Target.TabletType, shr.TabletAlias) { // also recompute old target's healthy list oldTargetKey := hc.keyFromTarget(currentTarget) all := hc.healthData[oldTargetKey] allArray := make([]*TabletHealth, 0, len(all)) for _, s := range all { // only tablets in same cell / cellAlias are included in healthy list - if hc.isIncluded(shr) { + if hc.isIncluded(s.Tablet.Type, s.Tablet.Alias) { allArray = append(allArray, s) } } @@ -716,14 +719,14 @@ func (hc *HealthCheckImpl) getAliasByCell(cell string) string { return alias } -func (hc *HealthCheckImpl) isIncluded(shr *query.StreamHealthResponse) bool { - if shr.Target.TabletType == topodata.TabletType_MASTER { +func (hc *HealthCheckImpl) isIncluded(tabletType topodata.TabletType, tabletAlias *topodata.TabletAlias) bool { + if tabletType == topodata.TabletType_MASTER { return true } - if shr.TabletAlias.Cell == hc.cell { + if tabletAlias.Cell == hc.cell { return true } - if hc.getAliasByCell(shr.TabletAlias.Cell) == hc.getAliasByCell(hc.cell) { + if hc.getAliasByCell(tabletAlias.Cell) == hc.getAliasByCell(hc.cell) { return true } return false From 6bf72ed2da09f0a907257056798b39cd17f3b723 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Wed, 21 Oct 2020 17:18:57 -0700 Subject: [PATCH 015/310] Merge pull request #6849 from tinyspeck/am_mysqld_shutdown_timeout Add timeout for mysqld_shutdown Signed-off-by: Andrew Mason --- go/vt/hook/hook.go | 68 ++++++--- go/vt/hook/hook_test.go | 39 +++++ go/vt/mysqlctl/builtinbackupengine.go | 12 +- go/vt/mysqlctl/builtinbackupengine_test.go | 135 ++++++++++++++++++ .../fakemysqldaemon/fakemysqldaemon.go | 26 ++++ go/vt/mysqlctl/mysqld.go | 2 +- 6 files changed, 264 insertions(+), 18 deletions(-) create mode 100644 go/vt/hook/hook_test.go create mode 100644 go/vt/mysqlctl/builtinbackupengine_test.go diff --git a/go/vt/hook/hook.go b/go/vt/hook/hook.go index 0215a143829..6cee35e4241 100644 --- a/go/vt/hook/hook.go +++ b/go/vt/hook/hook.go @@ -18,6 +18,8 @@ package hook import ( "bytes" + "context" + "errors" "fmt" "io" "os" @@ -25,6 +27,7 @@ import ( "path" "strings" "syscall" + "time" vtenv "vitess.io/vitess/go/vt/env" "vitess.io/vitess/go/vt/log" @@ -69,6 +72,10 @@ const ( // HOOK_GENERIC_ERROR is returned for unknown errors. HOOK_GENERIC_ERROR = -6 + + // HOOK_TIMEOUT_ERROR is returned when a CommandContext has its context + // become done before the command terminates. + HOOK_TIMEOUT_ERROR = -7 ) // WaitFunc is a return type for the Pipe methods. @@ -90,8 +97,8 @@ func NewHookWithEnv(name string, params []string, env map[string]string) *Hook { return &Hook{Name: name, Parameters: params, ExtraEnv: env} } -// findHook trie to locate the hook, and returns the exec.Cmd for it. -func (hook *Hook) findHook() (*exec.Cmd, int, error) { +// findHook tries to locate the hook, and returns the exec.Cmd for it. +func (hook *Hook) findHook(ctx context.Context) (*exec.Cmd, int, error) { // Check the hook path. if strings.Contains(hook.Name, "/") { return nil, HOOK_INVALID_NAME, fmt.Errorf("hook cannot contain '/'") @@ -116,7 +123,7 @@ func (hook *Hook) findHook() (*exec.Cmd, int, error) { // Configure the command. log.Infof("hook: executing hook: %v %v", vthook, strings.Join(hook.Parameters, " ")) - cmd := exec.Command(vthook, hook.Parameters...) + cmd := exec.CommandContext(ctx, vthook, hook.Parameters...) if len(hook.ExtraEnv) > 0 { cmd.Env = os.Environ() for key, value := range hook.ExtraEnv { @@ -127,12 +134,12 @@ func (hook *Hook) findHook() (*exec.Cmd, int, error) { return cmd, HOOK_SUCCESS, nil } -// Execute tries to execute the Hook and returns a HookResult. -func (hook *Hook) Execute() (result *HookResult) { +// ExecuteContext tries to execute the Hook with the given context and returns a HookResult. +func (hook *Hook) ExecuteContext(ctx context.Context) (result *HookResult) { result = &HookResult{} // Find the hook. - cmd, status, err := hook.findHook() + cmd, status, err := hook.findHook(ctx) if err != nil { result.ExitStatus = status result.Stderr = err.Error() + "\n" @@ -143,25 +150,54 @@ func (hook *Hook) Execute() (result *HookResult) { var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr + + start := time.Now() err = cmd.Run() + duration := time.Since(start) + result.Stdout = stdout.String() result.Stderr = stderr.String() + + defer func() { + log.Infof("hook: result is %v", result.String()) + }() + if err == nil { result.ExitStatus = HOOK_SUCCESS - } else { - if cmd.ProcessState != nil && cmd.ProcessState.Sys() != nil { - result.ExitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() - } else { - result.ExitStatus = HOOK_CANNOT_GET_EXIT_STATUS - } - result.Stderr += "ERROR: " + err.Error() + "\n" + return result } - log.Infof("hook: result is %v", result.String()) + if ctx.Err() != nil && errors.Is(ctx.Err(), context.DeadlineExceeded) { + // When (exec.Cmd).Run hits a context cancelled, the process is killed via SIGTERM. + // This means: + // 1. cmd.ProcessState.Exited() is false. + // 2. cmd.ProcessState.ExitCode() is -1. + // [ref]: https://golang.org/pkg/os/#ProcessState.ExitCode + // + // Therefore, we need to catch this error specifically, and set result.ExitStatus to + // HOOK_TIMEOUT_ERROR, because just using ExitStatus will result in HOOK_DOES_NOT_EXIST, + // which would be wrong. Since we're already doing some custom handling, we'll also include + // the amount of time the command was running in the error string, in case that is helpful. + result.ExitStatus = HOOK_TIMEOUT_ERROR + result.Stderr += fmt.Sprintf("ERROR: (after %s) %s\n", duration, err) + return result + } + + if cmd.ProcessState != nil && cmd.ProcessState.Sys() != nil { + result.ExitStatus = cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus() + } else { + result.ExitStatus = HOOK_CANNOT_GET_EXIT_STATUS + } + result.Stderr += "ERROR: " + err.Error() + "\n" return result } +// Execute tries to execute the Hook and returns a HookResult. +func (hook *Hook) Execute() (result *HookResult) { + return hook.ExecuteContext(context.Background()) +} + // ExecuteOptional executes an optional hook, logs if it doesn't // exist, and returns a printable error. func (hook *Hook) ExecuteOptional() error { @@ -187,7 +223,7 @@ func (hook *Hook) ExecuteOptional() error { // - an error code and an error if anything fails. func (hook *Hook) ExecuteAsWritePipe(out io.Writer) (io.WriteCloser, WaitFunc, int, error) { // Find the hook. - cmd, status, err := hook.findHook() + cmd, status, err := hook.findHook(context.Background()) if err != nil { return nil, nil, status, err } @@ -226,7 +262,7 @@ func (hook *Hook) ExecuteAsWritePipe(out io.Writer) (io.WriteCloser, WaitFunc, i // - an error code and an error if anything fails. func (hook *Hook) ExecuteAsReadPipe(in io.Reader) (io.Reader, WaitFunc, int, error) { // Find the hook. - cmd, status, err := hook.findHook() + cmd, status, err := hook.findHook(context.Background()) if err != nil { return nil, nil, status, err } diff --git a/go/vt/hook/hook_test.go b/go/vt/hook/hook_test.go new file mode 100644 index 00000000000..fd9235f14b3 --- /dev/null +++ b/go/vt/hook/hook_test.go @@ -0,0 +1,39 @@ +package hook + +import ( + "context" + "os" + "os/exec" + "path" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + vtenv "vitess.io/vitess/go/vt/env" +) + +func TestExecuteContext(t *testing.T) { + vtroot, err := vtenv.VtRoot() + require.NoError(t, err) + + sleep, err := exec.LookPath("sleep") + require.NoError(t, err) + + sleepHookPath := path.Join(vtroot, "vthook", "sleep") + require.NoError(t, os.Symlink(sleep, sleepHookPath)) + defer func() { + require.NoError(t, os.Remove(sleepHookPath)) + }() + + h := NewHook("sleep", []string{"5"}) + ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*10) + defer cancel() + + hr := h.ExecuteContext(ctx) + assert.Equal(t, HOOK_TIMEOUT_ERROR, hr.ExitStatus) + + h.Parameters = []string{"0.1"} + hr = h.Execute() + assert.Equal(t, HOOK_SUCCESS, hr.ExitStatus) +} diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index cc077bb6610..a1db9af5107 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -20,6 +20,7 @@ import ( "bufio" "context" "encoding/json" + "flag" "fmt" "io" "os" @@ -47,6 +48,13 @@ const ( dataDictionaryFile = "mysql.ibd" ) +var ( + // BuiltinBackupMysqldTimeout is how long ExecuteBackup should wait for response from mysqld.Shutdown. + // It can later be extended for other calls to mysqld during backup functions. + // Exported for testing. + BuiltinBackupMysqldTimeout = flag.Duration("builtinbackup_mysqld_timeout", 10*time.Minute, "how long to wait for mysqld to shutdown at the start of the backup") +) + // BuiltinBackupEngine encapsulates the logic of the builtin engine // it implements the BackupEngine interface and contains all the logic // required to implement a backup/restore by copying files from and to @@ -182,7 +190,9 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupP params.Logger.Infof("using replication position: %v", replicationPosition) // shutdown mysqld - err = params.Mysqld.Shutdown(ctx, params.Cnf, true) + shutdownCtx, cancel := context.WithTimeout(ctx, *BuiltinBackupMysqldTimeout) + err = params.Mysqld.Shutdown(shutdownCtx, params.Cnf, true) + defer cancel() if err != nil { return false, vterrors.Wrap(err, "can't shutdown mysqld") } diff --git a/go/vt/mysqlctl/builtinbackupengine_test.go b/go/vt/mysqlctl/builtinbackupengine_test.go new file mode 100644 index 00000000000..3e9b739839b --- /dev/null +++ b/go/vt/mysqlctl/builtinbackupengine_test.go @@ -0,0 +1,135 @@ +// Package mysqlctl_test is the blackbox tests for package mysqlctl. +// Tests that need to use fakemysqldaemon must be written as blackbox tests; +// since fakemysqldaemon imports mysqlctl, importing fakemysqldaemon in +// a `package mysqlctl` test would cause a circular import. +package mysqlctl_test + +import ( + "context" + "os" + "path" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "vitess.io/vitess/go/mysql/fakesqldb" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/mysqlctl" + "vitess.io/vitess/go/vt/mysqlctl/fakemysqldaemon" + "vitess.io/vitess/go/vt/mysqlctl/filebackupstorage" + "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vttime" + "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/memorytopo" + "vitess.io/vitess/go/vt/vttablet/faketmclient" + "vitess.io/vitess/go/vt/vttablet/tmclient" +) + +func setBuiltinBackupMysqldDeadline(t time.Duration) time.Duration { + old := *mysqlctl.BuiltinBackupMysqldTimeout + mysqlctl.BuiltinBackupMysqldTimeout = &t + + return old +} + +func createBackupDir(root string, dirs ...string) error { + for _, dir := range dirs { + if err := os.MkdirAll(path.Join(root, dir), 0755); err != nil { + return err + } + } + + return nil +} + +func TestExecuteBackup(t *testing.T) { + // Set up local backup directory + backupRoot := "testdata/builtinbackup_test" + *filebackupstorage.FileBackupStorageRoot = backupRoot + require.NoError(t, createBackupDir(backupRoot, "innodb", "log", "datadir")) + defer os.RemoveAll(backupRoot) + + ctx := context.Background() + + // Set up topo + keyspace, shard := "mykeyspace", "-80" + ts := memorytopo.NewServer("cell1") + defer ts.Close() + + require.NoError(t, ts.CreateKeyspace(ctx, keyspace, &topodata.Keyspace{})) + require.NoError(t, ts.CreateShard(ctx, keyspace, shard)) + + tablet := topo.NewTablet(100, "cell1", "mykeyspace-00-80-0100") + tablet.Keyspace = keyspace + tablet.Shard = shard + + require.NoError(t, ts.CreateTablet(ctx, tablet)) + + _, err := ts.UpdateShardFields(ctx, keyspace, shard, func(si *topo.ShardInfo) error { + si.MasterAlias = &topodata.TabletAlias{Uid: 100, Cell: "cell1"} + + now := time.Now() + si.MasterTermStartTime = &vttime.Time{Seconds: int64(now.Second()), Nanoseconds: int32(now.Nanosecond())} + + return nil + }) + require.NoError(t, err) + + // Set up tm client + // Note that using faketmclient.NewFakeTabletManagerClient will cause infinite recursion :shrug: + tmclient.RegisterTabletManagerClientFactory("grpc", + func() tmclient.TabletManagerClient { return &faketmclient.FakeTabletManagerClient{} }, + ) + + be := &mysqlctl.BuiltinBackupEngine{} + + // Configure a tight deadline to force a timeout + oldDeadline := setBuiltinBackupMysqldDeadline(time.Second) + defer setBuiltinBackupMysqldDeadline(oldDeadline) + + bh := filebackupstorage.FileBackupHandle{} + + // Spin up a fake daemon to be used in backups. It needs to be allowed to receive: + // "STOP SLAVE", "START SLAVE", in that order. + mysqld := fakemysqldaemon.NewFakeMysqlDaemon(fakesqldb.New(t)) + mysqld.ExpectedExecuteSuperQueryList = []string{"STOP SLAVE", "START SLAVE"} + // mysqld.ShutdownTime = time.Minute + + ok, err := be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logutil.NewConsoleLogger(), + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + }, &bh) + + require.NoError(t, err) + assert.True(t, ok) + + mysqld.ExpectedExecuteSuperQueryCurrent = 0 // resest the index of what queries we've run + mysqld.ShutdownTime = time.Minute // reminder that shutdownDeadline is 1s + + ok, err = be.ExecuteBackup(ctx, mysqlctl.BackupParams{ + Logger: logutil.NewConsoleLogger(), + Mysqld: mysqld, + Cnf: &mysqlctl.Mycnf{ + InnodbDataHomeDir: path.Join(backupRoot, "innodb"), + InnodbLogGroupHomeDir: path.Join(backupRoot, "log"), + DataDir: path.Join(backupRoot, "datadir"), + }, + HookExtraEnv: map[string]string{}, + TopoServer: ts, + Keyspace: keyspace, + Shard: shard, + }, &bh) + + assert.Error(t, err) + assert.False(t, ok) +} diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index f4142ffee20..84e933dfa6f 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -48,6 +48,14 @@ type FakeMysqlDaemon struct { // Running is used by Start / Shutdown Running bool + // StartupTime is used to simulate mysqlds that take some time to respond + // to a "start" command. It is used by Start. + StartupTime time.Duration + + // ShutdownTime is used to simulate mysqlds that take some time to respond + // to a "stop" request (i.e. a wedged systemd unit). It is used by Shutdown. + ShutdownTime time.Duration + // MysqlPort will be returned by GetMysqlPort(). Set to -1 to // return an error. MysqlPort sync2.AtomicInt32 @@ -181,6 +189,15 @@ func (fmd *FakeMysqlDaemon) Start(ctx context.Context, cnf *mysqlctl.Mycnf, mysq if fmd.Running { return fmt.Errorf("fake mysql daemon already running") } + + if fmd.StartupTime > 0 { + select { + case <-time.After(fmd.StartupTime): + case <-ctx.Done(): + return ctx.Err() + } + } + fmd.Running = true return nil } @@ -190,6 +207,15 @@ func (fmd *FakeMysqlDaemon) Shutdown(ctx context.Context, cnf *mysqlctl.Mycnf, w if !fmd.Running { return fmt.Errorf("fake mysql daemon not running") } + + if fmd.ShutdownTime > 0 { + select { + case <-time.After(fmd.ShutdownTime): + case <-ctx.Done(): + return ctx.Err() + } + } + fmd.Running = false return nil } diff --git a/go/vt/mysqlctl/mysqld.go b/go/vt/mysqlctl/mysqld.go index 7abd1da7a78..fc6fce373be 100644 --- a/go/vt/mysqlctl/mysqld.go +++ b/go/vt/mysqlctl/mysqld.go @@ -512,7 +512,7 @@ func (mysqld *Mysqld) Shutdown(ctx context.Context, cnf *Mycnf, waitForMysqld bo // try the mysqld shutdown hook, if any h := hook.NewSimpleHook("mysqld_shutdown") - hr := h.Execute() + hr := h.ExecuteContext(ctx) switch hr.ExitStatus { case hook.HOOK_SUCCESS: // hook exists and worked, we can keep going From 52f4f05ef299fe0e1ce619e66313bfc35853fa6f Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 13 Oct 2020 08:17:57 +0200 Subject: [PATCH 016/310] VDiff Enum: make enum compareable Signed-off-by: Rohit Nayak --- go/vt/vtgate/evalengine/arithmetic.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/evalengine/arithmetic.go b/go/vt/vtgate/evalengine/arithmetic.go index f40e9d5c456..bf34797276c 100644 --- a/go/vt/vtgate/evalengine/arithmetic.go +++ b/go/vt/vtgate/evalengine/arithmetic.go @@ -209,7 +209,7 @@ func isByteComparable(v sqltypes.Value) bool { return true } switch v.Type() { - case sqltypes.Timestamp, sqltypes.Date, sqltypes.Time, sqltypes.Datetime: + case sqltypes.Timestamp, sqltypes.Date, sqltypes.Time, sqltypes.Datetime, sqltypes.Enum: return true } return false From 5c7e590524070af3be4ef519c7fce0039bf2140a Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Wed, 14 Oct 2020 14:40:03 +0200 Subject: [PATCH 017/310] VDiff Enum: add enum column to vrep e2e test. remove enum from uncomparable types test Signed-off-by: Rohit Nayak --- go.mod | 1 + go.sum | 2 ++ go/test/endtoend/vreplication/config.go | 2 +- go/test/endtoend/vreplication/unsharded_init_data.sql | 6 +++--- go/vt/vtgate/vindexes/consistent_lookup_test.go | 1 - 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 3f20e4a8295..ee4b897fc1b 100644 --- a/go.mod +++ b/go.mod @@ -57,6 +57,7 @@ require ( github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 github.com/mattn/go-sqlite3 v1.14.0 github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 + github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/go-testing-interface v1.14.0 // indirect github.com/mitchellh/mapstructure v1.2.3 // indirect github.com/montanaflynn/stats v0.6.3 diff --git a/go.sum b/go.sum index 017ce039aa5..c1e6fc5d55d 100644 --- a/go.sum +++ b/go.sum @@ -439,6 +439,8 @@ github.com/mitchellh/cli v1.1.0 h1:tEElEatulEHDeedTxwckzyYMA5c86fbmNIUL1hBIiTg= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= diff --git a/go/test/endtoend/vreplication/config.go b/go/test/endtoend/vreplication/config.go index cd06ff3cee1..2f031b329f7 100644 --- a/go/test/endtoend/vreplication/config.go +++ b/go/test/endtoend/vreplication/config.go @@ -3,7 +3,7 @@ package vreplication var ( initialProductSchema = ` create table product(pid int, description varbinary(128), primary key(pid)); -create table customer(cid int, name varbinary(128), primary key(cid)); +create table customer(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), primary key(cid)); create table merchant(mname varchar(128), category varchar(128), primary key(mname)) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; create table orders(oid int, cid int, pid int, mname varchar(128), price int, primary key(oid)); create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; diff --git a/go/test/endtoend/vreplication/unsharded_init_data.sql b/go/test/endtoend/vreplication/unsharded_init_data.sql index 955392b0753..9b405e76b8e 100644 --- a/go/test/endtoend/vreplication/unsharded_init_data.sql +++ b/go/test/endtoend/vreplication/unsharded_init_data.sql @@ -1,6 +1,6 @@ -insert into customer(cid, name) values(1, 'john'); -insert into customer(cid, name) values(2, 'paul'); -insert into customer(cid, name) values(3, 'ringo'); +insert into customer(cid, name, typ) values(1, 'john',1); +insert into customer(cid, name, typ) values(2, 'paul','soho'); +insert into customer(cid, name, typ) values(3, 'ringo','enterprise'); insert into merchant(mname, category) values('monoprice', 'electronics'); insert into merchant(mname, category) values('newegg', 'electronics'); insert into product(pid, description) values(1, 'keyboard'); diff --git a/go/vt/vtgate/vindexes/consistent_lookup_test.go b/go/vt/vtgate/vindexes/consistent_lookup_test.go index b0ec78081b0..4c496be1583 100644 --- a/go/vt/vtgate/vindexes/consistent_lookup_test.go +++ b/go/vt/vtgate/vindexes/consistent_lookup_test.go @@ -451,7 +451,6 @@ func TestConsistentLookupUpdateBecauseUncomparableTypes(t *testing.T) { {querypb.Type_VARCHAR, "some string"}, {querypb.Type_CHAR, "some string"}, {querypb.Type_BIT, "some string"}, - {querypb.Type_ENUM, "some string"}, {querypb.Type_SET, "some string"}, {querypb.Type_GEOMETRY, "some string"}, {querypb.Type_JSON, "some string"}, From e4d81c4fd83451a45c7f0745241e9bf7e5f83431 Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Thu, 22 Oct 2020 12:27:20 -0700 Subject: [PATCH 018/310] Revert "Docker - upgrade to Debian Buster (release-8.0)" Signed-off-by: deepthi --- docker/bootstrap/Dockerfile.common | 23 ++++++++++++++++++----- docker/bootstrap/Dockerfile.mariadb | 2 +- docker/bootstrap/Dockerfile.mariadb103 | 2 +- docker/bootstrap/Dockerfile.mysql56 | 8 +------- docker/bootstrap/Dockerfile.mysql57 | 4 ++-- docker/bootstrap/Dockerfile.mysql80 | 4 ++-- docker/bootstrap/Dockerfile.percona | 14 +------------- docker/bootstrap/Dockerfile.percona57 | 4 ++-- docker/bootstrap/Dockerfile.percona80 | 4 ++-- docker/lite/Dockerfile.mariadb | 2 +- docker/lite/Dockerfile.mariadb103 | 2 +- docker/lite/Dockerfile.mysql56 | 2 +- docker/lite/Dockerfile.mysql57 | 2 +- docker/lite/Dockerfile.mysql80 | 2 +- docker/lite/Dockerfile.percona | 2 +- docker/lite/Dockerfile.percona57 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/lite/Dockerfile.testing | 2 +- docker/lite/install_dependencies.sh | 16 ++++++++-------- docker/orchestrator/build.sh | 2 +- 20 files changed, 48 insertions(+), 53 deletions(-) diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index 54402e358ef..92ca899f712 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,22 +1,35 @@ -FROM golang:1.13-buster +FROM golang:1.13-stretch # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ # TODO(mberlin): Group these to make it easier to understand which library actually requires them. - ant \ + automake \ + bison \ + bzip2 \ chromium \ curl \ - default-jdk \ - etcd \ g++ \ git \ + libgconf-2-4 \ + libtool \ make \ - maven \ + openjdk-8-jdk \ software-properties-common \ + virtualenv \ unzip \ + xvfb \ zip \ + libz-dev \ + ant \ && rm -rf /var/lib/apt/lists/* +# Install Maven 3.1+ +RUN mkdir -p /vt/src/vitess.io/vitess/dist && \ + cd /vt/src/vitess.io/vitess/dist && \ + curl -sL --connect-timeout 10 --retry 3 \ + http://www-us.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz | tar -xz && \ + mv apache-maven-3.3.9 maven + # Set up Vitess environment (equivalent to '. dev.env') ENV VTROOT /vt/src/vitess.io/vitess ENV VTDATAROOT /vt/vtdataroot diff --git a/docker/bootstrap/Dockerfile.mariadb b/docker/bootstrap/Dockerfile.mariadb index 90d9dd1e201..19d5c9973d0 100644 --- a/docker/bootstrap/Dockerfile.mariadb +++ b/docker/bootstrap/Dockerfile.mariadb @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install MariaDB 10 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - add-apt-repository 'deb http://repo.percona.com/apt buster main' && \ + add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mariadb103 b/docker/bootstrap/Dockerfile.mariadb103 index 5d15356f419..c2828ddd25d 100644 --- a/docker/bootstrap/Dockerfile.mariadb103 +++ b/docker/bootstrap/Dockerfile.mariadb103 @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install MariaDB 10.3 RUN apt-key adv --no-tty --recv-keys --keyserver keyserver.ubuntu.com 0xF1656F24C74CD1D8 \ - && add-apt-repository 'deb [arch=amd64] http://ftp.osuosl.org/pub/mariadb/repo/10.3/debian buster main' \ + && add-apt-repository 'deb [arch=amd64] http://ftp.osuosl.org/pub/mariadb/repo/10.3/debian stretch main' \ && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ mariadb-server-10.3 \ libmariadb-dev \ diff --git a/docker/bootstrap/Dockerfile.mysql56 b/docker/bootstrap/Dockerfile.mysql56 index 46ee7b8553a..0cdb5ae84f2 100644 --- a/docker/bootstrap/Dockerfile.mysql56 +++ b/docker/bootstrap/Dockerfile.mysql56 @@ -1,16 +1,10 @@ FROM vitess/bootstrap:common # Install MySQL 5.6 -# -# Unfortunately we need to keep the 'stretch' repo from Oracle as there's no official support -# for MySQL 5.6 for Debian Buster: https://bugs.mysql.com/bug.php?id=101055 -# -# I think it's fine as MySQL 5.6 will be EOL pretty soon (February 5, 2021) -# RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6' && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.6 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mysql57 b/docker/bootstrap/Dockerfile.mysql57 index 4889e74f4e1..7e0c5f99f96 100644 --- a/docker/bootstrap/Dockerfile.mysql57 +++ b/docker/bootstrap/Dockerfile.mysql57 @@ -3,9 +3,9 @@ FROM vitess/bootstrap:common # Install MySQL 5.7 RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gnupg dirmngr ca-certificates && \ for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver ha.pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ - add-apt-repository 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.7' && \ + add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.7' && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.mysql80 b/docker/bootstrap/Dockerfile.mysql80 index 543453e911a..0523a7847cc 100644 --- a/docker/bootstrap/Dockerfile.mysql80 +++ b/docker/bootstrap/Dockerfile.mysql80 @@ -2,9 +2,9 @@ FROM vitess/bootstrap:common # Install MySQL 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --recv-keys --keyserver ha.pool.sks-keyservers.net 8C718D3B5072E1F5 && break; done && \ - add-apt-repository 'deb http://repo.mysql.com/apt/debian/ buster mysql-8.0' && \ + add-apt-repository 'deb http://repo.mysql.com/apt/debian/ stretch mysql-8.0' && \ for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list && \ + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ diff --git a/docker/bootstrap/Dockerfile.percona b/docker/bootstrap/Dockerfile.percona index d2666c6b137..910d3be10b1 100644 --- a/docker/bootstrap/Dockerfile.percona +++ b/docker/bootstrap/Dockerfile.percona @@ -1,19 +1,8 @@ FROM vitess/bootstrap:common # Install Percona 5.6 -# -# Unfortunately we need to keep the 'stretch' repo from Percona as there's no official support -# for MySQL 5.6 for Debian Buster -# -# I think it's fine as MySQL 5.6 will be EOL pretty soon (February 5, 2021) -# -# Also, for the 'percona-xtrabackup-24' package we need to specificly target the -# 'buster' repository as the 'stretch' package requires 'libcurl3' that is not present -# in Debian Buster. -# RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ - add-apt-repository 'deb http://repo.percona.com/apt buster main' && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.6 percona-server-server/root_password password 'unused'; \ @@ -21,8 +10,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r } | debconf-set-selections && \ apt-get update && \ apt-get install -y --no-install-recommends \ - percona-server-server-5.6 libperconaserverclient18.1-dev rsync libev4 && \ - apt-get install -y -t buster percona-xtrabackup-24 && \ + percona-server-server-5.6 libperconaserverclient18.1-dev rsync libev4 percona-xtrabackup-24 && \ rm -rf /var/lib/apt/lists/* # Bootstrap Vitess diff --git a/docker/bootstrap/Dockerfile.percona57 b/docker/bootstrap/Dockerfile.percona57 index 4bac477d764..54c8477ffb6 100644 --- a/docker/bootstrap/Dockerfile.percona57 +++ b/docker/bootstrap/Dockerfile.percona57 @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install Percona 5.7 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done && \ - add-apt-repository 'deb http://repo.percona.com/apt buster main' && \ + add-apt-repository 'deb http://repo.percona.com/apt stretch main' && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-5.7 percona-server-server/root_password password 'unused'; \ @@ -11,7 +11,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r apt-get update && \ apt-get install -y --no-install-recommends \ percona-server-server-5.7 \ - libperconaserverclient20-dev percona-xtrabackup-24 && \ + libperconaserverclient18.1-dev percona-xtrabackup-24 && \ rm -rf /var/lib/apt/lists/* # Bootstrap Vitess diff --git a/docker/bootstrap/Dockerfile.percona80 b/docker/bootstrap/Dockerfile.percona80 index d649416a6b6..1ce9c52103f 100644 --- a/docker/bootstrap/Dockerfile.percona80 +++ b/docker/bootstrap/Dockerfile.percona80 @@ -2,7 +2,7 @@ FROM vitess/bootstrap:common # Install Percona 8.0 RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --recv-keys 9334A25F8507EFA5 && break; done \ - && echo 'deb http://repo.percona.com/ps-80/apt buster main' > /etc/apt/sources.list.d/percona.list && \ + && echo 'deb http://repo.percona.com/ps-80/apt stretch main' > /etc/apt/sources.list.d/percona.list && \ { \ echo debconf debconf/frontend select Noninteractive; \ echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ @@ -19,7 +19,7 @@ RUN for i in $(seq 1 10); do apt-key adv --no-tty --keyserver keys.gnupg.net --r rsync \ libev4 \ # && rm -f /etc/apt/sources.list.d/percona.list \ - && echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list \ + && echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list \ # { \ # echo debconf debconf/frontend select Noninteractive; \ # echo percona-server-server-8.0 percona-server-server/root_password password 'unused'; \ diff --git a/docker/lite/Dockerfile.mariadb b/docker/lite/Dockerfile.mariadb index 1617d899fe2..2299fa0866f 100644 --- a/docker/lite/Dockerfile.mariadb +++ b/docker/lite/Dockerfile.mariadb @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mariadb103 b/docker/lite/Dockerfile.mariadb103 index 079ab6ff4a7..825035a66a6 100644 --- a/docker/lite/Dockerfile.mariadb103 +++ b/docker/lite/Dockerfile.mariadb103 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mysql56 b/docker/lite/Dockerfile.mysql56 index ec361bec520..a8d5a76de68 100644 --- a/docker/lite/Dockerfile.mysql56 +++ b/docker/lite/Dockerfile.mysql56 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mysql57 b/docker/lite/Dockerfile.mysql57 index 5ff2d21514d..11013292b49 100644 --- a/docker/lite/Dockerfile.mysql57 +++ b/docker/lite/Dockerfile.mysql57 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.mysql80 b/docker/lite/Dockerfile.mysql80 index c395d24f37a..99752bf11b7 100644 --- a/docker/lite/Dockerfile.mysql80 +++ b/docker/lite/Dockerfile.mysql80 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.percona b/docker/lite/Dockerfile.percona index e0c5eac8a78..b93f0dffe4a 100644 --- a/docker/lite/Dockerfile.percona +++ b/docker/lite/Dockerfile.percona @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.percona57 b/docker/lite/Dockerfile.percona57 index e8cc430475c..a1091434a88 100644 --- a/docker/lite/Dockerfile.percona57 +++ b/docker/lite/Dockerfile.percona57 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index 0bb057d6ed2..dfa875a51db 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -30,7 +30,7 @@ USER vitess RUN make install PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/Dockerfile.testing b/docker/lite/Dockerfile.testing index 523d50e3c77..19214800013 100644 --- a/docker/lite/Dockerfile.testing +++ b/docker/lite/Dockerfile.testing @@ -30,7 +30,7 @@ USER vitess RUN make install-testing PREFIX=/vt/install # Start over and build the final image. -FROM debian:buster-slim +FROM debian:stretch-slim # Install dependencies COPY docker/lite/install_dependencies.sh /vt/dist/install_dependencies.sh diff --git a/docker/lite/install_dependencies.sh b/docker/lite/install_dependencies.sh index b9a05da3aa5..61e1451a851 100755 --- a/docker/lite/install_dependencies.sh +++ b/docker/lite/install_dependencies.sh @@ -126,30 +126,30 @@ add_apt_key 9334A25F8507EFA5 # Add extra apt repositories for MySQL. case "${FLAVOR}" in mysql56) - echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.6' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6' > /etc/apt/sources.list.d/mysql.list ;; mysql57) - echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-5.7' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ stretch mysql-5.7' > /etc/apt/sources.list.d/mysql.list ;; mysql80) - echo 'deb http://repo.mysql.com/apt/debian/ buster mysql-8.0' > /etc/apt/sources.list.d/mysql.list + echo 'deb http://repo.mysql.com/apt/debian/ stretch mysql-8.0' > /etc/apt/sources.list.d/mysql.list ;; mariadb) - echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.2/debian buster main' > /etc/apt/sources.list.d/mariadb.list + echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.2/debian stretch main' > /etc/apt/sources.list.d/mariadb.list ;; mariadb103) - echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/debian buster main' > /etc/apt/sources.list.d/mariadb.list + echo 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/debian stretch main' > /etc/apt/sources.list.d/mariadb.list ;; esac # Add extra apt repositories for Percona Server and/or Percona XtraBackup. case "${FLAVOR}" in mysql56|mysql57|mysql80|percona|percona57) - echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list ;; percona80) - echo 'deb http://repo.percona.com/apt buster main' > /etc/apt/sources.list.d/percona.list - echo 'deb http://repo.percona.com/ps-80/apt buster main' > /etc/apt/sources.list.d/percona80.list + echo 'deb http://repo.percona.com/apt stretch main' > /etc/apt/sources.list.d/percona.list + echo 'deb http://repo.percona.com/ps-80/apt stretch main' > /etc/apt/sources.list.d/percona80.list ;; esac diff --git a/docker/orchestrator/build.sh b/docker/orchestrator/build.sh index 933854a664a..dbc8dfc464b 100755 --- a/docker/orchestrator/build.sh +++ b/docker/orchestrator/build.sh @@ -23,7 +23,7 @@ script="go get vitess.io/vitess/go/cmd/vtctlclient && \ go install github.com/openark/orchestrator/go/cmd/orchestrator" echo "Building orchestrator..." -docker run -ti --name=vt_orc_build golang:1.14.4-buster bash -c "$script" +docker run -ti --name=vt_orc_build golang:1.14.4-stretch bash -c "$script" docker cp vt_orc_build:/go/bin/orchestrator $tmpdir docker cp vt_orc_build:/go/bin/vtctlclient $tmpdir docker cp vt_orc_build:/go/src/github.com/openark/orchestrator/resources $tmpdir From 3b4ca41e829d35866b64e6666ba92cd198efe3e3 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 10 Oct 2020 00:19:32 +0200 Subject: [PATCH 019/310] Set time zone to UTC while streaming rows Signed-off-by: Rohit Nayak --- go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go index 79bf3fba3cf..b5cac8cad9e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go +++ b/go/vt/vttablet/tabletserver/vstreamer/snapshot_conn.go @@ -94,6 +94,9 @@ func (conn *snapshotConn) startSnapshot(ctx context.Context, table string) (gtid if _, err := conn.ExecuteFetch("start transaction with consistent snapshot", 1, false); err != nil { return "", err } + if _, err := conn.ExecuteFetch("set @@session.time_zone = '+00:00'", 1, false); err != nil { + return "", err + } return mysql.EncodePosition(mpos), nil } From 5ba29f4f3c9d59df435353aa58b9c0380b779133 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Wed, 14 Oct 2020 20:29:00 +0200 Subject: [PATCH 020/310] Add a timestamp column to vrepl e2e to test a complete workflow with timestamps Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/endtoend/vreplication/config.go b/go/test/endtoend/vreplication/config.go index 2f031b329f7..c89dcde93d7 100644 --- a/go/test/endtoend/vreplication/config.go +++ b/go/test/endtoend/vreplication/config.go @@ -3,7 +3,7 @@ package vreplication var ( initialProductSchema = ` create table product(pid int, description varbinary(128), primary key(pid)); -create table customer(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), primary key(cid)); +create table customer(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), ts timestamp not null default current_timestamp, primary key(cid)); create table merchant(mname varchar(128), category varchar(128), primary key(mname)) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; create table orders(oid int, cid int, pid int, mname varchar(128), price int, primary key(oid)); create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; From 5e67474cbc6e6260801bbb48bdd8ecebe9fc3e7b Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Sat, 24 Oct 2020 15:58:11 +0530 Subject: [PATCH 021/310] added e2e test for insert statement in olap mode Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/misc_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index ef5615527fd..282a085f3ba 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -371,6 +371,19 @@ func TestUseStmtInOLAP(t *testing.T) { } } +func TestInsertStmtInOLAP(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + exec(t, conn, `set workload='olap'`) + _, err = conn.ExecuteFetch(`insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`, 1000, true) + require.Error(t, err) + assertMatches(t, conn, `select id1 from t1 order by id1`, `[]`) +} + func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) From a284ae0b0a3efc2902e7221257e77093c9094d11 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Sat, 24 Oct 2020 15:59:35 +0530 Subject: [PATCH 022/310] check error before calling callback Signed-off-by: Harshit Gangal --- go/vt/vtgate/executor.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 8627377ec76..a7a8e1de424 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -1196,22 +1196,23 @@ func (e *Executor) StreamExecute(ctx context.Context, method string, safeSession return nil }) - // Send left-over rows. - if len(result.Rows) > 0 || !seenResults { - if err := callback(result); err != nil { - return err + // Send left-over rows if there is no error on execution. + if err == nil { + if len(result.Rows) > 0 || !seenResults { + if err := callback(result); err != nil { + return err + } } + // save session stats for future queries + if !safeSession.foundRowsHandled { + safeSession.FoundRows = foundRows + } + safeSession.RowCount = -1 } logStats.ExecuteTime = time.Since(execStart) e.updateQueryCounts(plan.Instructions.RouteType(), plan.Instructions.GetKeyspaceName(), plan.Instructions.GetTableName(), int64(logStats.ShardQueries)) - // save session stats for future queries - if !safeSession.foundRowsHandled { - safeSession.FoundRows = foundRows - } - safeSession.RowCount = -1 - return err } From cc8c593ac503f68ce96880f6c99dc6b8cf8bfbc9 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Sat, 24 Oct 2020 16:30:31 +0530 Subject: [PATCH 023/310] fix test to delete row afterwards Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/misc_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 282a085f3ba..153d0d35569 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -328,11 +328,13 @@ func TestOffsetAndLimitWithOLAP(t *testing.T) { conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) defer conn.Close() + defer exec(t, conn, "delete from t1") exec(t, conn, "insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)") assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]") exec(t, conn, "set workload='olap'") assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]") + exec(t, conn, "set workload='oltp'") } func TestSwitchBetweenOlapAndOltp(t *testing.T) { From 16c6c2038c054d7711ae72796c8fae757d72263d Mon Sep 17 00:00:00 2001 From: deepthi Date: Sun, 25 Oct 2020 16:21:12 -0700 Subject: [PATCH 024/310] docker: pin mysql 5.7 and 8.0 versions for xtrabackup compatibility Signed-off-by: deepthi --- docker/lite/install_dependencies.sh | 35 +++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/docker/lite/install_dependencies.sh b/docker/lite/install_dependencies.sh index 61e1451a851..dcc89a483cf 100755 --- a/docker/lite/install_dependencies.sh +++ b/docker/lite/install_dependencies.sh @@ -60,18 +60,38 @@ mysql56) ) ;; mysql57) + mysql57_version=5.7.31 + wget https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/libmysqlclient20_${mysql57_version}-1debian9_amd64.deb -O /tmp/libmysqlclient20_${mysql57_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-community-client_${mysql57_version}-1debian9_amd64.deb -O /tmp/mysql-community-client_${mysql57_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-client_${mysql57_version}-1debian9_amd64.deb -O /tmp/mysql-client_${mysql57_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-community-server_${mysql57_version}-1debian9_amd64.deb -O /tmp/mysql-community-server_${mysql57_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-5.7/m/mysql-community/mysql-server_${mysql57_version}-1debian9_amd64.deb -O /tmp/mysql-server_${mysql57_version}-1debian9_amd64.deb PACKAGES=( - libmysqlclient20 - mysql-client - mysql-server + /tmp/libmysqlclient20_${mysql57_version}-1debian9_amd64.deb + /tmp/mysql-community-client_${mysql57_version}-1debian9_amd64.deb + /tmp/mysql-client_${mysql57_version}-1debian9_amd64.deb + /tmp/mysql-community-server_${mysql57_version}-1debian9_amd64.deb + /tmp/mysql-server_${mysql57_version}-1debian9_amd64.deb percona-xtrabackup-24 ) ;; mysql80) + mysql8_version=8.0.21 + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/libmysqlclient21_${mysql8_version}-1debian9_amd64.deb -O /tmp/libmysqlclient21_${mysql8_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client-core_${mysql8_version}-1debian9_amd64.deb -O /tmp/mysql-community-client-core_${mysql8_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-client_${mysql8_version}-1debian9_amd64.deb -O /tmp/mysql-community-client_${mysql8_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-client_${mysql8_version}-1debian9_amd64.deb -O /tmp/mysql-client_${mysql8_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server-core_${mysql8_version}-1debian9_amd64.deb -O /tmp/mysql-community-server-core_${mysql8_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-community-server_${mysql8_version}-1debian9_amd64.deb -O /tmp/mysql-community-server_${mysql8_version}-1debian9_amd64.deb + wget https://repo.mysql.com/apt/debian/pool/mysql-8.0/m/mysql-community/mysql-server_${mysql8_version}-1debian9_amd64.deb -O /tmp/mysql-server_${mysql8_version}-1debian9_amd64.deb PACKAGES=( - libmysqlclient21 - mysql-client - mysql-server + /tmp/libmysqlclient21_${mysql8_version}-1debian9_amd64.deb + /tmp/mysql-community-client-core_${mysql8_version}-1debian9_amd64.deb + /tmp/mysql-community-client_${mysql8_version}-1debian9_amd64.deb + /tmp/mysql-client_${mysql8_version}-1debian9_amd64.deb + /tmp/mysql-community-server-core_${mysql8_version}-1debian9_amd64.deb + /tmp/mysql-community-server_${mysql8_version}-1debian9_amd64.deb + /tmp/mysql-server_${mysql8_version}-1debian9_amd64.deb percona-xtrabackup-80 ) ;; @@ -91,7 +111,7 @@ percona57) percona80) PACKAGES=( libperconaserverclient21 - percona-server-rocksdb + percona-server-rocksdb percona-server-server percona-server-tokudb percona-xtrabackup-80 @@ -185,3 +205,4 @@ apt-get install -y --no-install-recommends "${PACKAGES[@]}" # Clean up files we won't need in the final image. rm -rf /var/lib/apt/lists/* rm -rf /var/lib/mysql/ +rm -rf /tmp/*.deb From 811d2887b85a9767261aec23dedef84101d472d5 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 26 Oct 2020 12:58:21 +0530 Subject: [PATCH 025/310] addressed review comment Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/misc_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 153d0d35569..5415642d46f 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -328,13 +328,12 @@ func TestOffsetAndLimitWithOLAP(t *testing.T) { conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) defer conn.Close() - defer exec(t, conn, "delete from t1") + defer exec(t, conn, "set workload=oltp;delete from t1") exec(t, conn, "insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)") assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]") exec(t, conn, "set workload='olap'") assertMatches(t, conn, "select id1 from t1 order by id1 limit 3 offset 2", "[[INT64(3)] [INT64(4)] [INT64(5)]]") - exec(t, conn, "set workload='oltp'") } func TestSwitchBetweenOlapAndOltp(t *testing.T) { From a110c39d84abad928a790183767c150bbd4a5a5b Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Mon, 26 Oct 2020 14:15:06 +0300 Subject: [PATCH 026/310] v8.0 Release Notes -final draft- Signed-off-by: Alkin Tezuysal --- doc/releasenotes/8_0_0_release_notes.md | 258 ++++++++++++++++++++++-- 1 file changed, 239 insertions(+), 19 deletions(-) diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md index 18790aa803a..f6c0b77186f 100644 --- a/doc/releasenotes/8_0_0_release_notes.md +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -1,45 +1,265 @@ -## Incompatible Changes +This release complies with VEP-3 which removes the upgrade order requirement. Components can be upgraded in any order. It is recommended that the upgrade order should still be followed if possible, except to canary test the new version of VTGate before upgrading the rest of the components. -*This release includes the following changes which may result in incompatibilities when upgrading from a previous release*. *It is important that Vitess components are* _[upgraded in the recommended order](https://vitess.io/docs/user-guides/upgrading/#upgrade-order)_. *This will change in the next release as documented in* *[VEP-3](https://github.com/vitessio/enhancements/blob/master/veps/vep-3.md).* +## Incompatible Changes -## Deprecations +The following PRs made changes to behavior that clients might be relying on. They should be reviewed carefully so that client code can be changed in concert with a Vitess release deployment. +* Change error code from 1203 to 1153 for three specific error conditions. #6630 + The three errors being changed: +When a GRPC message coming back to the vtgate exceeds the configured size limit (configured via grpc_max_message_size) +If a write is attempting to make a change with a payload that is larger than the configured allowable size +If a scatter query is attempting to collect and process too many rows in memory within the vtgate to construct a response +* Zero auto-increment mode: This enables inserting a 0 value (and not just NULL) into an auto-increment column to generate sequence values. This matches the default behavior of MySQL. #6749 +* Turn off schema tracker by default #6712 ## Bugs Fixed -* set workload = 'olap'; can not repeat, but set workload = 'oltp' can; #4086 +### VTGate / MySQL compatibility * Fix where clause in information schema with correct database name #6599 +* Fix DDL execution on reserved connection without in active transaction #6514 +* Fix allow passed table_schema in information_schema queries to vttablet if the keyspace is not found #6653 +* Fix information schema for non-existent schema #6667 +* Fix reserved connection in autocommit mode on DML #6748 +* Fix dbname that needs escaping that we broke in fce4cfd894 #6794 +* MySQL CLI, mysql --ssl does not work in MySQL 8.0 #5556 +* OperationalError: (_mysql_exceptions.OperationalError) (2013, 'Lost connection to MySQL server during query') #6208 +* Fix support for `show tables where tables_in_db` to use keyspace name, not underlying db name #6446 +* Common empty result set query on MySQL returns a row in Vitess #6663 +* Operator precedence issue #6734 +* Table names out-of-order between replica and primary #6738 +* Close Idle reserved connections and Rollback Idle transactions #6552 +* Minor Vindex fixes: #6526 +* VTgate does not report autocommit system variable and SERVER_STATUS_IN_TRANS flag correctly #5825 +* MariaDB JDBC Connector fails to connect to vtgate with default options #5851 +* VTgate panics if there are no vttablets and vtctlds #6117 +* Remove shard session held in vtgate for reserved connection on connection failure #6522 +* Session variable does not work as expected in 7.0 #6559 +* Retry should not happen when in dedicated connection #6523 +* Correctly report AUTOCOMMIT status in network packets #6551 +* Close Idle reserved connections and Rollback Idle transactions #6552 +* Reset Session for Reserved Connection Query Failure #6673 +* Errors in multi-statement queries not fatal to statement sequence #6747 #6808 +* Lock wait timeout on DELETE from table using lookup index #6698 +* Application couldn't connect to external db giving error tabletserver.go:1522] Code: INVALID_ARGUMENT syntax error at position 33 near ':vtg2' (CallerID: gnocchi) : Sql: "select convert(:vtg1, CHAR(:vtg2)) as anon_1 from dual", #6466 +* The client got the wrong database name #6753 +* DBAPIError exception wrapped from (pymysql.err.InternalError) (1105, u'vtgate: http://gnocchi-gnocchizone-vtgate:15000/: reserved connections are not supported on old gen gateway') #6577 +* Provide support for “SELECT INTO OUTFILE S3” #6811 +* Fix error around breaking of multi statements #6824 +* Support SHOW TABLE STATUS FROM db type queries in vtgate #6354 +* SHOW FULL FIELDS doesn't follow routing rules #6803 + +### Other +* VReplication tablet_picker should keep trying to find a tablet until context expires #6546 +* VReplication improve reverse workflow: update cells/tablet_types #6556 +* VDiff: fix panic for tables with a unicode_loose_md5 vindex #6640 +* Vtctld UI: Add mysqld port display back to vtctld web UI #6598 #6597 +* Vtctld: Fix workflow CopyState fetching (and thus printing). #6657 +* Fix unsaved event regression #6710 +* Change tracker to use allprivs instead of dba #6720 +* Fixes long wait filter keyspace #6721 +* s3 ListBackups doesn’t work from root directory #6732 +* Vtctld: ExecuteFetchAsDba and ExecuteFetchAsAllPrivs do not escape db names. #6545 +* Can't switch on restore_from_backup on existing shard with no tables #4896 +* Refactor conn.go #6818 + +## Functionality Added or Changed ### VTGate / MySQL compatibility +* Add support for DELETE IGNORE #6722 +* Only take on simple dual queries in the vtgate #6666 +* Support mycli access to vtgate #4365 +* Add support for unicode_loose_xxhash #6457 +* Provide virtual information_schema #5394 +* information_schema.tables_schema comparison with dynamic value no longer works #6827 +* Mysqldump: Allow setting multiple variables in one statement #5401 +* Block lock function usage other than dual table #6470 +* Lock Session Support #6517 +* Make sure lookup vindexes are queryable inside transaction #6499 +* Add unicode_loose_xxhash Vindex type #6549 +* Support vindex update or delete when destination is provided by client in dml query #6554 +* Make sure to handle EXPLAIN on tablets #6579 +* Rewrite SHOW TABLES #6615 +* Make offset work in OLAP mode #6655 +* Support sql_calc_found_rows with limit in sharded keyspace #6680 +* Lock shard session heartbeat #6683 +* Mysql -ssl tag is deprecated in the later versions of mysql #6682 +* Use statement support in olap mode #6692 +* Delete row using consistent lookup vindex in where clause #6700 +* Add vtexplain support for non-evenly sharded keyspaces #6705 +* Make sure dual queries set found_rows correctly #6718 +* Add if not exists support to database ddl in parsing #6724 +* Allow Update of same vindex using same vindex lookup on consistent lookup vindex #6736 +* Update Vindex only on changes #6737 +* Add support for `SHOW (DATABASES|VITESS_SHARDS|VITESS_TABLETS) LIKE` #6750 +* 'CASCADE' support #6743 +* Mask database name #6791 +* Make sure to backtick schema names properly #6550 +* Transaction Limiter: fix quota leak if Begin() errors or if the tx killer runs #6731 +* Allow Load Data From S3 #6823 -## Functionality Added or Changed +### OLAP Functioanlity +* Allow switching between OLAP and OLTP #6691 +* Use statement support in olap mode #6692 -* Emergency Reparent Refactor #6449 - * Make emergency reparents more robust. #6206 -* vttablet: create database if not present #6490 -### VReplication +### Set Statement Support +Set statement support is added in Vitess. There are [some system variables](https://github.com/vitessio/vitess/blob/master/go/vt/sysvars/sysvars.go#L147,L190) which are disabled by default and can be enabled using flag `-enable_system_settings` on VTGate. These system variables are set on the mysql and they does not use connection pool and have their own dedicated connection. -* VReplication: _vt.vreplication source column VARBINARY->BLOB #6421 +* Disabled passthrough system variables by default. #6859 +* Allow switching workload between OLAP and OLTP #4086 #6691 +* Support for multiple session set statement syntax #6508 #6495 #6494 +* Allow enumeration in set system variables #6493 +* Handle boolean settings better #6501 +* Set statements refactored to use plan building #6487 +* Add more system settings #6486 +* Evaluate system variables #6708 -### Point-in-time Recovery -### Healthcheck -### Examples / Tutorials +### VReplication -## Documentation +* VReplication: _vt.vreplication source column VARBINARY->BLOB, allowing more tables to participate in a workflow #6421 +* VReplication and vstreamer performance and error metrics #6519, #6132 +* VReplication: Find collations for char primary keys and cast comparison during catchup #6568 +* Varchar primary keys with collations can cause vreplication to miss rows #6622 +* VReplication: Timestamp w/ Heartbeat #6635 +* VReplication: Improve few error/log messages #6669 +* VReplication: handle SET statements in the binlog stream #6772 +* VReplication: e2e Tests added to CI #6730 +* VDiff logs: additional logging around vdiff/vstreamer for observability #6684 +* VStream: experimental POC of mysql protocol #6670 +* Materialize: Support rollups using a literal value as a column #6733 +* Materialization: Ignore non-participating tables that are renamed/deleted #6778 +* Materialize: add ability for maintaining accurate table-level aggregates #6767 +* Schema Tracker: Turn off schema tracker by default #6712 (breaking change) +* Workflow: Add List-All Command #6533 +* Workflow: List -> Show, and Expand Metadata #6544 +* Refactor: Cleanup Noisy Workflow Logging #6744 +* Schema tracker: Change tracker to use the allprivs user instead of dba #6720 +* vtctl: Adding VExec and Workflow commands #6410 +* vtctl Workflow cmd: don't expect all shards to have workflow streams #6576 +* Reshard: Sort table definitions before comparing them #6765 #6738 +* Expose a shard range calculator as a vtctl command GenerateShardRanges #6751 #6752 +* VStream: Field event now has all column attributes #6525 +* VStream events do not populate field "Flags" on FIELD events #5914 +* RFC: VReplication based SplitClone #4604 +* Experimental: Mysql Protocol support for VStream #6675 +* VReplication: Add metrics around vstreamer and vreplication metrics #6787 +* Fix issues with missing tables in vstreams #6789 +* Add validations and logs to fix common issues faced during MoveTables/Reshard #6814 +* Allow multiple blacklists for master #6816 -## Build Environment Changes +### VTtablet +* VTtablet throttling #6668 +https://vitess.io/docs/reference/features/tablet-throttler/ +* TabletManager: publish displayState #6648 +* TabletManager: call setReadOnly inside ChangeTabletType #6762 +* TabletManager: change how SetReadOnly is called to avoid errors from externally managed tablets #6786 +* TabletManager: call SetReadOnly inside ChangeTabletType #6804 +* vttablet: Open and Close healthStreamer #6515 +* vttablet: create database if not present #6490 +* Restore: do not change tablet type to RESTORE if not actually performing a restore #6679 +* Restore: checkNoDB should not require tables to be present #6695 +* Heartbeat: Additional metrics/stats (lag histogram) #6528 #6634 +* VTtablet throttler feature flag: -enable-lag-throttler #6815 +* VTtablet two-phase commit design doc #6498 -## Functionality Neutral Changes +### VTorc - Orchestrator +* Orchestrator: initial import of Orchestrator #6582 +* Orchestrator: vitess mode #6613 +* Orchestrator: more changes #6714 +* Orchestrator: use contexts with timeout for remote operations #6780 +* Orchestrator: fixed orchestrator govet errors #6781 +* Orchestrator: Add clusters_to_watch flag to. Defaults to all clusters. #6821 -* SET planning #6487 -* Settings tweak backport #6488 -* Add more system settings #6486 +### Point in Time Recovery + +* PITR: Fix deadlock in ff code #6774 +* Add flags to allow PITR binlog client TLS support #6775 ### Other +* Add realtime health stats to vtctld /api/keyspace/ks/tablets API #6569 +* vtctld UI: Fix logic for displaying vindexes #6603 +* Online schema changes [#6547](https://vitess.io/docs/user-guides/schema-changes/) +* Table lifecycle management #6719, [docs](https://vitess.io/docs/reference/features/table-lifecycle/) +* Online-DDL: migration uses low priority throttling #6837 +* Emergency Reparent Refactor #6449 + * Make emergency reparents more robust. #6206 +* Reparent test failures #6706 +* Update user-facing terminology in the vtctld2 UI #6481 +* GetSchema: Batch/parallel access to underlying mysqld for lower latency #6491 +* Prometheus interface: vtgate_buffer_* metrics cardinality #6326 +* Show more vindex details in vtctld /app/schema UI #6450 +* GRPC: update enforcement policy on server to match the one from the client #6629 + +## Examples / Tutorials + +* region_sharding: working resharding example #6565 +* vtcompose/docker-compose: fix InitShardMaster #6584 +* [docker] fix tablet hostname #6509 +## Documentation + +* Replace more uses of slave with replica/replication #6520 +* Update some option docstrings for accuracy. #6590 +* Minor addition to Materialize help text. #6627 +* Remove auto-generation comment #6728 * add skip flag that can skip comparing source & destination schema when run splitdiff #6477 +* Fix and clarify some help options #6817 + +## Build Environment Changes + +* Address #6631 by reducing optimization level #6632 +* Add front-end build tooling + fix build error #6473 +* Replace gogo proto with golang #6571 +* Improve make proto #6580 +* Remove chromium hard-coding #6636 +* Docker - allow BUILD_NUMBER variable override #6628 +* Docker/lite: Fix package URLs for ubi images. #6704 +* Helm & docker/k8s update #6723 +* Fix build errors in ./go/vt/vtgate for go1.15 #6800 +* Fix build error on vcursor_impl tests on newer versions of go #6799 * [java] bump java version to 8.0.0-SNAPSHOT for next release #6478 +* Helm/docker: fix Docker builds + tag 7.0.2 #6773 + +## Functionality Neutral Changes + +* Routing cleanup: remove routeOptions #6531 +* PITR: testcase #6594 +* Replaced Error with a warning in case parsing of VT_SPAN_CONTEXT fails #6766 +* Reparent tests refactoring: setup/teardown for each test, reduce cut/paste, improve readability #6726 +* Decider: endtoend test infrastructure + tests #6770 +* Orchestrator: add more test cases #6801 +* Orchestrator: don't set DbName for tests that don't need it. #6812 +* Add unit test case to improve test coverage for go/sqltypes/named_result.go #6672 +* End to end: deflake sharding tests #6715 +* Workflow test: fix flaky test. remove obsolete code #6694 +* Add unit test for func Proto3ValuesEqual. #6649 +* Ensure tests for discoverygateway #6536 +* Convert syslog events to normal log events #6511 +* Add diagnostic logging to healthcheck. #6512 +* Healthcheck should receive healthcheck updates from all tablets in cells_to_watch #6852 +* Named columns and convenience SQL query interface #6543 +* Check http response code in vtctld API tests #6570 +* Reverting package-lock.json to the one pre-PR #6603 #6611 +* Removed sqlparser.preview to set logstats stmtType and use plan.type #6637 +* AST struct name rewording #6642 +* Fix: Remove SetMaster Query Expectation from ERS Test #6617 +* Fix path for vttablet query log in end to end test #6656 +* Fixes error log #6496 +* Add diagnostic logging to healthcheck. #6535 +* Try to install apt keys from list of different keyservers #6674 +* Trivial copy-pasta comment fixup #6592 +* Remove long-unused memcache and cacheservice #6596 +* Fix MoveTables docstring; was not valid JSON. #6606 +* Tablet gateway: unit tests #6608 +* Tablet gateway doesn't see all tablets in cells from cells_to_watch #6846 +* Add Sleep to ERS Unit Test #6610 +* Strings to enum #6729 +* Remove syslog dependency #3563 +* Operator precedence must take associativity into consideration #6758 +* Add optional ignore to delete statement #6802 +* Invalid trace payload causes vitess to fail the request and return an error #6759 +* Vttablet: minor logging fix #6564 +* Vttablet: add more logging to checkMastership #6618 From c0091beed8ff0c8a8ebfb36fdb0d72f477cd189e Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Mon, 26 Oct 2020 16:20:35 +0300 Subject: [PATCH 027/310] Added [8.0] Fix error handling in olap mode #6940 Signed-off-by: Alkin Tezuysal --- doc/releasenotes/8_0_0_release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md index f6c0b77186f..48c5f670715 100644 --- a/doc/releasenotes/8_0_0_release_notes.md +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -46,6 +46,7 @@ If a scatter query is attempting to collect and process too many rows in memory * Fix error around breaking of multi statements #6824 * Support SHOW TABLE STATUS FROM db type queries in vtgate #6354 * SHOW FULL FIELDS doesn't follow routing rules #6803 +* Fix error handling in olap mode #6940 ### Other * VReplication tablet_picker should keep trying to find a tablet until context expires #6546 From e02d668050f1eecd4930a1b5a2a22004b63f197f Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Mon, 26 Oct 2020 00:17:29 +0100 Subject: [PATCH 028/310] VDiff/Tablet Picker: fix picker retry logic to handle canceled context Signed-off-by: Rohit Nayak --- go/vt/discovery/tablet_picker.go | 8 +++++++- go/vt/wrangler/vdiff.go | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index 2c4f1f84584..7390d9f0907 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -112,7 +112,13 @@ func (tp *TabletPicker) PickForStreaming(ctx context.Context) (*topodatapb.Table // if no candidates were found, sleep and try again log.Infof("No tablet found for streaming, shard %s.%s, cells %v, tabletTypes %v, sleeping for %d seconds", tp.keyspace, tp.shard, tp.cells, tp.tabletTypes, int(GetTabletPickerRetryDelay()/1e9)) - time.Sleep(GetTabletPickerRetryDelay()) + timer := time.NewTimer(GetTabletPickerRetryDelay()) + select { + case <-ctx.Done(): + timer.Stop() + return nil, vterrors.Errorf(vtrpcpb.Code_CANCELED, "context has expired") + case <-timer.C: + } continue } // try at most len(candidate) times to find a healthy tablet diff --git a/go/vt/wrangler/vdiff.go b/go/vt/wrangler/vdiff.go index 087963cdf15..95a3e0d7768 100644 --- a/go/vt/wrangler/vdiff.go +++ b/go/vt/wrangler/vdiff.go @@ -814,7 +814,7 @@ func (td *tableDiffer) diff(ctx context.Context, wr *Wrangler) (*DiffReport, err advanceTarget := true for { if s := logSteps(int64(dr.ProcessedRows)); s != "" { - log.Infof("VDiff processed %s rows", s) + log.Infof("VDiff progress:: table %s: %s rows", td.targetTable, s) } if advanceSource { sourceRow, err = sourceExecutor.next() From b434dde81e1bd89780c6796f285918ea6fb7c1c8 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 27 Oct 2020 12:43:20 +0300 Subject: [PATCH 029/310] Minor updates in this branch Signed-off-by: Alkin Tezuysal --- doc/releasenotes/8_0_0_release_notes.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md index 48c5f670715..9ade6977b32 100644 --- a/doc/releasenotes/8_0_0_release_notes.md +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -46,7 +46,8 @@ If a scatter query is attempting to collect and process too many rows in memory * Fix error around breaking of multi statements #6824 * Support SHOW TABLE STATUS FROM db type queries in vtgate #6354 * SHOW FULL FIELDS doesn't follow routing rules #6803 -* Fix error handling in olap mode #6940 +* VDiff/Tablet Picker: fix picker retry logic to handle canceled context #6954 +* Healthcheck: Use isIncluded correctly to fix replica/rdonly routing bug #6922 ### Other * VReplication tablet_picker should keep trying to find a tablet until context expires #6546 @@ -102,6 +103,7 @@ If a scatter query is attempting to collect and process too many rows in memory ### OLAP Functioanlity * Allow switching between OLAP and OLTP #6691 * Use statement support in olap mode #6692 +* Fix error handling in olap mode #6940 ### Set Statement Support @@ -223,6 +225,10 @@ https://vitess.io/docs/reference/features/tablet-throttler/ * Fix build error on vcursor_impl tests on newer versions of go #6799 * [java] bump java version to 8.0.0-SNAPSHOT for next release #6478 * Helm/docker: fix Docker builds + tag 7.0.2 #6773 +* Docker: Upgrade to Debian Buster (release-8.0) #6888 +* Docker: Pin mysql 5.7 and 8.0 versions for xtrabackup compatibility +* Docker: Revert "Docker - upgrade to Debian Buster (release-8.0)" #6929 +* Zookeper: Download zookeeper 3.4.14 from archive site #6867 ## Functionality Neutral Changes @@ -240,7 +246,7 @@ https://vitess.io/docs/reference/features/tablet-throttler/ * Ensure tests for discoverygateway #6536 * Convert syslog events to normal log events #6511 * Add diagnostic logging to healthcheck. #6512 -* Healthcheck should receive healthcheck updates from all tablets in cells_to_watch #6852 +* Healthcheck should receive healthcheck updates from all tablets in cells_to_watch #6852 * Named columns and convenience SQL query interface #6543 * Check http response code in vtctld API tests #6570 * Reverting package-lock.json to the one pre-PR #6603 #6611 From 234a25c41b72a202a57b1bc984a38a70f603a894 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 27 Oct 2020 12:48:24 +0300 Subject: [PATCH 030/310] Vtorc comment by Sugu Signed-off-by: Alkin Tezuysal --- doc/releasenotes/8_0_0_release_notes.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md index 9ade6977b32..be216e50aa6 100644 --- a/doc/releasenotes/8_0_0_release_notes.md +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -169,6 +169,8 @@ https://vitess.io/docs/reference/features/tablet-throttler/ * VTtablet two-phase commit design doc #6498 ### VTorc - Orchestrator +Following PRs are experimental version of Vitess-native Orchestrator 'vtorc' is ready for users to try out. + * Orchestrator: initial import of Orchestrator #6582 * Orchestrator: vitess mode #6613 * Orchestrator: more changes #6714 From 72d930259cfcf7167b50542feaceed65eb84b584 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 27 Oct 2020 13:52:56 +0300 Subject: [PATCH 031/310] Updated set commentary by systay Signed-off-by: Alkin Tezuysal --- doc/releasenotes/8_0_0_release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md index be216e50aa6..26d50aab3dd 100644 --- a/doc/releasenotes/8_0_0_release_notes.md +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -107,7 +107,7 @@ If a scatter query is attempting to collect and process too many rows in memory ### Set Statement Support -Set statement support is added in Vitess. There are [some system variables](https://github.com/vitessio/vitess/blob/master/go/vt/sysvars/sysvars.go#L147,L190) which are disabled by default and can be enabled using flag `-enable_system_settings` on VTGate. These system variables are set on the mysql and they does not use connection pool and have their own dedicated connection. +Set statement support is added in Vitess. There are [some system variables](https://github.com/vitessio/vitess/blob/master/go/vt/sysvars/sysvars.go#L147,L190) which are disabled by default and can be enabled using flag `-enable_system_settings` on VTGate.These system variables are set on the backing MySQL instance, and will force the connection to be dedicated instead of part of the connection pool. * Disabled passthrough system variables by default. #6859 * Allow switching workload between OLAP and OLTP #4086 #6691 From 7a36e8685bd19d00c5720b636cf34bdefceb8d96 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Fri, 30 Oct 2020 18:39:57 +0530 Subject: [PATCH 032/310] Fixed a bug which caused the connection to not close in case of error writing an error packet Signed-off-by: GuptaManan100 --- go/mysql/conn.go | 27 +++++----- go/mysql/conn_test.go | 120 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 13 deletions(-) diff --git a/go/mysql/conn.go b/go/mysql/conn.go index bbb30d241d8..5b77ac2e742 100644 --- a/go/mysql/conn.go +++ b/go/mysql/conn.go @@ -893,14 +893,14 @@ func (c *Conn) handleComStmtSendLongData(data []byte) bool { prepare, ok := c.PrepareData[stmtID] if !ok { err := fmt.Errorf("got wrong statement id from client %v, statement ID(%v) is not found from record", c.ConnectionID, stmtID) - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } if prepare.BindVars == nil || prepare.ParamsCount == uint16(0) || paramID >= prepare.ParamsCount { err := fmt.Errorf("invalid parameter Number from client %v, statement: %v", c.ConnectionID, prepare.PrepareStmt) - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } chunk := make([]byte, len(chunkData)) @@ -936,7 +936,7 @@ func (c *Conn) handleComStmtExecute(handler Handler, data []byte) (kontinue bool } if err != nil { - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } fieldSent := false @@ -1003,14 +1003,15 @@ func (c *Conn) handleComPrepare(handler Handler, data []byte) bool { var queries []string if c.Capabilities&CapabilityClientMultiStatements != 0 { - queries, err := sqlparser.SplitStatementToPieces(query) + var err error + queries, err = sqlparser.SplitStatementToPieces(query) if err != nil { log.Errorf("Conn %v: Error splitting query: %v", c, err) - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } if len(queries) != 1 { log.Errorf("Conn %v: can not prepare multiple statements", c, err) - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } } else { queries = []string{query} @@ -1059,7 +1060,7 @@ func (c *Conn) handleComPrepare(handler Handler, data []byte) bool { fld, err := handler.ComPrepare(c, queries[0], bindVars) if err != nil { - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } if err := c.writePrepare(fld, c.PrepareData[c.StatementID]); err != nil { @@ -1132,7 +1133,7 @@ func (c *Conn) handleComQuery(handler Handler, data []byte) (kontinue bool) { queries, err = sqlparser.SplitStatementToPieces(query) if err != nil { log.Errorf("Conn %v: Error splitting query: %v", c, err) - return !c.writeErrorPacketFromErrorAndLog(err) + return c.writeErrorPacketFromErrorAndLog(err) } } else { queries = []string{query} @@ -1153,7 +1154,7 @@ func (c *Conn) handleComQuery(handler Handler, data []byte) (kontinue bool) { } func (c *Conn) execQuery(query string, handler Handler, more bool) execResult { - fieldSent := false + callbackCalled := false // sendFinished is set if the response should just be an OK packet. sendFinished := false @@ -1167,8 +1168,8 @@ func (c *Conn) execQuery(query string, handler Handler, more bool) execResult { return io.EOF } - if !fieldSent { - fieldSent = true + if !callbackCalled { + callbackCalled = true if len(qr.Fields) == 0 { sendFinished = true @@ -1189,8 +1190,8 @@ func (c *Conn) execQuery(query string, handler Handler, more bool) execResult { return c.writeRows(qr) }) - // If no field was sent, we expect an error. - if !fieldSent { + // If callback was not called, we expect an error. + if !callbackCalled { // This is just a failsafe. Should never happen. if err == nil || err == io.EOF { err = NewSQLErrorFromError(errors.New("unexpected: query ended without no results and no error")) diff --git a/go/mysql/conn_test.go b/go/mysql/conn_test.go index aa5bd2eaf45..9646ca229ca 100644 --- a/go/mysql/conn_test.go +++ b/go/mysql/conn_test.go @@ -340,6 +340,65 @@ func TestInitDbAgainstWrongDbDoesNotDropConnection(t *testing.T) { require.EqualValues(t, data[0], ErrPacket) // we should see the error here } +func TestConnectionErrorWhileWritingComQuery(t *testing.T) { + // Set the conn for the server connection to the simulated connection which always returns an error on writing + sConn := newConn(testConn{ + writeToPass: []bool{false, true}, + pos: -1, + queryPacket: []byte{0x21, 0x00, 0x00, 0x00, ComQuery, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x31}, + }) + + // this handler will return an error on the first run, and fail the test if it's run more times + errorString := make([]byte, 17000) + handler := &singleRun{t: t, err: fmt.Errorf(string(errorString))} + res := sConn.handleNextCommand(handler) + require.False(t, res, "we should beak the connection in case of error writing error packet") +} + +func TestConnectionErrorWhileWritingComStmtSendLongData(t *testing.T) { + // Set the conn for the server connection to the simulated connection which always returns an error on writing + sConn := newConn(testConn{ + writeToPass: []bool{false, true}, + pos: -1, + queryPacket: []byte{0x21, 0x00, 0x00, 0x00, ComStmtSendLongData, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x31}, + }) + + // this handler will return an error on the first run, and fail the test if it's run more times + handler := &singleRun{t: t, err: fmt.Errorf("not used")} + res := sConn.handleNextCommand(handler) + require.False(t, res, "we should beak the connection in case of error writing error packet") +} + +func TestConnectionErrorWhileWritingComPrepare(t *testing.T) { + // Set the conn for the server connection to the simulated connection which always returns an error on writing + sConn := newConn(testConn{ + writeToPass: []bool{false}, + pos: -1, + queryPacket: []byte{0x01, 0x00, 0x00, 0x00, ComPrepare}, + }) + sConn.Capabilities = sConn.Capabilities | CapabilityClientMultiStatements + // this handler will return an error on the first run, and fail the test if it's run more times + handler := &singleRun{t: t, err: fmt.Errorf("not used")} + res := sConn.handleNextCommand(handler) + require.False(t, res, "we should beak the connection in case of error writing error packet") +} + +func TestConnectionErrorWhileWritingComStmtExecute(t *testing.T) { + // Set the conn for the server connection to the simulated connection which always returns an error on writing + sConn := newConn(testConn{ + writeToPass: []bool{false}, + pos: -1, + queryPacket: []byte{0x21, 0x00, 0x00, 0x00, ComStmtExecute, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x40, 0x40, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x20, 0x31}, + }) + // this handler will return an error on the first run, and fail the test if it's run more times + handler := &singleRun{t: t, err: fmt.Errorf("not used")} + res := sConn.handleNextCommand(handler) + require.False(t, res, "we should beak the connection in case of error writing error packet") +} + type singleRun struct { hasRun bool t *testing.T @@ -380,3 +439,64 @@ func (h *singleRun) ComResetConnection(*Conn) { } var _ Handler = (*singleRun)(nil) + +type testConn struct { + writeToPass []bool + pos int + queryPacket []byte +} + +func (t testConn) Read(b []byte) (n int, err error) { + for j, i := range t.queryPacket { + b[j] = i + } + return len(b), nil +} + +func (t testConn) Write(b []byte) (n int, err error) { + t.pos = t.pos + 1 + if t.writeToPass[t.pos] { + return 0, nil + } + return 0, fmt.Errorf("error in writing to connection") +} + +func (t testConn) Close() error { + panic("implement me") +} + +func (t testConn) LocalAddr() net.Addr { + panic("implement me") +} + +func (t testConn) RemoteAddr() net.Addr { + return mockAddress{s: "a"} +} + +func (t testConn) SetDeadline(t1 time.Time) error { + panic("implement me") +} + +func (t testConn) SetReadDeadline(t1 time.Time) error { + panic("implement me") +} + +func (t testConn) SetWriteDeadline(t1 time.Time) error { + panic("implement me") +} + +var _ net.Conn = (*testConn)(nil) + +type mockAddress struct { + s string +} + +func (m mockAddress) Network() string { + return m.s +} + +func (m mockAddress) String() string { + return m.s +} + +var _ net.Addr = (*mockAddress)(nil) From 5d6add98fdb6a6916746b21740ca1b6d5993d448 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Thu, 10 Dec 2020 21:23:12 -0800 Subject: [PATCH 033/310] Initial support for storing db credentials in Vault. Signed-off-by: Jacques Grove --- go.mod | 1 + go.sum | 2 + go/cmd/vttablet/vttablet.go | 4 +- go/vt/dbconfigs/credentials.go | 97 ++++++++++++++++++++++++- go/vt/vtexplain/vtexplain_vtgate.go | 18 ++--- go/vt/vttablet/tabletmanager/tm_init.go | 6 +- 6 files changed, 115 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 1a758fefcc4..ff94130a929 100644 --- a/go.mod +++ b/go.mod @@ -60,6 +60,7 @@ require ( github.com/martini-contrib/gzip v0.0.0-20151124214156-6c035326b43f github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 github.com/mattn/go-sqlite3 v1.14.0 + github.com/mch1307/vaultlib v0.5.0 github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 github.com/mitchellh/go-testing-interface v1.14.0 // indirect github.com/mitchellh/mapstructure v1.2.3 // indirect diff --git a/go.sum b/go.sum index 62825b13b93..176818faca2 100644 --- a/go.sum +++ b/go.sum @@ -472,6 +472,8 @@ github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/ github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mch1307/vaultlib v0.5.0 h1:+tI8YCG033aVI+kAKwo0fwrUylFs+wO6DB7DM5qXJzU= +github.com/mch1307/vaultlib v0.5.0/go.mod h1:phFbO1oIDL1xTqUrNXbrAG0VdcYEKP8TNa9FJd7hFic= github.com/miekg/dns v1.0.14 h1:9jZdLNd/P4+SfEJ0TNyxYpsK8N4GtfylBLqtbYN1sbA= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU= diff --git a/go/cmd/vttablet/vttablet.go b/go/cmd/vttablet/vttablet.go index d4c6cc01edd..135f3cd3191 100644 --- a/go/cmd/vttablet/vttablet.go +++ b/go/cmd/vttablet/vttablet.go @@ -73,7 +73,7 @@ func main() { log.Exitf("failed to parse -tablet-path: %v", err) } - // config and mycnf intializations are intertwined. + // config and mycnf initializations are intertwined. config, mycnf := initConfig(tabletAlias) ts := topo.Open() @@ -106,7 +106,7 @@ func main() { VREngine: vreplication.NewEngine(config, ts, tabletAlias.Cell, mysqld), } if err := tm.Start(tablet, config.Healthcheck.IntervalSeconds.Get()); err != nil { - log.Exitf("failed to parse -tablet-path: %v", err) + log.Exitf("failed to parse -tablet-path or initialize DB credentials: %v", err) } servenv.OnClose(func() { // Close the tm so that our topo entry gets pruned properly and any diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 026c9bafd6b..8b23910de88 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -30,6 +30,9 @@ import ( "os/signal" "sync" "syscall" + "time" + + vaultapi "github.com/mch1307/vaultlib" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/log" @@ -37,11 +40,18 @@ import ( var ( // generic flags - dbCredentialsServer = flag.String("db-credentials-server", "file", "db credentials server type (use 'file' for the file implementation)") + dbCredentialsServer = flag.String("db-credentials-server", "file", "db credentials server type ('file' - file implementation; 'vault' - HashiCorp Vault implementation)") // 'file' implementation flags dbCredentialsFile = flag.String("db-credentials-file", "", "db credentials file; send SIGHUP to reload this file") + // 'vault' implementation flags + dbCredentialsVaultAddr = flag.String("db-credentials-vault-addr", "", "URL to Vault server") + dbCredentialsVaultTimeout = flag.Duration("db-credentials-vault-timeout", 10*time.Second, "Timeout for vault API operations") + dbCredentialsVaultPath = flag.String("db-credentials-vault-path", "", "Vault path to credentials JSON blob, e.g.: secret/data/prod/dbcreds") + dbCredentialsVaultTokenFile = flag.String("db-credentials-vault-tokenfile", "", "Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable") + dbCredentialsVaultCacheTTL = flag.Duration("db-credentials-vault-ttl", 30*time.Minute, "How long to cache DB credentials from the Vault server") + // ErrUnknownUser is returned by credential server when the // user doesn't exist ErrUnknownUser = errors.New("unknown user") @@ -79,6 +89,14 @@ type FileCredentialsServer struct { dbCredentials map[string][]string } +// VaultCredentialsServer implements CredentialsServer using +// a Vault backend from HashiCorp. +type VaultCredentialsServer struct { + mu sync.Mutex + dbCredsCache map[string][]string + vaultCacheExpireTicker *time.Ticker +} + // GetUserAndPassword is part of the CredentialsServer interface func (fcs *FileCredentialsServer) GetUserAndPassword(user string) (string, string, error) { fcs.mu.Lock() @@ -111,6 +129,75 @@ func (fcs *FileCredentialsServer) GetUserAndPassword(user string) (string, strin return user, passwd[0], nil } +func (vcs *VaultCredentialsServer) GetUserAndPassword(user string) (string, string, error) { + vcs.mu.Lock() + defer vcs.mu.Unlock() + + if vcs.vaultCacheExpireTicker == nil { + vcs.vaultCacheExpireTicker = time.NewTicker(*dbCredentialsVaultCacheTTL) + go func() { + for range vcs.vaultCacheExpireTicker.C { + if vcs, ok := AllCredentialsServers["vault"].(*VaultCredentialsServer); ok { + vcs.dbCredsCache = nil + } + } + }() + } + + if vcs.dbCredsCache != nil { + return user, vcs.dbCredsCache[user][0], nil + } + + if *dbCredentialsVaultAddr == "" { + return "", "", errors.New("No Vault server specified") + } + + token := os.Getenv("VAULT_TOKEN") + if *dbCredentialsVaultTokenFile != "" { + tokenBytes, err := ioutil.ReadFile(*dbCredentialsVaultTokenFile) + if err != nil { + return "", "", errors.New("No Vault token in provided filename") + } + token = string(tokenBytes) + } + + // TODO: Add: Vault CA cert; Vault client cert/key + // SNI Name; disable retries or just single retry? retry interval? + // https://www.vaultproject.io/docs/commands#environment-variables + // Basically guaranteed to work; won't instantiate until we call out + config := vaultapi.NewConfig() + config.Address = *dbCredentialsVaultAddr + config.Timeout = *dbCredentialsVaultTimeout + config.Token = token + client, _ := vaultapi.NewClient(config) + + // From here on, errors might be transient, so we use ErrUnknownUser + // for everything + secret, err := client.GetSecret(*dbCredentialsVaultPath) + if err != nil { + log.Errorf("Error in Vault server params: %v", err) + return "", "", ErrUnknownUser + } + + if secret.JSONSecret == nil { + log.Errorf("Empty DB credentials retrieved from Vault server") + return "", "", ErrUnknownUser + } + + dbCreds := make(map[string][]string) + if err = json.Unmarshal(secret.JSONSecret, &dbCreds); err != nil { + log.Errorf("Error unmarshaling DB credentials from Vault server") + return "", "", ErrUnknownUser + } + if dbCreds[user] == nil { + log.Warningf("Vault lookup for user not found: %v\n", user) + return "", "", ErrUnknownUser + } + vcs.dbCredsCache = dbCreds + + return user, dbCreds[user][0], nil +} + // WithCredentials returns a copy of the provided ConnParams that we can use // to connect, after going through the CredentialsServer. func withCredentials(cp *mysql.ConnParams) (*mysql.ConnParams, error) { @@ -122,6 +209,8 @@ func withCredentials(cp *mysql.ConnParams) (*mysql.ConnParams, error) { result.Pass = passwd case ErrUnknownUser: // we just use what we have, and will fail later anyway + // TODO: except if the actual password is empty, in which case + // things will just "work" err = nil } return &result, err @@ -129,6 +218,7 @@ func withCredentials(cp *mysql.ConnParams) (*mysql.ConnParams, error) { func init() { AllCredentialsServers["file"] = &FileCredentialsServer{} + AllCredentialsServers["vault"] = &VaultCredentialsServer{} sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGHUP) @@ -139,6 +229,11 @@ func init() { fcs.dbCredentials = nil fcs.mu.Unlock() } + if vcs, ok := AllCredentialsServers["vault"].(*VaultCredentialsServer); ok { + vcs.mu.Lock() + vcs.dbCredsCache = nil + vcs.mu.Unlock() + } } }() } diff --git a/go/vt/vtexplain/vtexplain_vtgate.go b/go/vt/vtexplain/vtexplain_vtgate.go index ccdce29a55c..c3a6cb9969a 100644 --- a/go/vt/vtexplain/vtexplain_vtgate.go +++ b/go/vt/vtexplain/vtexplain_vtgate.go @@ -112,7 +112,12 @@ func buildTopology(opts *Options, vschemaStr string, ksShardMapStr string, numSh explainTopo.TabletConns = make(map[string]*explainTablet) explainTopo.KeyspaceShards = make(map[string]map[string]*topodatapb.ShardReference) for ks, vschema := range explainTopo.Keyspaces { - shards, err := getShardRanges(ks, vschema, ksShardMap, numShardsPerKeyspace) + numShards := numShardsPerKeyspace + if !vschema.Sharded { + numShards = 1 + } + + shards, err := getShardRanges(ks, vschema, ksShardMap, numShards) if err != nil { return err } @@ -162,15 +167,10 @@ func getShardRanges(ks string, vschema *vschemapb.Keyspace, ksShardMap map[strin } - numShards := 1 - if vschema.Sharded { - numShards = numShardsPerKeyspace - } - - shards := make([]*topodatapb.ShardReference, numShards) + shards := make([]*topodatapb.ShardReference, numShardsPerKeyspace) - for i := 0; i < numShards; i++ { - kr, err := key.EvenShardsKeyRange(i, numShards) + for i := 0; i < numShardsPerKeyspace; i++ { + kr, err := key.EvenShardsKeyRange(i, numShardsPerKeyspace) if err != nil { return nil, err } diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 9af7f22d314..6c9734b3ffb 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -512,7 +512,11 @@ func (tm *TabletManager) checkMastership(ctx context.Context, si *topo.ShardInfo } func (tm *TabletManager) checkMysql(ctx context.Context) error { - if appConfig, _ := tm.DBConfigs.AppWithDB().MysqlParams(); appConfig.Host != "" { + appConfig, err := tm.DBConfigs.AppWithDB().MysqlParams() + if err != nil { + return err + } + if appConfig.Host != "" { tm.tmState.UpdateTablet(func(tablet *topodatapb.Tablet) { tablet.MysqlHostname = appConfig.Host tablet.MysqlPort = int32(appConfig.Port) From a8076783c64d746bf30430e8052fb09fe17bba14 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Wed, 16 Dec 2020 12:56:04 -0800 Subject: [PATCH 034/310] Add Vault AppRole support. Signed-off-by: Jacques Grove --- go/vt/dbconfigs/credentials.go | 96 +++++++++++++++++++++++----------- 1 file changed, 66 insertions(+), 30 deletions(-) diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 8b23910de88..5dd25b26e14 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -28,6 +28,7 @@ import ( "io/ioutil" "os" "os/signal" + "strings" "sync" "syscall" "time" @@ -46,11 +47,15 @@ var ( dbCredentialsFile = flag.String("db-credentials-file", "", "db credentials file; send SIGHUP to reload this file") // 'vault' implementation flags - dbCredentialsVaultAddr = flag.String("db-credentials-vault-addr", "", "URL to Vault server") - dbCredentialsVaultTimeout = flag.Duration("db-credentials-vault-timeout", 10*time.Second, "Timeout for vault API operations") - dbCredentialsVaultPath = flag.String("db-credentials-vault-path", "", "Vault path to credentials JSON blob, e.g.: secret/data/prod/dbcreds") - dbCredentialsVaultTokenFile = flag.String("db-credentials-vault-tokenfile", "", "Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable") - dbCredentialsVaultCacheTTL = flag.Duration("db-credentials-vault-ttl", 30*time.Minute, "How long to cache DB credentials from the Vault server") + vaultAddr = flag.String("db-credentials-vault-addr", "", "URL to Vault server") + vaultTimeout = flag.Duration("db-credentials-vault-timeout", 10*time.Second, "Timeout for vault API operations") + vaultCACert = flag.String("db-credentials-vault-tls-ca", "", "Path to CA PEM for validating Vault server certificate") + vaultPath = flag.String("db-credentials-vault-path", "", "Vault path to credentials JSON blob, e.g.: secret/data/prod/dbcreds") + vaultCacheTTL = flag.Duration("db-credentials-vault-ttl", 30*time.Minute, "How long to cache DB credentials from the Vault server") + vaultTokenFile = flag.String("db-credentials-vault-tokenfile", "", "Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable") + vaultRoleID = flag.String("db-credentials-vault-roleid", "", "Vault AppRole id; can also be passed using VAULT_ROLEID environment variable") + vaultRoleSecretIDFile = flag.String("db-credentials-vault-role-secretidfile", "", "Path to file containing Vault AppRole secret_id; can also be passed using VAULT_SECRETID environment variable") + vaultRoleMountPoint = flag.String("db-credentials-vault-role-mountpoint", "approle", "Vault AppRole mountpoint; can also be passed using VAULT_MOUNTPOINT environment variable") // ErrUnknownUser is returned by credential server when the // user doesn't exist @@ -95,6 +100,10 @@ type VaultCredentialsServer struct { mu sync.Mutex dbCredsCache map[string][]string vaultCacheExpireTicker *time.Ticker + vaultClient *vaultapi.Client + // We use a separate valid flag to allow invalidating the cache + // without destroying it, in case Vault is temp down. + cacheValid bool } // GetUserAndPassword is part of the CredentialsServer interface @@ -129,51 +138,65 @@ func (fcs *FileCredentialsServer) GetUserAndPassword(user string) (string, strin return user, passwd[0], nil } +// GetUserAndPassword for Vault implementation func (vcs *VaultCredentialsServer) GetUserAndPassword(user string) (string, string, error) { vcs.mu.Lock() defer vcs.mu.Unlock() if vcs.vaultCacheExpireTicker == nil { - vcs.vaultCacheExpireTicker = time.NewTicker(*dbCredentialsVaultCacheTTL) + vcs.vaultCacheExpireTicker = time.NewTicker(*vaultCacheTTL) go func() { for range vcs.vaultCacheExpireTicker.C { if vcs, ok := AllCredentialsServers["vault"].(*VaultCredentialsServer); ok { - vcs.dbCredsCache = nil + vcs.cacheValid = false } } }() } - if vcs.dbCredsCache != nil { + if vcs.cacheValid && vcs.dbCredsCache != nil { return user, vcs.dbCredsCache[user][0], nil } - if *dbCredentialsVaultAddr == "" { + if *vaultAddr == "" { return "", "", errors.New("No Vault server specified") } - token := os.Getenv("VAULT_TOKEN") - if *dbCredentialsVaultTokenFile != "" { - tokenBytes, err := ioutil.ReadFile(*dbCredentialsVaultTokenFile) - if err != nil { - return "", "", errors.New("No Vault token in provided filename") - } - token = string(tokenBytes) + token, err := readFromFile(*vaultTokenFile) + if err != nil { + return "", "", errors.New("No Vault token in provided filename") + } + secretID, err := readFromFile(*vaultRoleSecretIDFile) + if err != nil { + return "", "", errors.New("No Vault secret_id in provided filename") } - - // TODO: Add: Vault CA cert; Vault client cert/key - // SNI Name; disable retries or just single retry? retry interval? - // https://www.vaultproject.io/docs/commands#environment-variables - // Basically guaranteed to work; won't instantiate until we call out - config := vaultapi.NewConfig() - config.Address = *dbCredentialsVaultAddr - config.Timeout = *dbCredentialsVaultTimeout - config.Token = token - client, _ := vaultapi.NewClient(config) // From here on, errors might be transient, so we use ErrUnknownUser - // for everything - secret, err := client.GetSecret(*dbCredentialsVaultPath) + // for everything, so we get retries + if vcs.vaultClient == nil { + config := vaultapi.NewConfig() + config.Address = *vaultAddr + config.Timeout = *vaultTimeout + config.CACert = *vaultCACert + config.Token = token + config.AppRoleCredentials.RoleID = *vaultRoleID + config.AppRoleCredentials.SecretID = secretID + config.AppRoleCredentials.MountPoint = *vaultRoleMountPoint + if config.CACert != "" { + // If we provide a CA, ensure we actually use it + config.InsecureSSL = false + } + + var err error + vcs.vaultClient, err = vaultapi.NewClient(config) + if err != nil || vcs.vaultClient == nil { + log.Errorf("Error in vault client initialization, will retry: %v", err) + vcs.vaultClient = nil + return "", "", ErrUnknownUser + } + } + + secret, err := vcs.vaultClient.GetSecret(*vaultPath) if err != nil { log.Errorf("Error in Vault server params: %v", err) return "", "", ErrUnknownUser @@ -193,11 +216,24 @@ func (vcs *VaultCredentialsServer) GetUserAndPassword(user string) (string, stri log.Warningf("Vault lookup for user not found: %v\n", user) return "", "", ErrUnknownUser } - vcs.dbCredsCache = dbCreds + log.Infof("Vault client status: %s", vcs.vaultClient.GetStatus()) + vcs.dbCredsCache = dbCreds + vcs.cacheValid = true return user, dbCreds[user][0], nil } +func readFromFile(filePath string) (string, error) { + if filePath == "" { + return "", nil + } + fileBytes, err := ioutil.ReadFile(filePath) + if err != nil { + return "", err + } + return strings.TrimSpace(string(fileBytes)), nil +} + // WithCredentials returns a copy of the provided ConnParams that we can use // to connect, after going through the CredentialsServer. func withCredentials(cp *mysql.ConnParams) (*mysql.ConnParams, error) { @@ -209,7 +245,7 @@ func withCredentials(cp *mysql.ConnParams) (*mysql.ConnParams, error) { result.Pass = passwd case ErrUnknownUser: // we just use what we have, and will fail later anyway - // TODO: except if the actual password is empty, in which case + // except if the actual password is empty, in which case // things will just "work" err = nil } From 4a677b8fd0a4ef0ef67975ad97b9d6ff86a68dd9 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Wed, 30 Dec 2020 11:29:59 -0800 Subject: [PATCH 035/310] * First cut of Vault support for vtgate credentials * Switch to forked vaultlib; for fixed token renewal Signed-off-by: Jacques Grove --- go.mod | 2 +- go/cmd/vtgate/plugin_auth_vault.go | 28 +++ go/mysql/auth_server_vault.go | 280 ++++++++++++++++++++++++++++ go/mysql/auth_server_vault_test.go | 47 +++++ go/vt/dbconfigs/credentials.go | 2 +- go/vt/vtgate/plugin_mysql_server.go | 2 +- 6 files changed, 358 insertions(+), 3 deletions(-) create mode 100644 go/cmd/vtgate/plugin_auth_vault.go create mode 100644 go/mysql/auth_server_vault.go create mode 100644 go/mysql/auth_server_vault_test.go diff --git a/go.mod b/go.mod index ff94130a929..4cb9a6c4e82 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/DataDog/datadog-go v2.2.0+incompatible github.com/GeertJohan/go.rice v1.0.0 github.com/PuerkitoBio/goquery v1.5.1 + github.com/aquarapid/vaultlib v0.5.1 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 github.com/aws/aws-sdk-go v1.28.8 @@ -60,7 +61,6 @@ require ( github.com/martini-contrib/gzip v0.0.0-20151124214156-6c035326b43f github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 github.com/mattn/go-sqlite3 v1.14.0 - github.com/mch1307/vaultlib v0.5.0 github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 github.com/mitchellh/go-testing-interface v1.14.0 // indirect github.com/mitchellh/mapstructure v1.2.3 // indirect diff --git a/go/cmd/vtgate/plugin_auth_vault.go b/go/cmd/vtgate/plugin_auth_vault.go new file mode 100644 index 00000000000..b43e471be36 --- /dev/null +++ b/go/cmd/vtgate/plugin_auth_vault.go @@ -0,0 +1,28 @@ +/* +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 agreedto 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 main + +// This plugin imports InitAuthServerVault to register the HashiCorp Vault implementation of AuthServer. + +import ( + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/vt/vtgate" +) + +func init() { + vtgate.RegisterPluginInitializer(func() { mysql.InitAuthServerVault() }) +} diff --git a/go/mysql/auth_server_vault.go b/go/mysql/auth_server_vault.go new file mode 100644 index 00000000000..f94367712bd --- /dev/null +++ b/go/mysql/auth_server_vault.go @@ -0,0 +1,280 @@ +/* +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 mysql + +import ( + "bytes" + "flag" + "fmt" + "io/ioutil" + "net" + "os" + "os/signal" + "strings" + "sync" + "syscall" + "time" + + vaultapi "github.com/aquarapid/vaultlib" + + "vitess.io/vitess/go/vt/log" +) + +var ( + vaultAddr = flag.String("mysql_auth_vault_addr", "", "TODO") + vaultTimeout = flag.Duration("mysql_auth_vault_timeout", 10*time.Second, "TODO") + vaultCACert = flag.String("mysql_auth_vault_tls_ca", "", "Path to CA PEM for validating Vault server certificate") + vaultPath = flag.String("mysql_auth_vault_path", "", "Vault path to vtgate credentials JSON blob, e.g.: secret/data/prod/vtgatecreds") + vaultCacheTTL = flag.Duration("mysql_auth_vault_ttl", 30*time.Minute, "How long to cache vtgate credentials from the Vault server") + vaultTokenFile = flag.String("mysql_auth_vault_tokenfile", "", "Path to file containing Vault auth token; token can also be passed using VAULT_TOKEN environment variable") + vaultRoleID = flag.String("mysql_auth_vault_roleid", "", "Vault AppRole id; can also be passed using VAULT_ROLEID environment variable") + vaultRoleSecretIDFile = flag.String("mysql_auth_vault_role_secretidfile", "", "Path to file containing Vault AppRole secret_id; can also be passed using VAULT_SECRETID environment variable") + vaultRoleMountPoint = flag.String("mysql_auth_vault_role_mountpoint", "approle", "Vault AppRole mountpoint; can also be passed using VAULT_MOUNTPOINT environment variable") +) + +// AuthServerVault implements AuthServer with a config loaded from Vault. +type AuthServerVault struct { + mu sync.Mutex + // method can be set to: + // - MysqlNativePassword + // - MysqlClearPassword + // - MysqlDialog + // It defaults to MysqlNativePassword. + method string + // users, passwords and user data + // We use the same JSON format as for -mysql_auth_server_static + // Acts as a cache for the in-Vault data + entries map[string][]*AuthServerStaticEntry + vaultCacheExpireTicker *time.Ticker + vaultClient *vaultapi.Client + vaultPath string + vaultTTL time.Duration + + sigChan chan os.Signal +} + +// InitAuthServerVault - entrypoint for initialization of Vault AuthServer implementation +func InitAuthServerVault() { + // Check critical parameters. + if *vaultAddr == "" { + log.Infof("Not configuring AuthServerVault, as -mysql_auth_vault_addr is empty.") + return + } + if *vaultPath == "" { + log.Exitf("If using Vault auth server, -mysql_auth_vault_path is required.") + } + + registerAuthServerVault(*vaultAddr, *vaultTimeout, *vaultCACert, *vaultPath, *vaultCacheTTL, *vaultTokenFile, *vaultRoleID, *vaultRoleSecretIDFile, *vaultRoleMountPoint) +} + +func registerAuthServerVault(addr string, timeout time.Duration, caCertPath string, path string, ttl time.Duration, tokenFilePath string, roleID string, secretIDPath string, roleMountPoint string) { + authServerVault, err := newAuthServerVault(addr, timeout, caCertPath, path, ttl, tokenFilePath, roleID, secretIDPath, roleMountPoint) + if err != nil { + log.Exitf("%s", err) + } + RegisterAuthServerImpl("vault", authServerVault) +} + +func newAuthServerVault(addr string, timeout time.Duration, caCertPath string, path string, ttl time.Duration, tokenFilePath string, roleID string, secretIDPath string, roleMountPoint string) (*AuthServerVault, error) { + // Validate more parameters + token, err := readFromFile(tokenFilePath) + if err != nil { + return nil, fmt.Errorf("No Vault token in provided filename for -mysql_auth_vault_tokenfile") + } + secretID, err := readFromFile(secretIDPath) + if err != nil { + return nil, fmt.Errorf("No Vault secret_id in provided filename for -mysql_auth_vault_role_secretidfile") + } + + config := vaultapi.NewConfig() + config.Address = addr + config.Timeout = timeout + config.CACert = caCertPath + config.Token = token + config.AppRoleCredentials.RoleID = roleID + config.AppRoleCredentials.SecretID = secretID + config.AppRoleCredentials.MountPoint = roleMountPoint + if config.CACert != "" { + // If we provide a CA, ensure we actually use it + config.InsecureSSL = false + } + + client, err := vaultapi.NewClient(config) + if err != nil || client == nil { + log.Errorf("Error in vault client initialization, will retry: %v", err) + } + + a := &AuthServerVault{ + vaultClient: client, + vaultPath: path, + vaultTTL: ttl, + method: MysqlNativePassword, + entries: make(map[string][]*AuthServerStaticEntry), + } + + a.reloadVault() + a.installSignalHandlers() + return a, nil +} + +// Caller must hold the a.mu mutex. +func (a *AuthServerVault) setTTLTicker(ttl time.Duration) { + if a.vaultCacheExpireTicker != nil { + a.vaultCacheExpireTicker.Stop() + } + a.vaultCacheExpireTicker = time.NewTicker(ttl) + go func() { + for range a.vaultCacheExpireTicker.C { + a.sigChan <- syscall.SIGHUP + } + }() +} + +// Reload JSON auth key from Vault. Return true if successful, false if not +func (a *AuthServerVault) reloadVault() error { + a.mu.Lock() + defer a.mu.Unlock() + secret, err := a.vaultClient.GetSecret(a.vaultPath) + a.setTTLTicker(10 * time.Second) // Reload frequently on error + + if err != nil { + return fmt.Errorf("Error in vtgate Vault auth server params: %v", err) + } + + if secret.JSONSecret == nil { + return fmt.Errorf("Empty vtgate credentials retrieved from Vault server") + } + + entries := make(map[string][]*AuthServerStaticEntry) + if err := parseConfig(secret.JSONSecret, &entries); err != nil { + return fmt.Errorf("Error parsing vtgate Vault auth server config: %v", err) + } + if len(entries) == 0 { + return fmt.Errorf("vtgate credentials from Vault empty! Not updating previously cached values") + } + + log.Infof("reloadVault(): success. Client status: %s", a.vaultClient.GetStatus()) + a.entries = entries + a.setTTLTicker(a.vaultTTL) + return nil +} + +func (a *AuthServerVault) installSignalHandlers() { + a.mu.Lock() + defer a.mu.Unlock() + + a.sigChan = make(chan os.Signal, 1) + signal.Notify(a.sigChan, syscall.SIGHUP) + go func() { + for range a.sigChan { + err := a.reloadVault() + if err != nil { + log.Errorf("%s", err) + } + + } + }() +} + +func (a *AuthServerVault) close() { + log.Warningf("Closing AuthServerVault instance.") + a.mu.Lock() + defer a.mu.Unlock() + if a.vaultCacheExpireTicker != nil { + a.vaultCacheExpireTicker.Stop() + } + if a.sigChan != nil { + signal.Stop(a.sigChan) + } +} + +// AuthMethod is part of the AuthServer interface. +func (a *AuthServerVault) AuthMethod(user string) (string, error) { + return a.method, nil +} + +// Salt is part of the AuthServer interface. +func (a *AuthServerVault) Salt() ([]byte, error) { + return NewSalt() +} + +// ValidateHash is part of the AuthServer interface. +func (a *AuthServerVault) ValidateHash(salt []byte, user string, authResponse []byte, remoteAddr net.Addr) (Getter, error) { + a.mu.Lock() + userEntries, ok := a.entries[user] + a.mu.Unlock() + + if !ok { + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) + } + + for _, entry := range userEntries { + if entry.MysqlNativePassword != "" { + isPass := isPassScrambleMysqlNativePassword(authResponse, salt, entry.MysqlNativePassword) + if matchSourceHost(remoteAddr, entry.SourceHost) && isPass { + return &StaticUserData{entry.UserData, entry.Groups}, nil + } + } else { + computedAuthResponse := ScramblePassword(salt, []byte(entry.Password)) + // Validate the password. + if matchSourceHost(remoteAddr, entry.SourceHost) && bytes.Equal(authResponse, computedAuthResponse) { + return &StaticUserData{entry.UserData, entry.Groups}, nil + } + } + } + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) +} + +// Negotiate is part of the AuthServer interface. +// It will be called if method is anything else than MysqlNativePassword. +// We only recognize MysqlClearPassword and MysqlDialog here. +func (a *AuthServerVault) Negotiate(c *Conn, user string, remoteAddr net.Addr) (Getter, error) { + // Finish the negotiation. + password, err := AuthServerNegotiateClearOrDialog(c, a.method) + if err != nil { + return nil, err + } + + a.mu.Lock() + userEntries, ok := a.entries[user] + a.mu.Unlock() + + if !ok { + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) + } + for _, entry := range userEntries { + // Validate the password. + if matchSourceHost(remoteAddr, entry.SourceHost) && entry.Password == password { + return &StaticUserData{entry.UserData, entry.Groups}, nil + } + } + return &StaticUserData{}, NewSQLError(ERAccessDeniedError, SSAccessDeniedError, "Access denied for user '%v'", user) +} + +// We ignore most errors here, to allow us to retry cleanly +// or ignore the cases where the input is not passed by file, but via env +func readFromFile(filePath string) (string, error) { + if filePath == "" { + return "", nil + } + fileBytes, err := ioutil.ReadFile(filePath) + if err != nil { + log.Errorf("Could not read file: %s", filePath) + return "", err + } + return strings.TrimSpace(string(fileBytes)), nil +} diff --git a/go/mysql/auth_server_vault_test.go b/go/mysql/auth_server_vault_test.go new file mode 100644 index 00000000000..34a8ff9352e --- /dev/null +++ b/go/mysql/auth_server_vault_test.go @@ -0,0 +1,47 @@ +/* +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 mysql + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestErrorConditions(t *testing.T) { + // Bad token file path + _, err := newAuthServerVault("localhost", 1*time.Second, "", "/path/to/secret/in/vault", 10*time.Second, "/tmp/this_file_does_not_exist", "", "", "") + assert.Contains(t, err.Error(), "No Vault token in provided filename") + + // Bad secretID file path + _, err = newAuthServerVault("localhost", 1*time.Second, "", "/path/to/secret/in/vault", 10*time.Second, "", "", "/tmp/this_file_does_not_exist", "") + assert.Contains(t, err.Error(), "No Vault secret_id in provided filename") + + // Bad init ; but we should just retry + a, err := newAuthServerVault("https://localhost:828", 1*time.Second, "", "/path/to/secret/in/vault", 10*time.Second, "", "", "", "") + assert.NotEqual(t, a, nil) + assert.Equal(t, err, nil) + + // Test reload, should surface error, since we don't have a Vault + // instance on port 828 + err = a.reloadVault() + assert.Contains(t, err.Error(), "Error in vtgate Vault auth server params") + assert.Contains(t, err.Error(), "connection refused") + + a.close() +} diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 5dd25b26e14..5dceefc2f38 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -33,7 +33,7 @@ import ( "syscall" "time" - vaultapi "github.com/mch1307/vaultlib" + vaultapi "github.com/aquarapid/vaultlib" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/log" diff --git a/go/vt/vtgate/plugin_mysql_server.go b/go/vt/vtgate/plugin_mysql_server.go index df850fe2f0a..5ee65dd5c45 100644 --- a/go/vt/vtgate/plugin_mysql_server.go +++ b/go/vt/vtgate/plugin_mysql_server.go @@ -54,7 +54,7 @@ var ( mysqlServerBindAddress = flag.String("mysql_server_bind_address", "", "Binds on this address when listening to MySQL binary protocol. Useful to restrict listening to 'localhost' only for instance.") mysqlServerSocketPath = flag.String("mysql_server_socket_path", "", "This option specifies the Unix socket file to use when listening for local connections. By default it will be empty and it won't listen to a unix socket") mysqlTCPVersion = flag.String("mysql_tcp_version", "tcp", "Select tcp, tcp4, or tcp6 to control the socket type.") - mysqlAuthServerImpl = flag.String("mysql_auth_server_impl", "static", "Which auth server implementation to use.") + mysqlAuthServerImpl = flag.String("mysql_auth_server_impl", "static", "Which auth server implementation to use. Options: none, ldap, clientcert, static, vault.") mysqlAllowClearTextWithoutTLS = flag.Bool("mysql_allow_clear_text_without_tls", false, "If set, the server will allow the use of a clear text password over non-SSL connections.") mysqlServerVersion = flag.String("mysql_server_version", mysql.DefaultServerVersion, "MySQL server version to advertise.") mysqlProxyProtocol = flag.Bool("proxy_protocol", false, "Enable HAProxy PROXY protocol on MySQL listener socket") From 43e50be72346ce1a5cc5efde6ae933b1c669288f Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Thu, 31 Dec 2020 16:54:40 -0800 Subject: [PATCH 036/310] Add end-to-end test for vtgate and tablet Vault support Signed-off-by: Jacques Grove --- go/test/endtoend/vault/ca.pem | 20 ++ go/test/endtoend/vault/dbcreds_policy.hcl | 28 ++ go/test/endtoend/vault/dbcreds_secret.json | 17 + go/test/endtoend/vault/vault-cert.pem | 87 +++++ go/test/endtoend/vault/vault-key.pem | 28 ++ go/test/endtoend/vault/vault-setup.sh | 46 +++ go/test/endtoend/vault/vault.hcl | 21 ++ go/test/endtoend/vault/vault_server.go | 129 ++++++++ go/test/endtoend/vault/vault_test.go | 308 ++++++++++++++++++ .../endtoend/vault/vtgatecreds_secret.json | 7 + 10 files changed, 691 insertions(+) create mode 100644 go/test/endtoend/vault/ca.pem create mode 100644 go/test/endtoend/vault/dbcreds_policy.hcl create mode 100644 go/test/endtoend/vault/dbcreds_secret.json create mode 100644 go/test/endtoend/vault/vault-cert.pem create mode 100644 go/test/endtoend/vault/vault-key.pem create mode 100644 go/test/endtoend/vault/vault-setup.sh create mode 100644 go/test/endtoend/vault/vault.hcl create mode 100644 go/test/endtoend/vault/vault_server.go create mode 100644 go/test/endtoend/vault/vault_test.go create mode 100644 go/test/endtoend/vault/vtgatecreds_secret.json diff --git a/go/test/endtoend/vault/ca.pem b/go/test/endtoend/vault/ca.pem new file mode 100644 index 00000000000..2c19d3b0ca3 --- /dev/null +++ b/go/test/endtoend/vault/ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIUGTcQb8NrTsJxh3Ef2lGd4YFDN7owDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKVGVzdGluZyBDQTAeFw0yMTAxMDEwMDAzMTBaFw0zMDEy +MzAwMDAzMTBaMBUxEzARBgNVBAMMClRlc3RpbmcgQ0EwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDE42b11YcFIPmUHzRo0GhUaulwQ78RDVQfCy3WrWWt +w1Fv5F7xSiONl+eCRDTHUD1Lt4lMee1zFKySXg+kSRLzrrCuDfsK8MZ/4fKcrRVS +XliI9eS0QZijczYzlwgIjodnoAqcSmMJi0inC3oRTDu2/zRUEMKCtM4F2A7Fh1vu +BEdO6b0SmIGBFAb1Eqn++U9dES1xhMrwESy81Vs/C9qyclZCqaFqtEUBgepqkTGQ +stpMqdubhrJxYq4Lj3dcN+N/jubpPTHPJZrHO7fIJiRQaBUrqlLxUafqHvOrvwEG +aqZgaNT34ylCOdYtzuJpeHjZ1ptewMEdqXmHKC3gmpNDAgMBAAGjgY8wgYwwHQYD +VR0OBBYEFCgXq7LJ5AI40DYi6rnQH/suQ4srMFAGA1UdIwRJMEeAFCgXq7LJ5AI4 +0DYi6rnQH/suQ4sroRmkFzAVMRMwEQYDVQQDDApUZXN0aW5nIENBghQZNxBvw2tO +wnGHcR/aUZ3hgUM3ujAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG +9w0BAQsFAAOCAQEAHDqcA40Q56giI8JybsE56+uk89MCfbamuk54/p2dIlKxP6sd +W7y9zhFCPJFH4LUj9Dyp9mxmafmxUtnFGRYRvnOs3peZbwQo2He86uw4TCxtrT6y +0lxNyxfoCtnzQUl5XGxl6WC0RsotUWp2paHfuh2YDQi8wMOa9CIczS+XZpVV7ByS +y0cvyl+1Hc6MaIsQRf8WERIx+rpG4qWwDeE0vqelRLoLpud1t+g4qe/o3YGWO1g3 ++fUExbhlqqo/DwYn4acnkTZJnZNyKSAQe9GtKwLXmpZSjHeea+dY4Ukdri5DlEpQ +MLDVIe6eFjtcrzPbdESKCpnb+tYP1epizj87Xw== +-----END CERTIFICATE----- diff --git a/go/test/endtoend/vault/dbcreds_policy.hcl b/go/test/endtoend/vault/dbcreds_policy.hcl new file mode 100644 index 00000000000..1b0a768fb34 --- /dev/null +++ b/go/test/endtoend/vault/dbcreds_policy.hcl @@ -0,0 +1,28 @@ +# Allow tokens to look up their own properties +path "auth/token/lookup-self" { + capabilities = ["read"] +} + +# Allow tokens to renew themselves +path "auth/token/renew-self" { + capabilities = ["update"] +} + +# Allow tokens to revoke themselves +path "auth/token/revoke-self" { + capabilities = ["update"] +} + +# Allow a token to look up its own capabilities on a path +path "sys/capabilities-self" { + capabilities = ["update"] +} + +path "kv/data/prod/dbcreds" { + capabilities = ["read"] +} + +path "kv/data/prod/vtgatecreds" { + capabilities = ["read"] +} + diff --git a/go/test/endtoend/vault/dbcreds_secret.json b/go/test/endtoend/vault/dbcreds_secret.json new file mode 100644 index 00000000000..96fff38bdcd --- /dev/null +++ b/go/test/endtoend/vault/dbcreds_secret.json @@ -0,0 +1,17 @@ +{ + "vt_app": [ + "password" + ], + "vt_dba": [ + "password" + ], + "vt_repl": [ + "password" + ], + "vt_appdebug": [ + "password" + ], + "vt_filtered": [ + "password" + ] +} diff --git a/go/test/endtoend/vault/vault-cert.pem b/go/test/endtoend/vault/vault-cert.pem new file mode 100644 index 00000000000..79dc973ca2b --- /dev/null +++ b/go/test/endtoend/vault/vault-cert.pem @@ -0,0 +1,87 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e8:d3:99:40:87:c1:7d:f3:93:7f:4f:da:96:0e:26:86 + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=Testing CA + Validity + Not Before: Jan 1 00:04:15 2021 GMT + Not After : Dec 29 00:04:15 2030 GMT + Subject: CN=vault-server + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:bb:96:88:43:7f:c7:4b:9a:e7:4c:1a:62:fc:c0: + 56:cb:1e:f7:42:d6:ca:18:16:41:22:f4:ca:ee:98: + c9:32:44:56:fa:06:54:5f:a1:2c:0a:1a:1b:7d:17: + f6:b9:cc:c6:c6:cd:a4:23:1d:03:c3:d5:2b:a7:4c: + ed:37:22:22:91:11:3f:96:40:f4:26:ce:e0:db:be: + f4:10:5d:7b:ca:91:22:78:33:2c:22:95:5f:98:c7: + 69:ce:33:6b:f7:f0:4f:8e:b1:9a:da:63:a5:89:64: + ce:c8:24:fb:56:29:f5:a5:14:32:18:46:20:5a:73: + 77:42:bc:1d:90:52:5e:6a:55:30:46:ee:4d:24:bb: + 93:85:6b:92:19:09:f5:25:0c:f1:02:ac:eb:41:85: + 55:3b:2c:d1:92:a1:7f:73:d7:5e:3a:40:f6:ff:63: + 3d:f7:b6:7c:f0:ca:bb:ae:25:7c:2e:fc:e2:95:55: + a6:73:3a:57:bb:70:d4:f6:0a:45:3c:46:87:f0:4f: + bf:41:62:f3:ff:cf:b6:64:7f:3d:58:69:e4:a1:96: + 24:eb:36:d2:94:83:14:75:5f:6e:e8:3d:f5:2c:3f: + 45:8b:7a:c6:c6:a8:5f:75:50:d1:b8:c8:d3:c9:51: + 94:e9:6b:35:28:1d:af:1f:13:0d:03:a3:3d:46:eb: + a9:bd + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 2C:5F:48:C0:DD:04:AE:62:87:37:5E:15:96:B6:98:61:41:1F:4C:7F + X509v3 Authority Key Identifier: + keyid:28:17:AB:B2:C9:E4:02:38:D0:36:22:EA:B9:D0:1F:FB:2E:43:8B:2B + DirName:/CN=Testing CA + serial:19:37:10:6F:C3:6B:4E:C2:71:87:71:1F:DA:51:9D:E1:81:43:37:BA + + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Key Usage: + Digital Signature, Key Encipherment + X509v3 Subject Alternative Name: + DNS:localhost, IP Address:127.0.0.1 + Signature Algorithm: sha256WithRSAEncryption + 70:11:fa:36:28:6b:0a:dc:7c:f5:2c:7e:a5:1a:e0:3c:c0:0d: + 0d:a2:2f:ed:50:71:79:46:0b:e9:af:d4:6b:f8:b0:95:f0:7e: + fc:9c:01:cd:57:92:27:46:3b:96:27:9b:2b:bc:d5:79:7f:fa: + 2b:02:f0:92:39:04:b8:3a:a1:09:2c:10:bf:48:8f:f9:43:31: + d5:d4:87:15:7f:82:72:ff:93:79:4f:02:53:cc:fd:e4:7d:c4: + 50:df:dd:59:86:66:dd:4a:ea:17:ce:b4:d9:9c:ed:b0:e0:13: + 22:66:58:95:33:46:af:5b:a6:fa:22:ac:aa:ce:dd:05:0d:85: + 68:b0:4a:72:97:a8:3a:39:3e:1d:79:1b:98:f6:a9:6e:35:ff: + 9c:0f:56:7c:65:52:8a:55:b7:6f:4f:90:3d:9b:6a:b0:45:56: + 74:80:c1:de:da:10:c2:d1:1b:52:9f:32:4f:a1:0f:90:28:02: + cb:2b:ab:fc:9a:18:a6:c8:c6:15:ba:55:f5:69:23:96:c2:c0: + c7:71:a5:c2:29:17:f7:ab:4a:a0:a5:58:e5:66:1d:c0:e1:e2: + 6e:05:7b:a9:dd:a6:19:9c:4f:ee:01:e4:a5:e8:4d:b5:2a:0f: + 42:af:5f:9b:b2:ab:c3:6d:4b:c9:5c:b9:7d:36:21:ce:99:2f: + 7a:0b:10:0d +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgIRAOjTmUCHwX3zk39P2pYOJoYwDQYJKoZIhvcNAQELBQAw +FTETMBEGA1UEAwwKVGVzdGluZyBDQTAeFw0yMTAxMDEwMDA0MTVaFw0zMDEyMjkw +MDA0MTVaMBcxFTATBgNVBAMMDHZhdWx0LXNlcnZlcjCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALuWiEN/x0ua50waYvzAVsse90LWyhgWQSL0yu6YyTJE +VvoGVF+hLAoaG30X9rnMxsbNpCMdA8PVK6dM7TciIpERP5ZA9CbO4Nu+9BBde8qR +IngzLCKVX5jHac4za/fwT46xmtpjpYlkzsgk+1Yp9aUUMhhGIFpzd0K8HZBSXmpV +MEbuTSS7k4VrkhkJ9SUM8QKs60GFVTss0ZKhf3PXXjpA9v9jPfe2fPDKu64lfC78 +4pVVpnM6V7tw1PYKRTxGh/BPv0Fi8//PtmR/PVhp5KGWJOs20pSDFHVfbug99Sw/ +RYt6xsaoX3VQ0bjI08lRlOlrNSgdrx8TDQOjPUbrqb0CAwEAAaOBvTCBujAJBgNV +HRMEAjAAMB0GA1UdDgQWBBQsX0jA3QSuYoc3XhWWtphhQR9MfzBQBgNVHSMESTBH +gBQoF6uyyeQCONA2Iuq50B/7LkOLK6EZpBcwFTETMBEGA1UEAwwKVGVzdGluZyBD +QYIUGTcQb8NrTsJxh3Ef2lGd4YFDN7owEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYD +VR0PBAQDAgWgMBoGA1UdEQQTMBGCCWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0B +AQsFAAOCAQEAcBH6NihrCtx89Sx+pRrgPMANDaIv7VBxeUYL6a/Ua/iwlfB+/JwB +zVeSJ0Y7liebK7zVeX/6KwLwkjkEuDqhCSwQv0iP+UMx1dSHFX+Ccv+TeU8CU8z9 +5H3EUN/dWYZm3UrqF8602ZztsOATImZYlTNGr1um+iKsqs7dBQ2FaLBKcpeoOjk+ +HXkbmPapbjX/nA9WfGVSilW3b0+QPZtqsEVWdIDB3toQwtEbUp8yT6EPkCgCyyur +/JoYpsjGFbpV9WkjlsLAx3GlwikX96tKoKVY5WYdwOHibgV7qd2mGZxP7gHkpehN +tSoPQq9fm7Krw21LyVy5fTYhzpkvegsQDQ== +-----END CERTIFICATE----- diff --git a/go/test/endtoend/vault/vault-key.pem b/go/test/endtoend/vault/vault-key.pem new file mode 100644 index 00000000000..bc1c7905a9b --- /dev/null +++ b/go/test/endtoend/vault/vault-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7lohDf8dLmudM +GmL8wFbLHvdC1soYFkEi9MrumMkyRFb6BlRfoSwKGht9F/a5zMbGzaQjHQPD1Sun +TO03IiKRET+WQPQmzuDbvvQQXXvKkSJ4MywilV+Yx2nOM2v38E+OsZraY6WJZM7I +JPtWKfWlFDIYRiBac3dCvB2QUl5qVTBG7k0ku5OFa5IZCfUlDPECrOtBhVU7LNGS +oX9z1146QPb/Yz33tnzwyruuJXwu/OKVVaZzOle7cNT2CkU8RofwT79BYvP/z7Zk +fz1YaeShliTrNtKUgxR1X27oPfUsP0WLesbGqF91UNG4yNPJUZTpazUoHa8fEw0D +oz1G66m9AgMBAAECggEAWUDASM1tN63WS0Fqw7OIGFD9eJHVyiwchdNPEsMjR4V4 +lLGaR33aBFxzo8tZGwIxublyVTqi5fRxNsLFQyw8oiVAye7Ru/1Gw4dRfM/d7H2t +lt9SKopD199ZmkChKHDwiYY7lZk/0+Vg9Z2S8GY6eHbpdt822ZKCtf/nWRm3zoM1 +THvNEIwok6Rw85AYUaoKP8RsWsVh5thZKQyptIv3J4b2EFkl/mNWSSQOZDde8CUg +N5wkZL/FSZ6Nx7Fqs6Y76DfVweDUYy/tazj7OO9VvqJk6Wq2z40KoPYVLebpNKJ4 +mw+8sj7Hq91MT/oFzvvcP7FEIqnZBdB461dwXTcEgQKBgQDedI1c5aZ4PtHSLLqr +jsxqC2zOxt5eE+b093kFc9vQ92pbtY+nc0AhM6yN90q4jD0g4Ch832rvv1TXyNTc +TcYq187mvLI29Mprt0R3N9YHUNV6Iyc1d3o13RXqUqW67TrTx3ankn40gMy6Vqbg +3Jt6tetGoH6FfSFpOXRZYyIxLQKBgQDX3/99t0f/nDRm+jVpMmaWvyvp+of+CApf +fiElrLiLm1sqmv7mgHHrZBqNvA/B8s+l4vwI2HWwQMcnNYYLP5MJWfRXpGiSUZtD +uMDBWYyqxpiKgHla243Rjr3RVI4raA2MEu0vfgZjz7Ye7QpwCOPrcQMT2jaOG5Gp +FBXecxIU0QKBgQCtWybOvih8jHf20eSmzSF/gmfIvDGOHvRc8n3dQeyLbEP2NAc+ +9xGCzkIqYAxaxO7eL9Fdfr5XF0OG5Xr8M5+6w3L5XROEwD7+slMolNq12MiD5eEo +SXNzhlcNxFpi0XyGjWpqLD8tqzHgBKcHlOOVPS+cWnY+kMT4u01wW1DKAQKBgAOS +7MrrBuEfd+qgh9PXBsXGInb8M9Yr0egk0W2rP17oUokRCdlNFRW9kYb5LxWZ7IAl +kuCenMwvNlza0P5MriWAfMAas7SAb16ep2pMDj0hjpL0b43mhqGKiG/3w2bKkTbZ +dV3M61Qpsy0t5XdXXlaeh1uDyFVv9WhkMbx+ETWRAoGBAM/k0LHRiQipcsYOVTKM +8NcNAD/rc/xWNuOyB/8QvgxkuA1kphKLVNwBPg7riPj/Sc2JL2LZ063ki2PtKxEt +MzGPUNsRBHtIk8gQVktaxkMrRPgnf2XmG7Bh/OxRxK0wiaIWpezX4hs2DH26Pyoy +1CE1W4oEFSBD/Lp5TENBWNSo +-----END PRIVATE KEY----- diff --git a/go/test/endtoend/vault/vault-setup.sh b/go/test/endtoend/vault/vault-setup.sh new file mode 100644 index 00000000000..6ad393eda44 --- /dev/null +++ b/go/test/endtoend/vault/vault-setup.sh @@ -0,0 +1,46 @@ +# We expect environment variables like the following to be set +#export VAULT_ADDR=https://test:9123 +#export VAULT=/path/to/vitess/test/bin/vault-1.6.1 +#export VAULT_CACERT=./vault-cert.pem + +# For debugging purposes +set -x +TMPFILE=/tmp/setup.sh.tmp.$RANDOM +$VAULT operator init -key-shares=1 -key-threshold=1 | grep ": " | awk '{ print $NF }' > $TMPFILE +export UNSEAL="$(head -1 $TMPFILE)" +export VAULT_TOKEN="$(tail -1 $TMPFILE)" +rm -f $TMPFILE + +# Unseal Vault +$VAULT operator unseal $UNSEAL + +# Enable secrets engine (v2); prefix will be /kv +$VAULT secrets enable -version=2 kv + +# Enable approles +$VAULT auth enable approle + +# Write a custom policy to allow credential access +$VAULT policy write dbcreds dbcreds_policy.hcl + +# Load up the db credentials (vttablet -> MySQL) secret +$VAULT kv put kv/prod/dbcreds @dbcreds_secret.json + +# Load up the vtgate credentials (app -> vttablet) secret +$VAULT kv put kv/prod/vtgatecreds @vtgatecreds_secret.json + +# Configure approle +# Keep the ttl low, so we can test a refresh +$VAULT write auth/approle/role/vitess secret_id_ttl=10m token_num_uses=0 token_ttl=30s token_max_ttl=0 secret_id_num_uses=4 policies=dbcreds +$VAULT read auth/approle/role/vitess + +# Read the role-id of the approle, we need to extract it +export ROLE_ID=$($VAULT read auth/approle/role/vitess/role-id | grep ^role_id | awk '{ print $NF }') + +# Get a secret_id for the approle +export SECRET_ID=$($VAULT write auth/approle/role/vitess/secret-id k=v | grep ^secret_id | head -1 | awk '{ print $NF }') + +# Echo it back, so the controlling process can read it from the log +echo "ROLE_ID=$ROLE_ID" +echo "SECRET_ID=$SECRET_ID" + diff --git a/go/test/endtoend/vault/vault.hcl b/go/test/endtoend/vault/vault.hcl new file mode 100644 index 00000000000..4cb4dd314b5 --- /dev/null +++ b/go/test/endtoend/vault/vault.hcl @@ -0,0 +1,21 @@ +{ + "ui": "true", + "disable_mlock": "true", + "listener": [ + { + "tcp": { + "address": "$server:$port", + "tls_disable": 0, + "tls_cert_file": "$cert", + "tls_key_file": "$key" + } + } + ], + "storage": [ + { + "inmem": {} + } + ], + "default_lease_ttl": "168h", + "max_lease_ttl": "720h" +} diff --git a/go/test/endtoend/vault/vault_server.go b/go/test/endtoend/vault/vault_server.go new file mode 100644 index 00000000000..a19c6c81990 --- /dev/null +++ b/go/test/endtoend/vault/vault_server.go @@ -0,0 +1,129 @@ +/* +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 vault + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path" + "strings" + "syscall" + "time" + + "vitess.io/vitess/go/vt/log" +) + +const ( + vaultExecutableName = "vault-1.6.1" + vaultDirName = "vault" + vaultConfigFileName = "vault.hcl" + vaultCertFileName = "vault-cert.pem" + vaultCAFileName = "ca.pem" + vaultKeyFileName = "vault-key.pem" + vaultSetupScript = "vault-setup.sh" +) + +// VaultServer : Basic parameters for the running the Vault server +type VaultServer struct { + address string + port1 int + port2 int + execPath string + logDir string + + proc *exec.Cmd + exit chan error +} + +// Start the Vault server in dev mode +func (vs *VaultServer) start() error { + hclFile := path.Join(os.Getenv("PWD"), vaultConfigFileName) + vs.execPath = path.Join(os.Getenv("EXTRA_BIN"), vaultExecutableName) + vs.logDir = path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("%s_%d", vaultDirName, vs.port1)) + if _, err := os.Stat(vs.logDir); os.IsNotExist(err) { + err := os.Mkdir(vs.logDir, 0700) + if err != nil { + log.Error(err) + return err + } + } + + hcl, _ := ioutil.ReadFile(hclFile) + // Replace variable parts in Vault config file + hcl = bytes.Replace(hcl, []byte("$server"), []byte(vs.address), 1) + hcl = bytes.Replace(hcl, []byte("$port"), []byte(fmt.Sprintf("%d", vs.port1)), 1) + hcl = bytes.Replace(hcl, []byte("$cert"), []byte(path.Join(os.Getenv("PWD"), vaultCertFileName)), 1) + hcl = bytes.Replace(hcl, []byte("$key"), []byte(path.Join(os.Getenv("PWD"), vaultKeyFileName)), 1) + newHclFile := path.Join(vs.logDir, vaultConfigFileName) + err := ioutil.WriteFile(newHclFile, hcl, 0700) + if err != nil { + log.Error(err) + return err + } + + vs.proc = exec.Command( + vs.execPath, + "server", + fmt.Sprintf("-config=%s", newHclFile), + ) + + logFile, err := os.Create(path.Join(vs.logDir, "log.txt")) + if err != nil { + log.Error(err) + return err + } + vs.proc.Stderr = logFile + vs.proc.Stdout = logFile + + vs.proc.Env = append(vs.proc.Env, os.Environ()...) + + log.Infof("Running Vault server with command: %v", strings.Join(vs.proc.Args, " ")) + + err = vs.proc.Start() + if err != nil { + return err + } + vs.exit = make(chan error) + go func() { + if vs.proc != nil { + vs.exit <- vs.proc.Wait() + } + }() + return nil +} + +func (vs *VaultServer) stop() error { + if vs.proc == nil || vs.exit == nil { + return nil + } + // Attempt graceful shutdown with SIGTERM first + vs.proc.Process.Signal(syscall.SIGTERM) + + select { + case err := <-vs.exit: + vs.proc = nil + return err + + case <-time.After(10 * time.Second): + vs.proc.Process.Kill() + vs.proc = nil + return <-vs.exit + } +} diff --git a/go/test/endtoend/vault/vault_test.go b/go/test/endtoend/vault/vault_test.go new file mode 100644 index 00000000000..5733d2bb8d5 --- /dev/null +++ b/go/test/endtoend/vault/vault_test.go @@ -0,0 +1,308 @@ +/* +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 vault + +import ( + "bufio" + "bytes" + "context" + "fmt" + "io/ioutil" + "net" + "os" + "os/exec" + "path" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/endtoend/cluster" + "vitess.io/vitess/go/vt/log" +) + +var ( + createTable = `create table product (id bigint(20) primary key, name char(10), created bigint(20));` + insertTable = `insert into product (id, name, created) values(%d, '%s', unix_timestamp());` +) + +var ( + clusterInstance *cluster.LocalProcessCluster + + master *cluster.Vttablet + replica *cluster.Vttablet + + cell = "zone1" + hostname = "localhost" + keyspaceName = "ks" + shardName = "0" + dbName = "vt_ks" + mysqlUsers = []string{"vt_dba", "vt_app", "vt_appdebug", "vt_repl", "vt_filtered"} + mysqlPassword = "password" + vtgateUser = "vtgate_user" + vtgatePassword = "password123" + commonTabletArg = []string{ + "-vreplication_healthcheck_topology_refresh", "1s", + "-vreplication_healthcheck_retry_delay", "1s", + "-vreplication_retry_delay", "1s", + "-degraded_threshold", "5s", + "-lock_tables_timeout", "5s", + "-watch_replication_stream", + // Frequently reload schema, generating some tablet traffic, + // so we can speed up token refresh + "-queryserver-config-schema-reload-time", "5", + "-serving_state_grace_period", "1s"} + vaultTabletArg = []string{ + "-db-credentials-server", "vault", + "-db-credentials-vault-timeout", "3s", + "-db-credentials-vault-path", "kv/prod/dbcreds", + // This is overriden by our env VAULT_ADDR + "-db-credentials-vault-addr", "https://127.0.0.1:8200", + // This is overriden by our env VAULT_CACERT + "-db-credentials-vault-tls-ca", "/path/to/ca.pem", + // This is provided by our env VAULT_ROLEID + //"-db-credentials-vault-roleid", "34644576-9ffc-8bb5-d046-4a0e41194e15", + // Contents of this file provided by our env VAULT_SECRETID + //"-db-credentials-vault-secretidfile", "/path/to/file/containing/secret_id", + // Make this small, so we can get a renewal + "-db-credentials-vault-ttl", "21s"} + vaultVTGateArg = []string{ + "-mysql_auth_server_impl", "vault", + "-mysql_auth_vault_timeout", "3s", + "-mysql_auth_vault_path", "kv/prod/vtgatecreds", + // This is overriden by our env VAULT_ADDR + "-mysql_auth_vault_addr", "https://127.0.0.1:8200", + // This is overriden by our env VAULT_CACERT + "-mysql_auth_vault_tls_ca", "/path/to/ca.pem", + // This is provided by our env VAULT_ROLEID + //"-mysql_auth_vault_roleid", "34644576-9ffc-8bb5-d046-4a0e41194e15", + // Contents of this file provided by our env VAULT_SECRETID + //"-mysql_auth_vault_role_secretidfile", "/path/to/file/containing/secret_id", + // Make this small, so we can get a renewal + "-mysql_auth_vault_ttl", "21s"} + mysqlctlArg = []string{ + "-db_dba_password", mysqlPassword} + vttabletLogFileName = "vttablet.INFO" + tokenRenewalString = "Vault client status: token renewed" +) + +func TestVaultAuth(t *testing.T) { + defer cluster.PanicHandler(nil) + initializeClusterEarly(t) + defer clusterInstance.Teardown() + + // start Vault server + vs := startVaultServer(t, master) + defer vs.stop() + + for i := 0; i < 60; i++ { + time.Sleep(250 * time.Millisecond) + ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", hostname, vs.port1)) + if err != nil { + // Vault is now up, we can continue + break + } + ln.Close() + } + + roleID, secretID := setupVaultServer(t, vs) + require.NotEmpty(t, roleID) + require.NotEmpty(t, secretID) + + // Passing via environment, easier than trying to modify + // vtgate/vttablet flags + os.Setenv("VAULT_ROLEID", roleID) + os.Setenv("VAULT_SECRETID", secretID) + + initializeClusterLate(t) + + // Creating the table + _, err := master.VttabletProcess.QueryTablet(createTable, keyspaceName, true) + require.NoError(t, err) + + // This tests the vtgate Vault auth. + insertRow(t, 1, "prd-1") + insertRow(t, 2, "prd-2") + + cluster.VerifyRowsInTabletForTable(t, replica, keyspaceName, 2, "product") + + // Sleep for a while; giving enough time for a token renewal + // and it making it into the (asynchronous) log + time.Sleep(30 * time.Second) + logContents, _ := ioutil.ReadFile(path.Join(clusterInstance.TmpDirectory, vttabletLogFileName)) + require.True(t, bytes.Contains(logContents, []byte(tokenRenewalString))) +} + +func startVaultServer(t *testing.T, masterTablet *cluster.Vttablet) *VaultServer { + vs := &VaultServer{ + address: hostname, + port1: clusterInstance.GetAndReservePort(), + port2: clusterInstance.GetAndReservePort(), + } + err := vs.start() + require.NoError(t, err) + + return vs +} + +// Setup everything we need in the Vault server +func setupVaultServer(t *testing.T, vs *VaultServer) (string, string) { + // The setup script uses these environment variables + // We also reuse VAULT_ADDR and VAULT_CACERT later on + os.Setenv("VAULT", vs.execPath) + os.Setenv("VAULT_ADDR", fmt.Sprintf("https://%s:%d", vs.address, vs.port1)) + os.Setenv("VAULT_CACERT", path.Join(os.Getenv("PWD"), vaultCAFileName)) + setup := exec.Command( + "/bin/bash", + path.Join(os.Getenv("PWD"), vaultSetupScript), + ) + + logFilePath := path.Join(vs.logDir, "log_setup.txt") + logFile, _ := os.Create(logFilePath) + setup.Stderr = logFile + setup.Stdout = logFile + + setup.Env = append(setup.Env, os.Environ()...) + log.Infof("Running Vault setup command: %v", strings.Join(setup.Args, " ")) + err := setup.Start() + if err != nil { + log.Errorf("Error during Vault setup: %v", err) + } + + setup.Wait() + var secretID, roleID string + file, err := os.Open(logFilePath) + if err != nil { + log.Error(err) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + if strings.HasPrefix(scanner.Text(), "ROLE_ID=") { + roleID = strings.Split(scanner.Text(), "=")[1] + } else if strings.HasPrefix(scanner.Text(), "SECRET_ID=") { + secretID = strings.Split(scanner.Text(), "=")[1] + } + } + if err := scanner.Err(); err != nil { + log.Error(err) + } + + return roleID, secretID +} + +// Setup cluster object and start topo +// We need this before vault, because we re-use the port reservation code +func initializeClusterEarly(t *testing.T) { + clusterInstance = cluster.NewCluster(cell, hostname) + + // Start topo server + err := clusterInstance.StartTopo() + require.NoError(t, err) +} + +func initializeClusterLate(t *testing.T) { + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + } + clusterInstance.Keyspaces = append(clusterInstance.Keyspaces, *keyspace) + shard := &cluster.Shard{ + Name: shardName, + } + + master = clusterInstance.NewVttabletInstance("replica", 0, "") + // We don't really need the replica to test this feature + // but keeping it in to excercise the vt_repl user/password path + replica = clusterInstance.NewVttabletInstance("replica", 0, "") + + shard.Vttablets = []*cluster.Vttablet{master, replica} + + clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, commonTabletArg...) + clusterInstance.VtTabletExtraArgs = append(clusterInstance.VtTabletExtraArgs, vaultTabletArg...) + clusterInstance.VtGateExtraArgs = append(clusterInstance.VtGateExtraArgs, vaultVTGateArg...) + + err := clusterInstance.SetupCluster(keyspace, []cluster.Shard{*shard}) + require.NoError(t, err) + + // Start MySQL + var mysqlCtlProcessList []*exec.Cmd + for _, shard := range clusterInstance.Keyspaces[0].Shards { + for _, tablet := range shard.Vttablets { + proc, err := tablet.MysqlctlProcess.StartProcess() + require.NoError(t, err) + mysqlCtlProcessList = append(mysqlCtlProcessList, proc) + } + } + + // Wait for MySQL startup + for _, proc := range mysqlCtlProcessList { + err = proc.Wait() + require.NoError(t, err) + } + + for _, tablet := range []*cluster.Vttablet{master, replica} { + for _, user := range mysqlUsers { + query := fmt.Sprintf("ALTER USER '%s'@'%s' IDENTIFIED BY '%s';", user, hostname, mysqlPassword) + _, err = tablet.VttabletProcess.QueryTablet(query, keyspace.Name, false) + // Reset after the first ALTER, or we lock ourselves out. + tablet.VttabletProcess.DbPassword = mysqlPassword + if err != nil { + query = fmt.Sprintf("ALTER USER '%s'@'%%' IDENTIFIED BY '%s';", user, mysqlPassword) + _, err = tablet.VttabletProcess.QueryTablet(query, keyspace.Name, false) + require.NoError(t, err) + } + } + query := fmt.Sprintf("create database %s;", dbName) + _, err = tablet.VttabletProcess.QueryTablet(query, keyspace.Name, false) + require.NoError(t, err) + + tablet.VttabletProcess.EnableSemiSync = true + err = tablet.VttabletProcess.Setup() + require.NoError(t, err) + + // Modify mysqlctl password too, or teardown will be locked out + tablet.MysqlctlProcess.ExtraArgs = append(tablet.MysqlctlProcess.ExtraArgs, mysqlctlArg...) + } + + err = clusterInstance.VtctlclientProcess.InitShardMaster(keyspaceName, shard.Name, cell, master.TabletUID) + require.NoError(t, err) + + // Start vtgate + err = clusterInstance.StartVtgate() + require.NoError(t, err) +} + +func insertRow(t *testing.T, id int, productName string) { + ctx := context.Background() + vtParams := mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + Uname: vtgateUser, + Pass: vtgatePassword, + } + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + insertSmt := fmt.Sprintf(insertTable, id, productName) + _, err = conn.ExecuteFetch(insertSmt, 1000, true) + require.NoError(t, err) +} diff --git a/go/test/endtoend/vault/vtgatecreds_secret.json b/go/test/endtoend/vault/vtgatecreds_secret.json new file mode 100644 index 00000000000..568609419f0 --- /dev/null +++ b/go/test/endtoend/vault/vtgatecreds_secret.json @@ -0,0 +1,7 @@ +{ + "vtgate_user": [ + { + "Password": "password123" + } + ] +} From 94f94a6df7da1767a17620033444f263128c927d Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Thu, 31 Dec 2020 17:40:18 -0800 Subject: [PATCH 037/310] Allow proper overriding of vault params by environment Signed-off-by: Jacques Grove --- go/mysql/auth_server_vault.go | 32 +++++++++++++++++++++++------- go/vt/dbconfigs/credentials.go | 36 +++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/go/mysql/auth_server_vault.go b/go/mysql/auth_server_vault.go index f94367712bd..5b490c99c49 100644 --- a/go/mysql/auth_server_vault.go +++ b/go/mysql/auth_server_vault.go @@ -101,13 +101,31 @@ func newAuthServerVault(addr string, timeout time.Duration, caCertPath string, p } config := vaultapi.NewConfig() - config.Address = addr - config.Timeout = timeout - config.CACert = caCertPath - config.Token = token - config.AppRoleCredentials.RoleID = roleID - config.AppRoleCredentials.SecretID = secretID - config.AppRoleCredentials.MountPoint = roleMountPoint + + // All these can be overriden by environment + // so we need to check if they have been set by NewConfig + if config.Address == "" { + config.Address = addr + } + if config.Timeout == (0 * time.Second) { + config.Timeout = timeout + } + if config.CACert == "" { + config.CACert = caCertPath + } + if config.Token == "" { + config.Token = token + } + if config.AppRoleCredentials.RoleID == "" { + config.AppRoleCredentials.RoleID = roleID + } + if config.AppRoleCredentials.SecretID == "" { + config.AppRoleCredentials.SecretID = secretID + } + if config.AppRoleCredentials.MountPoint == "" { + config.AppRoleCredentials.MountPoint = roleMountPoint + } + if config.CACert != "" { // If we provide a CA, ensure we actually use it config.InsecureSSL = false diff --git a/go/vt/dbconfigs/credentials.go b/go/vt/dbconfigs/credentials.go index 5dceefc2f38..760fc13d4d4 100644 --- a/go/vt/dbconfigs/credentials.go +++ b/go/vt/dbconfigs/credentials.go @@ -155,6 +155,10 @@ func (vcs *VaultCredentialsServer) GetUserAndPassword(user string) (string, stri } if vcs.cacheValid && vcs.dbCredsCache != nil { + if vcs.dbCredsCache[user] == nil { + log.Errorf("Vault cache is valid, but user %s unknown in cache, will retry", user) + return "", "", ErrUnknownUser + } return user, vcs.dbCredsCache[user][0], nil } @@ -175,13 +179,31 @@ func (vcs *VaultCredentialsServer) GetUserAndPassword(user string) (string, stri // for everything, so we get retries if vcs.vaultClient == nil { config := vaultapi.NewConfig() - config.Address = *vaultAddr - config.Timeout = *vaultTimeout - config.CACert = *vaultCACert - config.Token = token - config.AppRoleCredentials.RoleID = *vaultRoleID - config.AppRoleCredentials.SecretID = secretID - config.AppRoleCredentials.MountPoint = *vaultRoleMountPoint + + // All these can be overriden by environment + // so we need to check if they have been set by NewConfig + if config.Address == "" { + config.Address = *vaultAddr + } + if config.Timeout == (0 * time.Second) { + config.Timeout = *vaultTimeout + } + if config.CACert == "" { + config.CACert = *vaultCACert + } + if config.Token == "" { + config.Token = token + } + if config.AppRoleCredentials.RoleID == "" { + config.AppRoleCredentials.RoleID = *vaultRoleID + } + if config.AppRoleCredentials.SecretID == "" { + config.AppRoleCredentials.SecretID = secretID + } + if config.AppRoleCredentials.MountPoint == "" { + config.AppRoleCredentials.MountPoint = *vaultRoleMountPoint + } + if config.CACert != "" { // If we provide a CA, ensure we actually use it config.InsecureSSL = false From 2fa74821ef351e7a9149ebd1082e8d92f09928fd Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Thu, 31 Dec 2020 17:41:43 -0800 Subject: [PATCH 038/310] Add downloading & caching of vault executable Signed-off-by: Jacques Grove --- go/test/endtoend/vault/vault_server.go | 42 ++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/go/test/endtoend/vault/vault_server.go b/go/test/endtoend/vault/vault_server.go index a19c6c81990..57e64fe351e 100644 --- a/go/test/endtoend/vault/vault_server.go +++ b/go/test/endtoend/vault/vault_server.go @@ -19,7 +19,9 @@ package vault import ( "bytes" "fmt" + "io" "io/ioutil" + "net/http" "os" "os/exec" "path" @@ -31,7 +33,9 @@ import ( ) const ( - vaultExecutableName = "vault-1.6.1" + vaultExecutableName = "vault" + vaultDownloadSource = "https://vitess-operator.storage.googleapis.com/install/vault" + vaultDownloadSize = 132738840 vaultDirName = "vault" vaultConfigFileName = "vault.hcl" vaultCertFileName = "vault-cert.pem" @@ -54,8 +58,18 @@ type VaultServer struct { // Start the Vault server in dev mode func (vs *VaultServer) start() error { - hclFile := path.Join(os.Getenv("PWD"), vaultConfigFileName) + // Download and unpack vault binary vs.execPath = path.Join(os.Getenv("EXTRA_BIN"), vaultExecutableName) + fileStat, err := os.Stat(vs.execPath) + if err != nil || fileStat.Size() != vaultDownloadSize { + err := downloadExecFile(vs.execPath, vaultDownloadSource) + if err != nil { + log.Error(err) + return err + } + } + + // Create Vault log directory vs.logDir = path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("%s_%d", vaultDirName, vs.port1)) if _, err := os.Stat(vs.logDir); os.IsNotExist(err) { err := os.Mkdir(vs.logDir, 0700) @@ -65,6 +79,7 @@ func (vs *VaultServer) start() error { } } + hclFile := path.Join(os.Getenv("PWD"), vaultConfigFileName) hcl, _ := ioutil.ReadFile(hclFile) // Replace variable parts in Vault config file hcl = bytes.Replace(hcl, []byte("$server"), []byte(vs.address), 1) @@ -72,7 +87,7 @@ func (vs *VaultServer) start() error { hcl = bytes.Replace(hcl, []byte("$cert"), []byte(path.Join(os.Getenv("PWD"), vaultCertFileName)), 1) hcl = bytes.Replace(hcl, []byte("$key"), []byte(path.Join(os.Getenv("PWD"), vaultKeyFileName)), 1) newHclFile := path.Join(vs.logDir, vaultConfigFileName) - err := ioutil.WriteFile(newHclFile, hcl, 0700) + err = ioutil.WriteFile(newHclFile, hcl, 0700) if err != nil { log.Error(err) return err @@ -127,3 +142,24 @@ func (vs *VaultServer) stop() error { return <-vs.exit } } + +func downloadExecFile(path string, url string) error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + err = ioutil.WriteFile(path, []byte(""), 0700) + if err != nil { + return err + } + out, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY, os.ModeAppend) + if err != nil { + return err + } + defer out.Close() + + _, err = io.Copy(out, resp.Body) + return err +} From 4143b2ce8e3e42f894407c522d3d425467b9d9b0 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Fri, 1 Jan 2021 16:53:01 -0800 Subject: [PATCH 039/310] Add some test comments and logging. Signed-off-by: Jacques Grove --- go/test/endtoend/vault/vault_server.go | 4 ++++ go/test/endtoend/vault/vault_test.go | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/go/test/endtoend/vault/vault_server.go b/go/test/endtoend/vault/vault_server.go index 57e64fe351e..c5edfa56a85 100644 --- a/go/test/endtoend/vault/vault_server.go +++ b/go/test/endtoend/vault/vault_server.go @@ -62,11 +62,14 @@ func (vs *VaultServer) start() error { vs.execPath = path.Join(os.Getenv("EXTRA_BIN"), vaultExecutableName) fileStat, err := os.Stat(vs.execPath) if err != nil || fileStat.Size() != vaultDownloadSize { + log.Warningf("Downloading Vault binary to: %v", vs.execPath) err := downloadExecFile(vs.execPath, vaultDownloadSource) if err != nil { log.Error(err) return err } + } else { + log.Warningf("Vault binary already present at %v , not re-downloading", vs.execPath) } // Create Vault log directory @@ -143,6 +146,7 @@ func (vs *VaultServer) stop() error { } } +// Download file from url to path; making it executable func downloadExecFile(path string, url string) error { resp, err := http.Get(url) if err != nil { diff --git a/go/test/endtoend/vault/vault_test.go b/go/test/endtoend/vault/vault_test.go index 5733d2bb8d5..4f9b48d0aa3 100644 --- a/go/test/endtoend/vault/vault_test.go +++ b/go/test/endtoend/vault/vault_test.go @@ -104,13 +104,16 @@ var ( func TestVaultAuth(t *testing.T) { defer cluster.PanicHandler(nil) - initializeClusterEarly(t) defer clusterInstance.Teardown() + // Instantiate Vitess Cluster objects and start topo + initializeClusterEarly(t) + // start Vault server vs := startVaultServer(t, master) defer vs.stop() + // Wait for Vault server to come up for i := 0; i < 60; i++ { time.Sleep(250 * time.Millisecond) ln, err := net.Listen("tcp", fmt.Sprintf("%s:%d", hostname, vs.port1)) @@ -126,17 +129,18 @@ func TestVaultAuth(t *testing.T) { require.NotEmpty(t, secretID) // Passing via environment, easier than trying to modify - // vtgate/vttablet flags + // vtgate/vttablet flags within our test machinery os.Setenv("VAULT_ROLEID", roleID) os.Setenv("VAULT_SECRETID", secretID) + // Bring up rest of the Vitess cluster initializeClusterLate(t) - // Creating the table + // Create a table _, err := master.VttabletProcess.QueryTablet(createTable, keyspaceName, true) require.NoError(t, err) - // This tests the vtgate Vault auth. + // This tests the vtgate Vault auth & indirectly vttablet Vault auth too insertRow(t, 1, "prd-1") insertRow(t, 2, "prd-2") @@ -145,6 +149,8 @@ func TestVaultAuth(t *testing.T) { // Sleep for a while; giving enough time for a token renewal // and it making it into the (asynchronous) log time.Sleep(30 * time.Second) + // Check the log for the Vault token renewal message + // If we don't see it, that is a test failure logContents, _ := ioutil.ReadFile(path.Join(clusterInstance.TmpDirectory, vttabletLogFileName)) require.True(t, bytes.Contains(logContents, []byte(tokenRenewalString))) } From 22eef793f7834c05b6c112c628993e0dc8cb9582 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Fri, 1 Jan 2021 19:23:05 -0800 Subject: [PATCH 040/310] Add Vault e2e to shard 23 Signed-off-by: Jacques Grove --- test/config.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/config.json b/test/config.json index a7a48e23a1b..691ff4370a3 100644 --- a/test/config.json +++ b/test/config.json @@ -616,6 +616,15 @@ "RetryMax": 0, "Tags": [] }, + "vault": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vault"], + "Command": [], + "Manual": false, + "Shard": 23, + "RetryMax": 0, + "Tags": [] + }, "vreplication_v2": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vreplication", "-run", "TestBasicV2Workflows"], From d1d4eae86fc02aa5b3600271e003049d41445e1a Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Fri, 1 Jan 2021 20:08:18 -0800 Subject: [PATCH 041/310] Fix e2e Vault test cluster teardown initialization Signed-off-by: Jacques Grove --- go/test/endtoend/vault/vault_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/endtoend/vault/vault_test.go b/go/test/endtoend/vault/vault_test.go index 4f9b48d0aa3..79a9ba24f79 100644 --- a/go/test/endtoend/vault/vault_test.go +++ b/go/test/endtoend/vault/vault_test.go @@ -104,10 +104,10 @@ var ( func TestVaultAuth(t *testing.T) { defer cluster.PanicHandler(nil) - defer clusterInstance.Teardown() // Instantiate Vitess Cluster objects and start topo initializeClusterEarly(t) + defer clusterInstance.Teardown() // start Vault server vs := startVaultServer(t, master) From 7a5611f07d12f14624fb123df3fc9f2741318ec0 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Fri, 1 Jan 2021 21:56:33 -0800 Subject: [PATCH 042/310] Update go.sum for Vault lib Signed-off-by: Jacques Grove --- go.sum | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go.sum b/go.sum index 176818faca2..50b907dda98 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo= github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/aquarapid/vaultlib v0.5.1 h1:vuLWR6bZzLHybjJBSUYPgZlIp6KZ+SXeHLRRYTuk6d4= +github.com/aquarapid/vaultlib v0.5.1/go.mod h1:yT7AlEXtuabkxylOc/+Ulyp18tff1+QjgNLTnFWTlOs= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 h1:G1bPvciwNyF7IUmKXNt9Ak3m6u9DE1rF+RmtIkBpVdA= From 6d852dc95d26e9201f0c07c6effc2ef0e81f4255 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Sat, 2 Jan 2021 00:20:05 -0800 Subject: [PATCH 043/310] Add missing vtgate Vault commandline option help Signed-off-by: Jacques Grove --- go/mysql/auth_server_vault.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/mysql/auth_server_vault.go b/go/mysql/auth_server_vault.go index 5b490c99c49..cc43dc0fd85 100644 --- a/go/mysql/auth_server_vault.go +++ b/go/mysql/auth_server_vault.go @@ -35,8 +35,8 @@ import ( ) var ( - vaultAddr = flag.String("mysql_auth_vault_addr", "", "TODO") - vaultTimeout = flag.Duration("mysql_auth_vault_timeout", 10*time.Second, "TODO") + vaultAddr = flag.String("mysql_auth_vault_addr", "", "URL to Vault server") + vaultTimeout = flag.Duration("mysql_auth_vault_timeout", 10*time.Second, "Timeout for vault API operations") vaultCACert = flag.String("mysql_auth_vault_tls_ca", "", "Path to CA PEM for validating Vault server certificate") vaultPath = flag.String("mysql_auth_vault_path", "", "Vault path to vtgate credentials JSON blob, e.g.: secret/data/prod/vtgatecreds") vaultCacheTTL = flag.Duration("mysql_auth_vault_ttl", 30*time.Minute, "How long to cache vtgate credentials from the Vault server") From 6916d1511df38525a3ca403ba02d60c8193d20c2 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Wed, 6 Jan 2021 18:22:33 -0800 Subject: [PATCH 044/310] Rework mutex handling to avoid data races. Signed-off-by: Jacques Grove --- go/mysql/auth_server_vault.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/go/mysql/auth_server_vault.go b/go/mysql/auth_server_vault.go index cc43dc0fd85..7f72cd72e19 100644 --- a/go/mysql/auth_server_vault.go +++ b/go/mysql/auth_server_vault.go @@ -149,24 +149,26 @@ func newAuthServerVault(addr string, timeout time.Duration, caCertPath string, p return a, nil } -// Caller must hold the a.mu mutex. func (a *AuthServerVault) setTTLTicker(ttl time.Duration) { - if a.vaultCacheExpireTicker != nil { - a.vaultCacheExpireTicker.Stop() + a.mu.Lock() + defer a.mu.Unlock() + if a.vaultCacheExpireTicker == nil { + a.vaultCacheExpireTicker = time.NewTicker(ttl) + go func() { + for range a.vaultCacheExpireTicker.C { + a.sigChan <- syscall.SIGHUP + } + }() + } else { + a.vaultCacheExpireTicker.Reset(ttl) } - a.vaultCacheExpireTicker = time.NewTicker(ttl) - go func() { - for range a.vaultCacheExpireTicker.C { - a.sigChan <- syscall.SIGHUP - } - }() } // Reload JSON auth key from Vault. Return true if successful, false if not func (a *AuthServerVault) reloadVault() error { a.mu.Lock() - defer a.mu.Unlock() secret, err := a.vaultClient.GetSecret(a.vaultPath) + a.mu.Unlock() a.setTTLTicker(10 * time.Second) // Reload frequently on error if err != nil { @@ -186,7 +188,9 @@ func (a *AuthServerVault) reloadVault() error { } log.Infof("reloadVault(): success. Client status: %s", a.vaultClient.GetStatus()) + a.mu.Lock() a.entries = entries + a.mu.Unlock() a.setTTLTicker(a.vaultTTL) return nil } From 095ffcc21ad742447cc37962d8c49e5a966c4a07 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Wed, 6 Jan 2021 18:48:19 -0800 Subject: [PATCH 045/310] Revert an unrelated change that snuck into this branch Signed-off-by: Jacques Grove --- go/vt/vtexplain/vtexplain_vtgate.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/go/vt/vtexplain/vtexplain_vtgate.go b/go/vt/vtexplain/vtexplain_vtgate.go index c3a6cb9969a..ccdce29a55c 100644 --- a/go/vt/vtexplain/vtexplain_vtgate.go +++ b/go/vt/vtexplain/vtexplain_vtgate.go @@ -112,12 +112,7 @@ func buildTopology(opts *Options, vschemaStr string, ksShardMapStr string, numSh explainTopo.TabletConns = make(map[string]*explainTablet) explainTopo.KeyspaceShards = make(map[string]map[string]*topodatapb.ShardReference) for ks, vschema := range explainTopo.Keyspaces { - numShards := numShardsPerKeyspace - if !vschema.Sharded { - numShards = 1 - } - - shards, err := getShardRanges(ks, vschema, ksShardMap, numShards) + shards, err := getShardRanges(ks, vschema, ksShardMap, numShardsPerKeyspace) if err != nil { return err } @@ -167,10 +162,15 @@ func getShardRanges(ks string, vschema *vschemapb.Keyspace, ksShardMap map[strin } - shards := make([]*topodatapb.ShardReference, numShardsPerKeyspace) + numShards := 1 + if vschema.Sharded { + numShards = numShardsPerKeyspace + } + + shards := make([]*topodatapb.ShardReference, numShards) - for i := 0; i < numShardsPerKeyspace; i++ { - kr, err := key.EvenShardsKeyRange(i, numShardsPerKeyspace) + for i := 0; i < numShards; i++ { + kr, err := key.EvenShardsKeyRange(i, numShards) if err != nil { return nil, err } From 53d6e3882e4c199b3c77113089e31c304fda82ce Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Fri, 8 Jan 2021 08:39:10 +0100 Subject: [PATCH 046/310] don't try to compare varchars in vtgate we can't group together multiple varchar values into a IN query, because that forces use to compare varchar values on the vtgate level which we can't do correctly yet Signed-off-by: Andres Taylor --- go/test/endtoend/vtgate/lookup_test.go | 12 ++++++ go/test/endtoend/vtgate/main_test.go | 4 +- go/test/utils/diff.go | 6 +-- .../multi-output/selectsharded-output.txt | 4 +- go/vt/vtgate/executor_select_test.go | 38 ++++++------------- go/vt/vtgate/vindexes/lookup_internal.go | 2 +- 6 files changed, 32 insertions(+), 34 deletions(-) diff --git a/go/test/endtoend/vtgate/lookup_test.go b/go/test/endtoend/vtgate/lookup_test.go index d0c50b1c3e1..2073b41a463 100644 --- a/go/test/endtoend/vtgate/lookup_test.go +++ b/go/test/endtoend/vtgate/lookup_test.go @@ -513,3 +513,15 @@ func TestSelectNullLookup(t *testing.T) { exec(t, conn, "delete from t6") } + +func TestUnicodeLooseMD5CaseInsensitive(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + exec(t, conn, "insert into t4(id1, id2) values(1, 'test')") + defer exec(t, conn, "delete from t4") + + assertMatches(t, conn, "SELECT id1, id2 from t4 where id2 = 'Test'", `[[INT64(1) VARCHAR("test")]]`) +} diff --git a/go/test/endtoend/vtgate/main_test.go b/go/test/endtoend/vtgate/main_test.go index 84c066ef3b9..2fbc1e7781a 100644 --- a/go/test/endtoend/vtgate/main_test.go +++ b/go/test/endtoend/vtgate/main_test.go @@ -87,14 +87,14 @@ create table t4( id1 bigint, id2 varchar(10), primary key(id1) -) Engine=InnoDB; +) ENGINE=InnoDB DEFAULT charset=utf8mb4 COLLATE=utf8mb4_general_ci; create table t4_id2_idx( id2 varchar(10), id1 bigint, keyspace_id varbinary(50), primary key(id2, id1) -) Engine=InnoDB; +) Engine=InnoDB DEFAULT charset=utf8mb4 COLLATE=utf8mb4_general_ci; create table t5_null_vindex( id bigint not null, diff --git a/go/test/utils/diff.go b/go/test/utils/diff.go index 05a1f9eb66d..293d279e8c4 100644 --- a/go/test/utils/diff.go +++ b/go/test/utils/diff.go @@ -43,17 +43,17 @@ import ( // In Test*() function: // // mustMatch(t, want, got, "something doesn't match") -func MustMatchFn(allowUnexportedTypes []interface{}, ignoredFields []string, extraOpts ...cmp.Option) func(t *testing.T, want, got interface{}, errMsg string) { +func MustMatchFn(allowUnexportedTypes []interface{}, ignoredFields []string, extraOpts ...cmp.Option) func(t *testing.T, want, got interface{}, errMsg ...string) { diffOpts := append([]cmp.Option{ cmp.AllowUnexported(allowUnexportedTypes...), cmpIgnoreFields(ignoredFields...), }, extraOpts...) // Diffs want/got and fails with errMsg on any failure. - return func(t *testing.T, want, got interface{}, errMsg string) { + return func(t *testing.T, want, got interface{}, errMsg ...string) { t.Helper() diff := cmp.Diff(want, got, diffOpts...) if diff != "" { - t.Fatalf("%s: (-want +got)\n%v", errMsg, diff) + t.Fatalf("%v: (-want +got)\n%v", errMsg, diff) } } } diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 9ff0438d7b8..5762b2754c4 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -60,8 +60,8 @@ select count(*) from user where id = 1 /* point aggregate */ select count(*) from user where name in ('alice','bob') /* scatter aggregate */ 1 ks_sharded/40-80: select name, user_id from name_user_map where name in ('alice') limit 10001 /* scatter aggregate */ -1 ks_sharded/c0-: select name, user_id from name_user_map where name in ('bob') limit 10001 /* scatter aggregate */ -2 ks_sharded/-40: select count(*) from user where name in ('alice', 'bob') limit 10001 /* scatter aggregate */ +2 ks_sharded/c0-: select name, user_id from name_user_map where name in ('bob') limit 10001 /* scatter aggregate */ +3 ks_sharded/-40: select count(*) from user where name in ('alice', 'bob') limit 10001 /* scatter aggregate */ ---------------------------------------------------------------------- select name, count(*) from user group by name /* scatter aggregate */ diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 40eab7b6211..8114cf6e383 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -551,10 +551,8 @@ func TestSelectBindvars(t *testing.T) { lookup.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult( sqltypes.MakeTestFields("b|a", "varbinary|varbinary"), "foo1|1", - "foo2|1", ), sqltypes.MakeTestResult( sqltypes.MakeTestFields("b|a", "varbinary|varbinary"), - "foo1|1", "foo2|1", )}) @@ -567,12 +565,8 @@ func TestSelectBindvars(t *testing.T) { Sql: "select id from user where id = :id", BindVariables: map[string]*querypb.BindVariable{"id": sqltypes.Int64BindVariable(1)}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } - if sbc2.Queries != nil { - t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) - } + utils.MustMatch(t, sbc1.Queries, wantQueries) + assert.Empty(t, sbc2.Queries) sbc1.Queries = nil testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) @@ -591,11 +585,10 @@ func TestSelectBindvars(t *testing.T) { "__vals": sqltypes.TestBindVariable([]interface{}{"foo1", "foo2"}), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) sbc1.Queries = nil testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) + testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) // Test with BytesBindVariable @@ -606,17 +599,14 @@ func TestSelectBindvars(t *testing.T) { }) require.NoError(t, err) wantQueries = []*querypb.BoundQuery{{ - Sql: "select id from user where name in ::__vals", + Sql: "select id from user where 1 != 1", BindVariables: map[string]*querypb.BindVariable{ - "name1": sqltypes.BytesBindVariable([]byte("foo1")), - "name2": sqltypes.BytesBindVariable([]byte("foo2")), - "__vals": sqltypes.TestBindVariable([]interface{}{[]byte("foo1"), []byte("foo2")}), + "name1": sqltypes.BytesBindVariable([]byte("foo1")), + "name2": sqltypes.BytesBindVariable([]byte("foo2")), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } - + utils.MustMatch(t, wantQueries, sbc1.Queries) + testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) @@ -645,9 +635,7 @@ func TestSelectBindvars(t *testing.T) { "name": sqltypes.StringBindVariable("nonexistent"), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) vars, err := sqltypes.BuildBindVariable([]interface{}{sqltypes.NewVarBinary("nonexistent")}) require.NoError(t, err) @@ -657,13 +645,11 @@ func TestSelectBindvars(t *testing.T) { "name": vars, }, }} - if !reflect.DeepEqual(lookup.Queries, wantLookupQueries) { - t.Errorf("lookup.Queries: %+v, want %+v\n", lookup.Queries, wantLookupQueries) - } + + utils.MustMatch(t, wantLookupQueries, lookup.Queries) testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) - } func TestSelectEqual(t *testing.T) { diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index 346c7219f84..76d9140da3e 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -80,7 +80,7 @@ func (lkp *lookupInternal) Lookup(vcursor VCursor, ids []sqltypes.Value, co vtga if vcursor.InTransactionAndIsDML() { sel = sel + " for update" } - if !ids[0].IsIntegral() && !ids[0].IsBinary() { + if !ids[0].IsIntegral() { // for non integral and binary type, fallback to send query per id for _, id := range ids { vars, err := sqltypes.BuildBindVariable([]interface{}{id}) From 3503ef2ff32fb104c78100cff763818b884e72ce Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Fri, 8 Jan 2021 08:39:10 +0100 Subject: [PATCH 047/310] don't try to compare varchars in vtgate we can't group together multiple varchar values into a IN query, because that forces use to compare varchar values on the vtgate level which we can't do correctly yet Signed-off-by: Andres Taylor --- go/test/endtoend/vtgate/lookup_test.go | 12 +++++ go/test/endtoend/vtgate/main_test.go | 4 +- go/test/utils/diff.go | 6 +-- .../multi-output/selectsharded-output.txt | 4 +- go/vt/vtgate/executor_framework_test.go | 25 ++++------ go/vt/vtgate/executor_select_test.go | 39 +++++---------- go/vt/vtgate/vindexes/lookup_internal.go | 48 +++++++++---------- 7 files changed, 65 insertions(+), 73 deletions(-) diff --git a/go/test/endtoend/vtgate/lookup_test.go b/go/test/endtoend/vtgate/lookup_test.go index 489bb814227..796ed695ac2 100644 --- a/go/test/endtoend/vtgate/lookup_test.go +++ b/go/test/endtoend/vtgate/lookup_test.go @@ -515,3 +515,15 @@ func TestSelectNullLookup(t *testing.T) { }) } } + +func TestUnicodeLooseMD5CaseInsensitive(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + exec(t, conn, "insert into t4(id1, id2) values(1, 'test')") + defer exec(t, conn, "delete from t4") + + assertMatches(t, conn, "SELECT id1, id2 from t4 where id2 = 'Test'", `[[INT64(1) VARCHAR("test")]]`) +} diff --git a/go/test/endtoend/vtgate/main_test.go b/go/test/endtoend/vtgate/main_test.go index 5f4422984e9..e3c4817a800 100644 --- a/go/test/endtoend/vtgate/main_test.go +++ b/go/test/endtoend/vtgate/main_test.go @@ -87,14 +87,14 @@ create table t4( id1 bigint, id2 varchar(10), primary key(id1) -) Engine=InnoDB; +) ENGINE=InnoDB DEFAULT charset=utf8mb4 COLLATE=utf8mb4_general_ci; create table t4_id2_idx( id2 varchar(10), id1 bigint, keyspace_id varbinary(50), primary key(id2, id1) -) Engine=InnoDB; +) Engine=InnoDB DEFAULT charset=utf8mb4 COLLATE=utf8mb4_general_ci; create table t5_null_vindex( id bigint not null, diff --git a/go/test/utils/diff.go b/go/test/utils/diff.go index 05a1f9eb66d..293d279e8c4 100644 --- a/go/test/utils/diff.go +++ b/go/test/utils/diff.go @@ -43,17 +43,17 @@ import ( // In Test*() function: // // mustMatch(t, want, got, "something doesn't match") -func MustMatchFn(allowUnexportedTypes []interface{}, ignoredFields []string, extraOpts ...cmp.Option) func(t *testing.T, want, got interface{}, errMsg string) { +func MustMatchFn(allowUnexportedTypes []interface{}, ignoredFields []string, extraOpts ...cmp.Option) func(t *testing.T, want, got interface{}, errMsg ...string) { diffOpts := append([]cmp.Option{ cmp.AllowUnexported(allowUnexportedTypes...), cmpIgnoreFields(ignoredFields...), }, extraOpts...) // Diffs want/got and fails with errMsg on any failure. - return func(t *testing.T, want, got interface{}, errMsg string) { + return func(t *testing.T, want, got interface{}, errMsg ...string) { t.Helper() diff := cmp.Diff(want, got, diffOpts...) if diff != "" { - t.Fatalf("%s: (-want +got)\n%v", errMsg, diff) + t.Fatalf("%v: (-want +got)\n%v", errMsg, diff) } } } diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 69a10e8198c..ccad1126651 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -60,8 +60,8 @@ select count(*) from user where id = 1 /* point aggregate */ select count(*) from user where name in ('alice','bob') /* scatter aggregate */ 1 ks_sharded/40-80: select `name`, user_id from name_user_map where `name` in ('alice') limit 10001 /* scatter aggregate */ -1 ks_sharded/c0-: select `name`, user_id from name_user_map where `name` in ('bob') limit 10001 /* scatter aggregate */ -2 ks_sharded/-40: select count(*) from user where `name` in ('alice', 'bob') limit 10001 /* scatter aggregate */ +2 ks_sharded/c0-: select `name`, user_id from name_user_map where `name` in ('bob') limit 10001 /* scatter aggregate */ +3 ks_sharded/-40: select count(*) from user where `name` in ('alice', 'bob') limit 10001 /* scatter aggregate */ ---------------------------------------------------------------------- select name, count(*) from user group by name /* scatter aggregate */ diff --git a/go/vt/vtgate/executor_framework_test.go b/go/vt/vtgate/executor_framework_test.go index 71e6528673d..fcc24f67b08 100644 --- a/go/vt/vtgate/executor_framework_test.go +++ b/go/vt/vtgate/executor_framework_test.go @@ -24,6 +24,10 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + + "github.com/stretchr/testify/assert" + "context" "vitess.io/vitess/go/sqltypes" @@ -546,19 +550,14 @@ func testQueryLog(t *testing.T, logChan chan interface{}, method, stmtType, sql t.Helper() logStats := getQueryLog(logChan) - if logStats == nil { - t.Errorf("logstats: no querylog in channel, want sql %s", sql) - return nil - } + require.NotNil(t, logStats) var log bytes.Buffer streamlog.GetFormatter(QueryLogger)(&log, nil, logStats) fields := strings.Split(log.String(), "\t") // fields[0] is the method - if method != fields[0] { - t.Errorf("logstats: method want %q got %q", method, fields[0]) - } + assert.Equal(t, method, fields[0], "logstats: method") // fields[1] - fields[6] are the caller id, start/end times, etc @@ -588,22 +587,16 @@ func testQueryLog(t *testing.T, logChan chan interface{}, method, stmtType, sql } // fields[11] is the statement type - if stmtType != fields[11] { - t.Errorf("logstats: stmtType want %q got %q", stmtType, fields[11]) - } + assert.Equal(t, stmtType, fields[11], "logstats: stmtType") // fields[12] is the original sql wantSQL := fmt.Sprintf("%q", sql) - if wantSQL != fields[12] { - t.Errorf("logstats: SQL want %s got %s", wantSQL, fields[12]) - } + assert.Equal(t, wantSQL, fields[12], "logstats: SQL") // fields[13] contains the formatted bind vars // fields[14] is the count of shard queries - if fmt.Sprintf("%v", shardQueries) != fields[14] { - t.Errorf("logstats: ShardQueries want %v got %v", shardQueries, fields[14]) - } + assert.Equal(t, fmt.Sprintf("%v", shardQueries), fields[14], "logstats: ShardQueries") return logStats } diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 74c72baf988..d5783b070ce 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -568,10 +568,8 @@ func TestSelectBindvars(t *testing.T) { lookup.SetResults([]*sqltypes.Result{sqltypes.MakeTestResult( sqltypes.MakeTestFields("b|a", "varbinary|varbinary"), "foo1|1", - "foo2|1", ), sqltypes.MakeTestResult( sqltypes.MakeTestFields("b|a", "varbinary|varbinary"), - "foo1|1", "foo2|1", )}) @@ -584,12 +582,8 @@ func TestSelectBindvars(t *testing.T) { Sql: "select id from user where id = :id", BindVariables: map[string]*querypb.BindVariable{"id": sqltypes.Int64BindVariable(1)}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } - if sbc2.Queries != nil { - t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) - } + utils.MustMatch(t, sbc1.Queries, wantQueries) + assert.Empty(t, sbc2.Queries) sbc1.Queries = nil testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) @@ -608,11 +602,10 @@ func TestSelectBindvars(t *testing.T) { "__vals": sqltypes.TestBindVariable([]interface{}{"foo1", "foo2"}), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) sbc1.Queries = nil testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) + testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) // Test with BytesBindVariable @@ -623,17 +616,14 @@ func TestSelectBindvars(t *testing.T) { }) require.NoError(t, err) wantQueries = []*querypb.BoundQuery{{ - Sql: "select id from user where `name` in ::__vals", + Sql: "select id from user where 1 != 1", BindVariables: map[string]*querypb.BindVariable{ - "name1": sqltypes.BytesBindVariable([]byte("foo1")), - "name2": sqltypes.BytesBindVariable([]byte("foo2")), - "__vals": sqltypes.TestBindVariable([]interface{}{[]byte("foo1"), []byte("foo2")}), + "name1": sqltypes.BytesBindVariable([]byte("foo1")), + "name2": sqltypes.BytesBindVariable([]byte("foo2")), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } - + utils.MustMatch(t, wantQueries, sbc1.Queries) + testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) @@ -662,9 +652,7 @@ func TestSelectBindvars(t *testing.T) { "name": sqltypes.StringBindVariable("nonexistent"), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) vars, err := sqltypes.BuildBindVariable([]interface{}{sqltypes.NewVarBinary("nonexistent")}) require.NoError(t, err) @@ -674,9 +662,8 @@ func TestSelectBindvars(t *testing.T) { "name": vars, }, }} - if !reflect.DeepEqual(lookup.Queries, wantLookupQueries) { - t.Errorf("lookup.Queries: %+v, want %+v\n", lookup.Queries, wantLookupQueries) - } + + utils.MustMatch(t, wantLookupQueries, lookup.Queries) testQueryLog(t, logChan, "VindexLookup", "SELECT", "select name, user_id from name_user_map where name in ::name", 1) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 1) @@ -829,7 +816,7 @@ func TestSelectNormalize(t *testing.T) { }, }} require.Empty(t, sbc1.Queries) - utils.MustMatch(t, sbc2.Queries, wantQueries, "sbc2.Queries") + utils.MustMatch(t, wantQueries, sbc2.Queries, "sbc2.Queries") sbc2.Queries = nil masterSession.TargetString = "" } diff --git a/go/vt/vtgate/vindexes/lookup_internal.go b/go/vt/vtgate/vindexes/lookup_internal.go index 346c7219f84..e14162e8efd 100644 --- a/go/vt/vtgate/vindexes/lookup_internal.go +++ b/go/vt/vtgate/vindexes/lookup_internal.go @@ -80,30 +80,7 @@ func (lkp *lookupInternal) Lookup(vcursor VCursor, ids []sqltypes.Value, co vtga if vcursor.InTransactionAndIsDML() { sel = sel + " for update" } - if !ids[0].IsIntegral() && !ids[0].IsBinary() { - // for non integral and binary type, fallback to send query per id - for _, id := range ids { - vars, err := sqltypes.BuildBindVariable([]interface{}{id}) - if err != nil { - return nil, fmt.Errorf("lookup.Map: %v", err) - } - bindVars := map[string]*querypb.BindVariable{ - lkp.FromColumns[0]: vars, - } - var result *sqltypes.Result - result, err = vcursor.Execute("VindexLookup", sel, bindVars, false /* rollbackOnError */, co) - if err != nil { - return nil, fmt.Errorf("lookup.Map: %v", err) - } - rows := make([][]sqltypes.Value, 0, len(result.Rows)) - for _, row := range result.Rows { - rows = append(rows, []sqltypes.Value{row[1]}) - } - results = append(results, &sqltypes.Result{ - Rows: rows, - }) - } - } else { + if ids[0].IsIntegral() { // for integral or binary type, batch query all ids and then map them back to the input order vars, err := sqltypes.BuildBindVariable(ids) if err != nil { @@ -126,6 +103,29 @@ func (lkp *lookupInternal) Lookup(vcursor VCursor, ids []sqltypes.Value, co vtga Rows: resultMap[id.ToString()], }) } + } else { + // for non integral and binary type, fallback to send query per id + for _, id := range ids { + vars, err := sqltypes.BuildBindVariable([]interface{}{id}) + if err != nil { + return nil, fmt.Errorf("lookup.Map: %v", err) + } + bindVars := map[string]*querypb.BindVariable{ + lkp.FromColumns[0]: vars, + } + var result *sqltypes.Result + result, err = vcursor.Execute("VindexLookup", sel, bindVars, false /* rollbackOnError */, co) + if err != nil { + return nil, fmt.Errorf("lookup.Map: %v", err) + } + rows := make([][]sqltypes.Value, 0, len(result.Rows)) + for _, row := range result.Rows { + rows = append(rows, []sqltypes.Value{row[1]}) + } + results = append(results, &sqltypes.Result{ + Rows: rows, + }) + } } return results, nil } From 7c7ea05504d197cf5a12f97b50df516d8b3b1976 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Mon, 11 Jan 2021 20:28:00 -0800 Subject: [PATCH 048/310] Merge pull request #7285 from tinyspeck/am_fix_findallshardsinkeyspace [vtctld] Fix accidentally-broken legacy vtctl output format Signed-off-by: Andrew Mason --- go/vt/vtctl/vtctl.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index e38d10deb74..91e86532984 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2561,7 +2561,14 @@ func commandFindAllShardsInKeyspace(ctx context.Context, wr *wrangler.Wrangler, return err } - return printJSON(wr.Logger(), result.Shards) + // reformat data into structure of old interface + legacyShardMap := make(map[string]*topodatapb.Shard, len(result.Shards)) + + for _, shard := range result.Shards { + legacyShardMap[shard.Name] = shard.Shard + } + + return printJSON(wr.Logger(), legacyShardMap) } func commandValidate(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { From bcab7f352f392b06b7363000e17205c92c28fab6 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 15 Jan 2021 15:15:36 +0530 Subject: [PATCH 049/310] default to false for system settings to be changed per session at the database connection level Signed-off-by: Harshit Gangal --- go/vt/vtgate/vtgate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 164179319f6..156a4f7e897 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -73,7 +73,7 @@ var ( warnPayloadSize = flag.Int("warn_payload_size", 0, "The warning threshold for query payloads in bytes. A payload greater than this threshold will cause the VtGateWarnings.WarnPayloadSizeExceeded counter to be incremented.") // Put set-passthrough under a flag. - sysVarSetEnabled = flag.Bool("enable_system_settings", true, "This will enable the system settings to be changed per session at the database connection level") + sysVarSetEnabled = flag.Bool("enable_system_settings", false, "This will enable the system settings to be changed per session at the database connection level") // lockHeartbeatTime is used to set the next heartbeat time. lockHeartbeatTime = flag.Duration("lock_heartbeat_time", 5*time.Second, "If there is lock function used. This will keep the lock connection active by using this heartbeat") ) From 74109636b9fd87fc733adf7c3b6a4dce51007fcc Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 20 Jan 2021 06:29:53 +0200 Subject: [PATCH 050/310] Backport: Testing version upgrade/downgrade path from/to 8.0 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../workflows/cluster_endtoend_upgrade.yml | 105 +++++++++ go/test/endtoend/cluster/cluster_process.go | 73 +++++-- go/test/endtoend/cluster/mysqlctl_process.go | 12 +- .../endtoend/cluster/vtctlclient_process.go | 14 +- .../endtoend/versionupgrade/upgrade_test.go | 206 ++++++++++++++++++ test.go | 3 + test/config.json | 9 + 7 files changed, 394 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/cluster_endtoend_upgrade.yml create mode 100644 go/test/endtoend/versionupgrade/upgrade_test.go diff --git a/.github/workflows/cluster_endtoend_upgrade.yml b/.github/workflows/cluster_endtoend_upgrade.yml new file mode 100644 index 00000000000..185b9fbbe09 --- /dev/null +++ b/.github/workflows/cluster_endtoend_upgrade.yml @@ -0,0 +1,105 @@ +name: Cluster (upgrade) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (upgrade) + runs-on: ubuntu-latest + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Check out v8.0.0 + uses: actions/checkout@v2 + with: + ref: v8.0.0 + + - name: Get dependencies + run: | + # This prepares general purpose binary dependencies + # as well as v8.0.0 specific go modules + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Building v8.0.0 binaries + timeout-minutes: 10 + run: | + # We build v8.0.0 binaries and save them in a temporary location + source build.env + make build + mkdir -p /tmp/vitess-build-v8.0.0/ + cp -R bin /tmp/vitess-build-v8.0.0/ + + - name: Check out HEAD + uses: actions/checkout@v2 + + - name: Run cluster endtoend test v8.0.0 (create cluster) + timeout-minutes: 5 + run: | + # By checking out we deleted bin/ directory. We now restore our pre-built v8.0.0 binaries + cp -R /tmp/vitess-build-v8.0.0/bin . + # create the directory where we store test data; ensure it is empty: + rm -rf /tmp/vtdataroot + mkdir -p /tmp/vtdataroot + source build.env + # We pass -skip-build so that we use the v8.0.0 binaries, not HEAD binaries + eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28 + + - name: Check out HEAD + uses: actions/checkout@v2 + + + - name: Building HEAD binaries + timeout-minutes: 10 + run: | + go mod download + + source build.env + make build + mkdir -p /tmp/vitess-build-head/ + cp -R bin /tmp/vitess-build-head/ + + - name: Run cluster endtoend test HEAD based on v8.0.0 data (upgrade path) + timeout-minutes: 5 + run: | + # /tmp/vtdataroot exists from previous test + + source build.env + # We built HEAD binaries manually in previous step and there's no need for the test to build. + eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28 + + - name: Run cluster endtoend test HEAD (create cluster) + timeout-minutes: 5 + run: | + # create the directory where we store test data; ensure it is empty: + rm -rf /tmp/vtdataroot + mkdir -p /tmp/vtdataroot + + source build.env + # We still have the binaries from previous step. No need to build + eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28 + + + - name: Run cluster endtoend test v8.0.0 based on HEAD data (downgrade path) + timeout-minutes: 5 + run: | + # /tmp/vtdataroot exists from previous test + cp -R /tmp/vitess-build-v8.0.0/bin . + + source build.env + # We again built manually and there's no need for the test to build. + eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28 diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index 18049c90051..879b2ef8a0e 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -42,9 +42,12 @@ const ( ) var ( - 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") + 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") + forcePortStart = flag.Int("force-port-start", 0, "force assigning ports based on this seed") + forceBaseTabletUID = flag.Int("force-base-tablet-uid", 0, "force assigning tablet ports based on this seed") ) // LocalProcessCluster Testcases need to use this to iniate a cluster @@ -57,6 +60,7 @@ type LocalProcessCluster struct { TmpDirectory string OriginalVTDATAROOT string CurrentVTDATAROOT string + ReusingVTDATAROOT bool VtgateMySQLPort int VtgateGrpcPort int @@ -192,10 +196,12 @@ func (cluster *LocalProcessCluster) StartTopo() (err error) { } } - cluster.VtctlProcess = *VtctlProcessInstance(cluster.TopoProcess.Port, cluster.Hostname) - if err = cluster.VtctlProcess.AddCellInfo(cluster.Cell); err != nil { - log.Error(err) - return + if !cluster.ReusingVTDATAROOT { + cluster.VtctlProcess = *VtctlProcessInstance(cluster.TopoProcess.Port, cluster.Hostname) + if err = cluster.VtctlProcess.AddCellInfo(cluster.Cell); err != nil { + log.Error(err) + return + } } cluster.VtctldProcess = *VtctldProcessInstance(cluster.GetAndReservePort(), cluster.GetAndReservePort(), @@ -230,7 +236,9 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames } log.Infof("Starting keyspace: %v", keyspace.Name) - _ = cluster.VtctlProcess.CreateKeyspace(keyspace.Name) + if !cluster.ReusingVTDATAROOT { + _ = cluster.VtctlProcess.CreateKeyspace(keyspace.Name) + } var mysqlctlProcessList []*exec.Cmd for _, shardName := range shardNames { shard := &Shard{ @@ -256,7 +264,7 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames } // Start Mysqlctl process log.Infof("Starting mysqlctl for table uid %d, mysql port %d", tablet.TabletUID, tablet.MySQLPort) - tablet.MysqlctlProcess = *MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, cluster.TmpDirectory) + tablet.MysqlctlProcess = *MysqlCtlProcessInstanceOptionalInit(tablet.TabletUID, tablet.MySQLPort, cluster.TmpDirectory, !cluster.ReusingVTDATAROOT) proc, err := tablet.MysqlctlProcess.StartProcess() if err != nil { log.Errorf("error starting mysqlctl process: %v, %v", tablet.MysqlctldProcess, err) @@ -279,6 +287,9 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames cluster.VtTabletExtraArgs, cluster.EnableSemiSync) tablet.Alias = tablet.VttabletProcess.TabletPath + if cluster.ReusingVTDATAROOT { + tablet.VttabletProcess.ServingStatus = "SERVING" + } shard.Vttablets = append(shard.Vttablets, tablet) // Apply customizations for _, customizer := range customizers { @@ -298,9 +309,11 @@ func (cluster *LocalProcessCluster) StartKeyspace(keyspace Keyspace, shardNames } } for _, tablet := range shard.Vttablets { - if _, err = tablet.VttabletProcess.QueryTablet(fmt.Sprintf("create database vt_%s", keyspace.Name), keyspace.Name, false); err != nil { - log.Errorf("error creating database for keyspace %v: %v", keyspace.Name, err) - return + if !cluster.ReusingVTDATAROOT { + if _, err = tablet.VttabletProcess.QueryTablet(fmt.Sprintf("create database vt_%s", keyspace.Name), keyspace.Name, false); err != nil { + log.Errorf("error creating database for keyspace %v: %v", keyspace.Name, err) + return + } } log.Infof("Starting vttablet for tablet uid %d, grpc port %d", tablet.TabletUID, tablet.GrpcPort) @@ -358,11 +371,13 @@ func (cluster *LocalProcessCluster) SetupCluster(keyspace *Keyspace, shards []Sh log.Infof("Starting keyspace: %v", keyspace.Name) - // Create Keyspace - err = cluster.VtctlProcess.CreateKeyspace(keyspace.Name) - if err != nil { - log.Error(err) - return + if !cluster.ReusingVTDATAROOT { + // Create Keyspace + err = cluster.VtctlProcess.CreateKeyspace(keyspace.Name) + if err != nil { + log.Error(err) + return + } } // Create shard @@ -441,8 +456,18 @@ func NewCluster(cell string, hostname string) *LocalProcessCluster { go cluster.CtrlCHandler() cluster.OriginalVTDATAROOT = os.Getenv("VTDATAROOT") cluster.CurrentVTDATAROOT = path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("vtroot_%d", cluster.GetAndReservePort())) - _ = createDirectory(cluster.CurrentVTDATAROOT, 0700) + if *forceVTDATAROOT != "" { + cluster.CurrentVTDATAROOT = *forceVTDATAROOT + } + if _, err := os.Stat(cluster.CurrentVTDATAROOT); err == nil { + // path/to/whatever exists + cluster.ReusingVTDATAROOT = true + } else { + _ = createDirectory(cluster.CurrentVTDATAROOT, 0700) + } _ = os.Setenv("VTDATAROOT", cluster.CurrentVTDATAROOT) + log.Infof("Created cluster on %s. ReusingVTDATAROOT=%v", cluster.CurrentVTDATAROOT, cluster.ReusingVTDATAROOT) + rand.Seed(time.Now().UTC().UnixNano()) return cluster } @@ -591,7 +616,11 @@ func (cluster *LocalProcessCluster) StartVtbackup(newInitDBFile string, initalBa // GetAndReservePort gives port for required process func (cluster *LocalProcessCluster) GetAndReservePort() int { if cluster.nextPortForProcess == 0 { - cluster.nextPortForProcess = getPort() + if *forcePortStart > 0 { + cluster.nextPortForProcess = *forcePortStart + } else { + cluster.nextPortForProcess = getPort() + } } for { cluster.nextPortForProcess = cluster.nextPortForProcess + 1 @@ -634,7 +663,11 @@ func getPort() int { // GetAndReserveTabletUID gives tablet uid func (cluster *LocalProcessCluster) GetAndReserveTabletUID() int { if cluster.BaseTabletUID == 0 { - cluster.BaseTabletUID = getRandomNumber(10000, 0) + if *forceBaseTabletUID > 0 { + cluster.BaseTabletUID = *forceBaseTabletUID + } else { + cluster.BaseTabletUID = getRandomNumber(10000, 0) + } } cluster.BaseTabletUID = cluster.BaseTabletUID + 1 return cluster.BaseTabletUID diff --git a/go/test/endtoend/cluster/mysqlctl_process.go b/go/test/endtoend/cluster/mysqlctl_process.go index 928ac6b3295..4954b3cb550 100644 --- a/go/test/endtoend/cluster/mysqlctl_process.go +++ b/go/test/endtoend/cluster/mysqlctl_process.go @@ -161,9 +161,9 @@ func (mysqlctl *MysqlctlProcess) CleanupFiles(tabletUID int) { os.RemoveAll(path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/vt_%010d/innodb", tabletUID))) } -// MysqlCtlProcessInstance returns a Mysqlctl handle for mysqlctl process +// MysqlCtlProcessInstanceOptionalInit returns a Mysqlctl handle for mysqlctl process // configured with the given Config. -func MysqlCtlProcessInstance(tabletUID int, mySQLPort int, tmpDirectory string) *MysqlctlProcess { +func MysqlCtlProcessInstanceOptionalInit(tabletUID int, mySQLPort int, tmpDirectory string, initMySQL bool) *MysqlctlProcess { mysqlctl := &MysqlctlProcess{ Name: "mysqlctl", Binary: "mysqlctl", @@ -172,11 +172,17 @@ func MysqlCtlProcessInstance(tabletUID int, mySQLPort int, tmpDirectory string) } mysqlctl.MySQLPort = mySQLPort mysqlctl.TabletUID = tabletUID - mysqlctl.InitMysql = true + mysqlctl.InitMysql = initMySQL mysqlctl.SecureTransport = false return mysqlctl } +// MysqlCtlProcessInstance returns a Mysqlctl handle for mysqlctl process +// configured with the given Config. +func MysqlCtlProcessInstance(tabletUID int, mySQLPort int, tmpDirectory string) *MysqlctlProcess { + return MysqlCtlProcessInstanceOptionalInit(tabletUID, mySQLPort, tmpDirectory, true) +} + // StartMySQL starts mysqlctl process func StartMySQL(ctx context.Context, tablet *Vttablet, username string, tmpDirectory string) error { tablet.MysqlctlProcess = *MysqlCtlProcessInstance(tablet.TabletUID, tablet.MySQLPort, tmpDirectory) diff --git a/go/test/endtoend/cluster/vtctlclient_process.go b/go/test/endtoend/cluster/vtctlclient_process.go index e94f83d76d1..1fd5d9ef00b 100644 --- a/go/test/endtoend/cluster/vtctlclient_process.go +++ b/go/test/endtoend/cluster/vtctlclient_process.go @@ -49,16 +49,20 @@ func (vtctlclient *VtctlClientProcess) InitShardMaster(Keyspace string, Shard st // ApplySchemaWithOutput applies SQL schema to the keyspace func (vtctlclient *VtctlClientProcess) ApplySchemaWithOutput(Keyspace string, SQL string, ddlStrategy string) (result string, err error) { - return vtctlclient.ExecuteCommandWithOutput( + args := []string{ "ApplySchema", "-sql", SQL, - "-ddl_strategy", ddlStrategy, - Keyspace) + } + if ddlStrategy != "" { + args = append(args, "-ddl_strategy", ddlStrategy) + } + args = append(args, Keyspace) + return vtctlclient.ExecuteCommandWithOutput(args...) } // ApplySchema applies SQL schema to the keyspace func (vtctlclient *VtctlClientProcess) ApplySchema(Keyspace string, SQL string) (err error) { - _, err = vtctlclient.ApplySchemaWithOutput(Keyspace, SQL, "") + _, err = vtctlclient.ApplySchemaWithOutput(Keyspace, SQL, "direct") return err } @@ -96,7 +100,7 @@ func (vtctlclient *VtctlClientProcess) OnlineDDLCancelMigration(Keyspace, uuid s ) } -// OnlineDDLCancelMigration cancels a given migration uuid +// OnlineDDLCancelAllMigrations cancels all migrations for a keyspace func (vtctlclient *VtctlClientProcess) OnlineDDLCancelAllMigrations(Keyspace string) (result string, err error) { return vtctlclient.ExecuteCommandWithOutput( "OnlineDDL", diff --git a/go/test/endtoend/versionupgrade/upgrade_test.go b/go/test/endtoend/versionupgrade/upgrade_test.go new file mode 100644 index 00000000000..f341bf792e0 --- /dev/null +++ b/go/test/endtoend/versionupgrade/upgrade_test.go @@ -0,0 +1,206 @@ +/* +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. +*/ + +/* + +ABOUT THIS TEST +=============== + +This test plays part in testing an upgrade path from a previous version/tag. It takes a GitHub workflow file to complete the functionality. +What's in this file is the setting up of a cluster, sharded and unsharded keyspace, creating and populating some tables, then testing retrieval of data. +The twist here is that you can run this test over pre-existing vtdataroot, which means this test can reuse existing etcd, existing tables, existing mysql, +in which case it will not attempt to create keyspaces/schemas/tables, nor will it populate table data. Instead, it will only check for retrieval of data. + +The game is to setup the cluster with a stable version (say `v8.0.0`), take it down (and preserve data), then setup a new cluster with a new version (namely the branch/PR head) and attempt to read the data. + +Both executions must force some settings so that both reuse same directories, ports, etc. An invocation will look like: +go test ./go/test/endtoend/versionupgrade80/upgrade80_test.go --keep-data -force-vtdataroot /tmp/vtdataroot/vtroot_10901 --force-port-start 11900 --force-base-tablet-uid 1190 + +*/ + +package versionupgrade + +import ( + "flag" + "fmt" + "os" + "path" + "testing" + + "vitess.io/vitess/go/mysql" + + "vitess.io/vitess/go/test/endtoend/cluster" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +var ( + clusterInstance *cluster.LocalProcessCluster + vtParams mysql.ConnParams + hostname = "localhost" + keyspaceName = "ks" + cell = "zone1" + schemaChangeDirectory = "" + totalTableCount = 4 + createTable = ` + CREATE TABLE %s ( + id bigint(20) NOT NULL, + msg varchar(64), + PRIMARY KEY (id) + ) ENGINE=InnoDB; + ` + insertIntoTable = ` + INSERT INTO %s (id, msg) VALUES (17, 'abc'); + ` + selectFromTable = ` + SELECT id, msg FROM %s LIMIT 1; + ` +) + +// TestMain is the main entry point +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitcode, err := func() (int, error) { + clusterInstance = cluster.NewCluster(cell, hostname) + schemaChangeDirectory = path.Join("/tmp", fmt.Sprintf("schema_change_dir_%d", clusterInstance.GetAndReserveTabletUID())) + defer os.RemoveAll(schemaChangeDirectory) + defer clusterInstance.Teardown() + + if _, err := os.Stat(schemaChangeDirectory); os.IsNotExist(err) { + _ = os.Mkdir(schemaChangeDirectory, 0700) + } + + clusterInstance.VtctldExtraArgs = []string{ + "-schema_change_dir", schemaChangeDirectory, + "-schema_change_controller", "local", + "-schema_change_check_interval", "1"} + + if err := clusterInstance.StartTopo(); err != nil { + return 1, err + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + } + + if err := clusterInstance.StartUnshardedKeyspace(*keyspace, 2, true); err != nil { + return 1, err + } + if err := clusterInstance.StartKeyspace(*keyspace, []string{"1"}, 1, false); err != nil { + return 1, err + } + + vtgateInstance := clusterInstance.NewVtgateInstance() + // set the gateway we want to use + vtgateInstance.GatewayImplementation = "tabletgateway" + // Start vtgate + if err := vtgateInstance.Setup(); err != nil { + return 1, err + } + // ensure it is torn down during cluster TearDown + clusterInstance.VtgateProcess = *vtgateInstance + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + + return m.Run(), nil + }() + if err != nil { + fmt.Printf("%v\n", err) + os.Exit(1) + } else { + os.Exit(exitcode) + } + +} + +func TestShards(t *testing.T) { + defer cluster.PanicHandler(t) + assert.Equal(t, 2, len(clusterInstance.Keyspaces[0].Shards)) +} + +func TestDeploySchema(t *testing.T) { + defer cluster.PanicHandler(t) + + if clusterInstance.ReusingVTDATAROOT { + // we assume data is already deployed + return + } + // Create n tables, populate + for i := 0; i < totalTableCount; i++ { + tableName := fmt.Sprintf("vt_upgrade_test_%02d", i) + + { + sqlQuery := fmt.Sprintf(createTable, tableName) + _, err := clusterInstance.VtctlclientProcess.ApplySchemaWithOutput(keyspaceName, sqlQuery, "") + require.Nil(t, err) + } + for i := range clusterInstance.Keyspaces[0].Shards { + sqlQuery := fmt.Sprintf(insertIntoTable, tableName) + tablet := clusterInstance.Keyspaces[0].Shards[i].Vttablets[0] + _, err := tablet.VttabletProcess.QueryTablet(sqlQuery, keyspaceName, true) + require.Nil(t, err) + } + } + + checkTables(t, "", totalTableCount) +} + +func TestTablesExist(t *testing.T) { + defer cluster.PanicHandler(t) + + checkTables(t, "", totalTableCount) +} + +// checkTables checks the number of tables in the first two shards. +func checkTables(t *testing.T, showTableName string, expectCount int) { + for i := range clusterInstance.Keyspaces[0].Shards { + checkTablesCount(t, clusterInstance.Keyspaces[0].Shards[i].Vttablets[0], showTableName, expectCount) + } +} + +// checkTablesCount checks the number of tables in the given tablet +func checkTablesCount(t *testing.T, tablet *cluster.Vttablet, showTableName string, expectCount int) { + query := fmt.Sprintf(`show tables like '%%%s%%';`, showTableName) + queryResult, err := tablet.VttabletProcess.QueryTablet(query, keyspaceName, true) + require.Nil(t, err) + assert.Equal(t, expectCount, len(queryResult.Rows)) +} + +// TestTablesData checks the data in tables +func TestTablesData(t *testing.T) { + // Create n tables, populate + for i := 0; i < totalTableCount; i++ { + tableName := fmt.Sprintf("vt_upgrade_test_%02d", i) + + for i := range clusterInstance.Keyspaces[0].Shards { + sqlQuery := fmt.Sprintf(selectFromTable, tableName) + tablet := clusterInstance.Keyspaces[0].Shards[i].Vttablets[0] + queryResult, err := tablet.VttabletProcess.QueryTablet(sqlQuery, keyspaceName, true) + require.Nil(t, err) + require.NotNil(t, queryResult) + row := queryResult.Named().Row() + require.NotNil(t, row) + require.Equal(t, int64(17), row.AsInt64("id", 0)) + require.Equal(t, "abc", row.AsString("msg", "")) + } + } +} diff --git a/test.go b/test.go index 3db180fc21c..bf355e39a72 100755 --- a/test.go +++ b/test.go @@ -90,6 +90,7 @@ var ( printLog = flag.Bool("print-log", false, "print the log of each failed test (or all tests if -log-pass) to the console") follow = flag.Bool("follow", false, "print test output as it runs, instead of waiting to see if it passes or fails") parallel = flag.Int("parallel", 1, "number of tests to run in parallel") + skipBuild = flag.Bool("skip-build", false, "skip running 'make build'. Assumes pre-existing binaries exist") remoteStats = flag.String("remote-stats", "", "url to send remote stats") ) @@ -380,6 +381,8 @@ func main() { log.Printf("Can't set permissions on temp dir %v: %v: %s", tmpDir, err, out) } vtRoot = tmpDir + } else if *skipBuild { + log.Printf("Skipping build...") } else { // Since we're sharing the working dir, do the build once for all tests. log.Printf("Running make build...") diff --git a/test/config.json b/test/config.json index a7a48e23a1b..34cf975e626 100644 --- a/test/config.json +++ b/test/config.json @@ -441,6 +441,15 @@ "site_test" ] }, + "upgrade": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/versionupgrade", "-keep-data", "-force-vtdataroot", "/tmp/vtdataroot/vtroot_10901", "-force-port-start", "11900", "-force-base-tablet-uid", "1190"], + "Command": [], + "Manual": false, + "Shard": 28, + "RetryMax": 0, + "Tags": [] + }, "vertical_split": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/sharding/verticalsplit"], From da39b1b271caa63bdec12081c0afd96393c0c12b Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 9 Jan 2021 11:47:34 +0100 Subject: [PATCH 051/310] Rename abort to cancel Signed-off-by: Rohit Nayak --- .../resharding_workflows_v2_test.go | 8 ++++---- go/vt/vtctl/vtctl.go | 20 +++++++++---------- go/vt/workflow/manager.go | 2 +- go/vt/wrangler/traffic_switcher.go | 2 +- go/vt/wrangler/workflow.go | 6 +++--- go/vt/wrangler/workflow_test.go | 10 +++++----- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go index 7d15ca31014..ccc287d132a 100644 --- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go +++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go @@ -47,7 +47,7 @@ const ( workflowActionSwitchTraffic = "SwitchTraffic" workflowActionReverseTraffic = "ReverseTraffic" workflowActionComplete = "Complete" - workflowActionAbort = "Abort" + workflowActionCancel = "Cancel" ) var ( @@ -154,8 +154,8 @@ func tstWorkflowComplete(t *testing.T) error { return tstWorkflowAction(t, workflowActionComplete, "", "") } -func tstWorkflowAbort(t *testing.T) error { - return tstWorkflowAction(t, workflowActionAbort, "", "") +func tstWorkflowCancel(t *testing.T) error { + return tstWorkflowAction(t, workflowActionCancel, "", "") } func validateReadsRoute(t *testing.T, tabletTypes string, tablet *cluster.VttabletProcess) { @@ -276,7 +276,7 @@ func testMoveTablesV2Workflow(t *testing.T) { output, _ = vc.VtctlClient.ExecuteCommandWithOutput(listAllArgs...) require.Contains(t, output, "Following workflow(s) found in keyspace customer: wf1") - err := tstWorkflowAbort(t) + err := tstWorkflowCancel(t) require.NoError(t, err) output, _ = vc.VtctlClient.ExecuteCommandWithOutput(listAllArgs...) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 91e86532984..b4b964d1a26 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1958,7 +1958,7 @@ const ( vReplicationWorkflowActionSwitchTraffic = "switchtraffic" vReplicationWorkflowActionReverseTraffic = "reversetraffic" vReplicationWorkflowActionComplete = "complete" - vReplicationWorkflowActionAbort = "abort" + vReplicationWorkflowActionCancel = "cancel" vReplicationWorkflowActionShow = "show" vReplicationWorkflowActionProgress = "progress" vReplicationWorkflowActionGetState = "getstate" @@ -1970,7 +1970,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla cells := subFlags.String("cells", "", "Cell(s) or CellAlias(es) (comma-separated) to replicate from.") tabletTypes := subFlags.String("tablet_types", "", "Source tablet types to replicate from (e.g. master, replica, rdonly). Defaults to -vreplication_tablet_type parameter value for the tablet, which has the default value of replica.") dryRun := subFlags.Bool("dry_run", false, "Does a dry run of SwitchReads and only reports the actions to be taken") - timeout := subFlags.Duration("timeout", 30*time.Second, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be aborted on timeout.") + timeout := subFlags.Duration("timeout", 30*time.Second, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be cancelled on a timeout.") reverseReplication := subFlags.Bool("reverse_replication", true, "Also reverse the replication") keepData := subFlags.Bool("keep_data", false, "Do not drop tables or shards (if true, only vreplication artifacts are cleaned up)") @@ -2088,7 +2088,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla vrwp.TabletTypes = *tabletTypes vrwp.Timeout = *timeout vrwp.EnableReverseReplication = *reverseReplication - case vReplicationWorkflowActionAbort: + case vReplicationWorkflowActionCancel: vrwp.KeepData = *keepData case vReplicationWorkflowActionComplete: switch workflowType { @@ -2212,8 +2212,8 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla err = wf.ReverseTraffic() case vReplicationWorkflowActionComplete: err = wf.Complete() - case vReplicationWorkflowActionAbort: - err = wf.Abort() + case vReplicationWorkflowActionCancel: + err = wf.Cancel() case vReplicationWorkflowActionGetState: wr.Logger().Printf(wf.CachedState() + "\n") return nil @@ -2300,7 +2300,7 @@ func commandVDiff(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.Fla sourceCell := subFlags.String("source_cell", "", "The source cell to compare from") targetCell := subFlags.String("target_cell", "", "The target cell to compare with") tabletTypes := subFlags.String("tablet_types", "master,replica,rdonly", "Tablet types for source and target") - filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be aborted on timeout.") + filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be cancelled on a timeout.") maxRows := subFlags.Int64("limit", math.MaxInt64, "Max rows to stop comparing after") format := subFlags.String("format", "", "Format of report") //"json" or "" tables := subFlags.String("tables", "", "Only run vdiff for these tables in the workflow") @@ -2341,7 +2341,7 @@ func commandMigrateServedTypes(ctx context.Context, wr *wrangler.Wrangler, subFl cellsStr := subFlags.String("cells", "", "Specifies a comma-separated list of cells to update") reverse := subFlags.Bool("reverse", false, "Moves the served tablet type backward instead of forward.") skipReFreshState := subFlags.Bool("skip-refresh-state", false, "Skips refreshing the state of the source tablets after the migration, meaning that the refresh will need to be done manually, replica and rdonly only)") - filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be aborted on timeout.") + filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be cancelled on a timeout.") reverseReplication := subFlags.Bool("reverse_replication", false, "For master migration, enabling this flag reverses replication which allows you to rollback") if err := subFlags.Parse(args); err != nil { return err @@ -2371,7 +2371,7 @@ func commandMigrateServedTypes(ctx context.Context, wr *wrangler.Wrangler, subFl func commandMigrateServedFrom(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { reverse := subFlags.Bool("reverse", false, "Moves the served tablet type backward instead of forward.") cellsStr := subFlags.String("cells", "", "Specifies a comma-separated list of cells to update") - filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be aborted on timeout.") + filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "Specifies the maximum time to wait, in seconds, for filtered replication to catch up on master migrations. The migration will be cancelled on a timeout.") if err := subFlags.Parse(args); err != nil { return err } @@ -2480,8 +2480,8 @@ func commandSwitchReads(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl } func commandSwitchWrites(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { - timeout := subFlags.Duration("timeout", 30*time.Second, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be aborted on timeout.") - filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "DEPRECATED Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be aborted on timeout.") + timeout := subFlags.Duration("timeout", 30*time.Second, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be cancelled on a timeout.") + filteredReplicationWaitTime := subFlags.Duration("filtered_replication_wait_time", 30*time.Second, "DEPRECATED Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be cancelled on a timeout.") reverseReplication := subFlags.Bool("reverse_replication", true, "Also reverse the replication") cancel := subFlags.Bool("cancel", false, "Cancel the failed migration and serve from source") reverse := subFlags.Bool("reverse", false, "Reverse a previous SwitchWrites serve from source") diff --git a/go/vt/workflow/manager.go b/go/vt/workflow/manager.go index 5b0b7ca696f..345b51b350a 100644 --- a/go/vt/workflow/manager.go +++ b/go/vt/workflow/manager.go @@ -180,7 +180,7 @@ func (m *Manager) Run(ctx context.Context) { m.workflows = make(map[string]*runningWorkflow) m.mu.Unlock() - // Abort the running jobs. They won't save their state as + // Cancel the running jobs. They won't save their state as // m.ctx is nil and they know it means we're shutting down. for _, rw := range runningWorkflows { rw.cancel() diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index 1dcc904fafc..e1fdb4aa6a9 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -570,7 +570,7 @@ func (wr *Wrangler) SwitchWrites(ctx context.Context, targetKeyspace, workflow s return ts.id, sw.logs(), nil } -// DropTargets cleans up target tables, shards and blacklisted tables if a MoveTables/Reshard is aborted +// DropTargets cleans up target tables, shards and blacklisted tables if a MoveTables/Reshard is cancelled func (wr *Wrangler) DropTargets(ctx context.Context, targetKeyspace, workflow string, keepData, dryRun bool) (*[]string, error) { ts, err := wr.buildTrafficSwitcher(ctx, targetKeyspace, workflow) if err != nil { diff --git a/go/vt/wrangler/workflow.go b/go/vt/wrangler/workflow.go index a15f0380edd..e297ab7453f 100644 --- a/go/vt/wrangler/workflow.go +++ b/go/vt/wrangler/workflow.go @@ -258,7 +258,7 @@ func (vrw *VReplicationWorkflow) ReverseTraffic() error { // Workflow errors const ( ErrWorkflowNotFullySwitched = "cannot complete workflow because you have not yet switched all read and write traffic" - ErrWorkflowPartiallySwitched = "cannot abort workflow because you have already switched some or all read and write traffic" + ErrWorkflowPartiallySwitched = "cannot cancel workflow because you have already switched some or all read and write traffic" ) // Complete cleans up a successful workflow @@ -280,8 +280,8 @@ func (vrw *VReplicationWorkflow) Complete() error { return nil } -// Abort deletes all artifacts from a workflow which has not yet been switched -func (vrw *VReplicationWorkflow) Abort() error { +// Cancel deletes all artifacts from a workflow which has not yet been switched +func (vrw *VReplicationWorkflow) Cancel() error { ws := vrw.ws if ws.WritesSwitched || len(ws.ReplicaCellsSwitched) > 0 || len(ws.RdonlyCellsSwitched) > 0 { return fmt.Errorf(ErrWorkflowPartiallySwitched) diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go index 42c85aed4e3..0d236480db2 100644 --- a/go/vt/wrangler/workflow_test.go +++ b/go/vt/wrangler/workflow_test.go @@ -57,7 +57,7 @@ func TestReshardingWorkflowErrorsAndMisc(t *testing.T) { require.True(t, mtwf.Exists()) require.Errorf(t, mtwf.Complete(), ErrWorkflowNotFullySwitched) mtwf.ws.WritesSwitched = true - require.Errorf(t, mtwf.Abort(), ErrWorkflowPartiallySwitched) + require.Errorf(t, mtwf.Cancel(), ErrWorkflowPartiallySwitched) require.ElementsMatch(t, mtwf.getCellsAsArray(), []string{"cell1", "cell2"}) require.ElementsMatch(t, mtwf.getTabletTypes(), []topodata.TabletType{topodata.TabletType_REPLICA, topodata.TabletType_RDONLY}) @@ -286,7 +286,7 @@ func TestMoveTablesV2Partial(t *testing.T) { } -func TestMoveTablesV2Abort(t *testing.T) { +func TestMoveTablesV2Cancel(t *testing.T) { ctx := context.Background() p := &VReplicationWorkflowParams{ Workflow: "test", @@ -312,7 +312,7 @@ func TestMoveTablesV2Abort(t *testing.T) { require.True(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks2", "t1")) require.True(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks2", "t2")) - require.NoError(t, wf.Abort()) + require.NoError(t, wf.Cancel()) validateRoutingRuleCount(ctx, t, wf.wr.ts, 0) @@ -356,7 +356,7 @@ func TestReshardV2(t *testing.T) { require.NotNil(t, si) } -func TestReshardV2Abort(t *testing.T) { +func TestReshardV2Cancel(t *testing.T) { ctx := context.Background() sourceShards := []string{"-40", "40-"} targetShards := []string{"-80", "80-"} @@ -378,7 +378,7 @@ func TestReshardV2Abort(t *testing.T) { require.Equal(t, WorkflowStateNotSwitched, wf.CurrentState()) tme.expectNoPreviousJournals() expectReshardQueries(t, tme) - require.NoError(t, wf.Abort()) + require.NoError(t, wf.Cancel()) } func expectReshardQueries(t *testing.T, tme *testShardMigraterEnv) { From 9c017a9f957cef6f91cbd258eb5681158fc63080 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 14 Jan 2021 18:07:57 +0100 Subject: [PATCH 052/310] Remove zero padding in prefixes for decimal data types Signed-off-by: Rohit Nayak --- go/mysql/binlog_event_rbr.go | 18 +- go/mysql/binlog_event_rbr_test.go | 2 +- .../tabletserver/vstreamer/vstreamer_test.go | 162 ++++++++++-------- 3 files changed, 108 insertions(+), 74 deletions(-) diff --git a/go/mysql/binlog_event_rbr.go b/go/mysql/binlog_event_rbr.go index 913cdc2100e..7c2341a322a 100644 --- a/go/mysql/binlog_event_rbr.go +++ b/go/mysql/binlog_event_rbr.go @@ -22,6 +22,7 @@ import ( "fmt" "math" "strconv" + "strings" "time" "vitess.io/vitess/go/sqltypes" @@ -764,8 +765,21 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, styp querypb.Typ } } - return sqltypes.MakeTrusted(querypb.Type_DECIMAL, - txt.Bytes()), l, nil + // remove preceding 0s from the integral part, otherwise we get "000000000001.23" instead of "1.23" + trimPrecedingZeroes := func(b []byte) []byte { + s := string(b) + isNegative := false + if s[0] == '-' { + isNegative = true + s = s[1:] + } + s = strings.TrimLeft(s, "0") + if isNegative { + s = fmt.Sprintf("-%s", s) + } + return []byte(s) + } + return sqltypes.MakeTrusted(querypb.Type_DECIMAL, trimPrecedingZeroes(txt.Bytes())), l, nil case TypeEnum: switch metadata & 0xff { diff --git a/go/mysql/binlog_event_rbr_test.go b/go/mysql/binlog_event_rbr_test.go index 314eaf21b07..d225b2b555f 100644 --- a/go/mysql/binlog_event_rbr_test.go +++ b/go/mysql/binlog_event_rbr_test.go @@ -473,7 +473,7 @@ func TestCellLengthAndData(t *testing.T) { metadata: 20<<8 | 2, // DECIMAL(20,2) data: []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0, 0x01, 0x0a}, out: sqltypes.MakeTrusted(querypb.Type_DECIMAL, - []byte("000000000000000001.10")), + []byte("1.10")), }, { typ: TypeBlob, metadata: 1, diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 38ac3392cfd..47026f8749d 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -1512,6 +1512,7 @@ func TestTypes(t *testing.T) { "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", "create table vitess_null(id int, val varbinary(128), primary key(id))", + "create table vitess_decimal(id int, dec1 decimal(12,4), dec2 decimal(13,4), primary key(id))", }) defer execStatements(t, []string{ "drop table vitess_ints", @@ -1519,80 +1520,99 @@ func TestTypes(t *testing.T) { "drop table vitess_strings", "drop table vitess_misc", "drop table vitess_null", + "drop table vitess_decimal", }) engine.se.Reload(context.Background()) - testcases := []testcase{{ - input: []string{ - "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - input: []string{ - "insert into vitess_fracts values(1, 1.99, 2.99, 3.99, 4.99)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. - input: []string{ - "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - // TODO(sougou): validate that the geometry value generates the correct DMLs on the other end. - input: []string{ - "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - input: []string{ - "insert into vitess_null values(1, null)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }} + testcases := []testcase{ + { + input: []string{ + "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_fracts values(1, 1.99, 2.99, 3.99, 4.99)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. + input: []string{ + "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + // TODO(sougou): validate that the geometry value generates the correct DMLs on the other end. + input: []string{ + "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_null values(1, null)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_decimal values(1, 1.23, 1.23)", + "insert into vitess_decimal values(2, -1.23, -1.23)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }, { + `begin`, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }} runCases(t, nil, testcases, "", nil) } From 9f0e4868de9f348dc491b3e5f829d1dacd99271d Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 14 Jan 2021 18:15:04 +0100 Subject: [PATCH 053/310] Fix formatting Signed-off-by: Rohit Nayak --- .../tabletserver/vstreamer/vstreamer_test.go | 175 +++++++++--------- 1 file changed, 87 insertions(+), 88 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 47026f8749d..b6e27cb1302 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -1524,95 +1524,94 @@ func TestTypes(t *testing.T) { }) engine.se.Reload(context.Background()) - testcases := []testcase{ - { - input: []string{ - "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - input: []string{ - "insert into vitess_fracts values(1, 1.99, 2.99, 3.99, 4.99)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. - input: []string{ - "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - // TODO(sougou): validate that the geometry value generates the correct DMLs on the other end. - input: []string{ - "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }, { - input: []string{ - "insert into vitess_null values(1, null)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, + testcases := []testcase{{ + input: []string{ + "insert into vitess_ints values(-128, 255, -32768, 65535, -8388608, 16777215, -2147483648, 4294967295, -9223372036854775808, 18446744073709551615, 2012)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_fracts values(1, 1.99, 2.99, 3.99, 4.99)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. + input: []string{ + "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + // TODO(sougou): validate that the geometry value generates the correct DMLs on the other end. + input: []string{ + "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: fields: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_null values(1, null)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }, { + input: []string{ + "insert into vitess_decimal values(1, 1.23, 1.23)", + "insert into vitess_decimal values(2, -1.23, -1.23)", + }, + output: [][]string{{ + `begin`, + `type:FIELD field_event: fields: fields: > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, }, { - input: []string{ - "insert into vitess_decimal values(1, 1.23, 1.23)", - "insert into vitess_decimal values(2, -1.23, -1.23)", - }, - output: [][]string{{ - `begin`, - `type:FIELD field_event: fields: fields: > `, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }, { - `begin`, - `type:ROW row_event: > > `, - `gtid`, - `commit`, - }}, - }} + `begin`, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }} runCases(t, nil, testcases, "", nil) } From 312b3dbf5a1cca3d0c50e8643ebdff44c97c5fa5 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 19 Jan 2021 15:09:04 +0100 Subject: [PATCH 054/310] Add tests per review comment Signed-off-by: Rohit Nayak --- .../tabletserver/vstreamer/vstreamer_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index b6e27cb1302..4851b685b2f 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -1598,6 +1598,8 @@ func TestTypes(t *testing.T) { input: []string{ "insert into vitess_decimal values(1, 1.23, 1.23)", "insert into vitess_decimal values(2, -1.23, -1.23)", + "insert into vitess_decimal values(3, 0000000001.23, 0000000001.23)", + "insert into vitess_decimal values(4, -0000000001.23, -0000000001.23)", }, output: [][]string{{ `begin`, @@ -1610,6 +1612,16 @@ func TestTypes(t *testing.T) { `type:ROW row_event: > > `, `gtid`, `commit`, + }, { + `begin`, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }, { + `begin`, + `type:ROW row_event: > > `, + `gtid`, + `commit`, }}, }} runCases(t, nil, testcases, "", nil) From d12d85d2f43298bb7fcee16a6c4fa3115b4edbb7 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 5 Jan 2021 22:16:45 +0100 Subject: [PATCH 055/310] Report current dry run results for v2 commands Signed-off-by: Rohit Nayak --- .../vreplication/vreplication_test_env.go | 14 +--- go/vt/vtctl/vtctl.go | 26 +++++-- go/vt/wrangler/switcher_dry_run.go | 34 +++------ go/vt/wrangler/traffic_switcher_test.go | 22 +----- go/vt/wrangler/workflow.go | 69 +++++++++++-------- go/vt/wrangler/workflow_test.go | 40 +++++++---- 6 files changed, 107 insertions(+), 98 deletions(-) diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index 62e31c59e11..eb196227094 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -26,16 +26,7 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ "Create journal entries on source databases", "Enable writes on keyspace customer tables customer", "Switch routing from keyspace product to keyspace customer", - "Following rules will be deleted:", - " customer.customer@rdonly => customer.customer", - " customer.customer@replica => customer.customer", - " customer@rdonly => customer.customer", - " customer@replica => customer.customer", - " product.customer@rdonly => customer.customer", - " product.customer@replica => customer.customer", - "Following rules will be added:", - " customer => customer.customer", - " product.customer => customer.customer", + "Routing rules for tables customer will be updated", "SwitchWrites completed, freeze and delete vreplication streams on:", " tablet 200 ", " tablet 300 ", @@ -50,7 +41,8 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ var dryRunResultsReadCustomerShard = []string{ "Lock keyspace product", - "Switch reads for tables customer to keyspace customer", + "Switch reads for tables customer to keyspace customer for tablet types REPLICA", + "Routing rules for tables customer will be updated", "Unlock keyspace product", } diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index b4b964d1a26..adaa48db6f8 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1968,7 +1968,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla workflowType wrangler.VReplicationWorkflowType) error { cells := subFlags.String("cells", "", "Cell(s) or CellAlias(es) (comma-separated) to replicate from.") - tabletTypes := subFlags.String("tablet_types", "", "Source tablet types to replicate from (e.g. master, replica, rdonly). Defaults to -vreplication_tablet_type parameter value for the tablet, which has the default value of replica.") + tabletTypes := subFlags.String("tablet_types", "master,replica,rdonly", "Source tablet types to replicate from (e.g. master, replica, rdonly). Defaults to -vreplication_tablet_type parameter value for the tablet, which has the default value of replica.") dryRun := subFlags.Bool("dry_run", false, "Does a dry run of SwitchReads and only reports the actions to be taken") timeout := subFlags.Duration("timeout", 30*time.Second, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be cancelled on a timeout.") reverseReplication := subFlags.Bool("reverse_replication", true, "Also reverse the replication") @@ -1986,7 +1986,6 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla _ = subFlags.Bool("v2", true, "") - _ = dryRun //TODO: add dry run functionality if err := subFlags.Parse(args); err != nil { return err } @@ -2139,6 +2138,16 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla return printDetails() } + + if *dryRun { + switch action { + case vReplicationWorkflowActionSwitchTraffic, vReplicationWorkflowActionReverseTraffic, vReplicationWorkflowActionComplete: + default: + return fmt.Errorf("-dry_run is only supported for SwitchTraffic, ReverseTraffic and Complete, not for %s", originalAction) + } + } + + var dryRunResults *[]string startState := wf.CachedState() switch action { case vReplicationWorkflowActionShow: @@ -2207,11 +2216,11 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla } } case vReplicationWorkflowActionSwitchTraffic: - err = wf.SwitchTraffic(wrangler.DirectionForward) + dryRunResults, err = wf.SwitchTraffic(wrangler.DirectionForward) case vReplicationWorkflowActionReverseTraffic: - err = wf.ReverseTraffic() + dryRunResults, err = wf.ReverseTraffic() case vReplicationWorkflowActionComplete: - err = wf.Complete() + dryRunResults, err = wf.Complete() case vReplicationWorkflowActionCancel: err = wf.Cancel() case vReplicationWorkflowActionGetState: @@ -2224,6 +2233,13 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla log.Warningf(" %s error: %v", originalAction, wf) return wrapError(wf, err) } + if *dryRun { + if len(*dryRunResults) > 0 { + wr.Logger().Printf("Dry Run results for %s run at %s\nParameters: %s\n\n", time.RFC822, originalAction, strings.Join(args, " ")) + wr.Logger().Printf("%s\n", strings.Join(*dryRunResults, "\n")) + return nil + } + } wr.Logger().Printf("%s was successful\nStart State: %s\nCurrent State: %s\n\n", originalAction, startState, wf.CurrentState()) return nil diff --git a/go/vt/wrangler/switcher_dry_run.go b/go/vt/wrangler/switcher_dry_run.go index 9e6d756f366..9e1e101fc7c 100644 --- a/go/vt/wrangler/switcher_dry_run.go +++ b/go/vt/wrangler/switcher_dry_run.go @@ -68,7 +68,14 @@ func (dr *switcherDryRun) switchTableReads(ctx context.Context, cells []string, if direction == DirectionBackward { ks = dr.ts.sourceKeyspace } - dr.drLog.Log(fmt.Sprintf("Switch reads for tables %s to keyspace %s", strings.Join(dr.ts.tables, ","), ks)) + var tabletTypes []string + for _, servedType := range servedTypes { + tabletTypes = append(tabletTypes, servedType.String()) + } + tables := strings.Join(dr.ts.tables, ",") + dr.drLog.Log(fmt.Sprintf("Switch reads for tables %s to keyspace %s for tablet types %s", + tables, ks, strings.Join(tabletTypes, ","))) + dr.drLog.Log(fmt.Sprintf("Routing rules for tables %s will be updated", tables)) return nil } @@ -87,30 +94,11 @@ func (dr *switcherDryRun) allowTargetWrites(ctx context.Context) error { } func (dr *switcherDryRun) changeRouting(ctx context.Context) error { - rules, err := dr.ts.wr.getRoutingRules(ctx) - if err != nil { - return err - } dr.drLog.Log(fmt.Sprintf("Switch routing from keyspace %s to keyspace %s", dr.ts.sourceKeyspace, dr.ts.targetKeyspace)) - deleteLogs := make([]string, 0) - addLogs := make([]string, 0) + var deleteLogs, addLogs []string if dr.ts.migrationType == binlogdatapb.MigrationType_TABLES { - for _, table := range dr.ts.tables { - for _, tabletType := range []topodatapb.TabletType{topodatapb.TabletType_REPLICA, topodatapb.TabletType_RDONLY} { - tt := strings.ToLower(tabletType.String()) - deleteLogs = append(deleteLogs, fmt.Sprintf("\t%s => %s", table+"@"+tt, strings.Trim(rules[table+"@"+tt][0], "[]"))) - deleteLogs = append(deleteLogs, fmt.Sprintf("\t%s => %s", dr.ts.targetKeyspace+"."+table+"@"+tt, strings.Trim(rules[dr.ts.targetKeyspace+"."+table+"@"+tt][0], "[]"))) - deleteLogs = append(deleteLogs, fmt.Sprintf("\t%s => %s", dr.ts.sourceKeyspace+"."+table+"@"+tt, strings.Trim(rules[dr.ts.sourceKeyspace+"."+table+"@"+tt][0], "[]"))) - } - addLogs = append(addLogs, fmt.Sprintf("\t%s => %s", table, dr.ts.targetKeyspace+"."+table)) - addLogs = append(addLogs, fmt.Sprintf("\t%s => %s", dr.ts.sourceKeyspace+"."+table, dr.ts.targetKeyspace+"."+table)) - } - if len(deleteLogs) > 0 { - dr.drLog.Log("Following rules will be deleted:") - dr.drLog.LogSlice(deleteLogs) - dr.drLog.Log("Following rules will be added:") - dr.drLog.LogSlice(addLogs) - } + tables := strings.Join(dr.ts.tables, ",") + dr.drLog.Log(fmt.Sprintf("Routing rules for tables %s will be updated", tables)) return nil } deleteLogs = nil diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go index ba428fb66da..e5e40aaf79a 100644 --- a/go/vt/wrangler/traffic_switcher_test.go +++ b/go/vt/wrangler/traffic_switcher_test.go @@ -930,7 +930,8 @@ func TestTableMigrateOneToManyDryRun(t *testing.T) { wantdryRunReads := []string{ "Lock keyspace ks1", - "Switch reads for tables t1,t2 to keyspace ks2", + "Switch reads for tables t1,t2 to keyspace ks2 for tablet types RDONLY", + "Routing rules for tables t1,t2 will be updated", "Unlock keyspace ks1", } wantdryRunWrites := []string{ @@ -943,24 +944,7 @@ func TestTableMigrateOneToManyDryRun(t *testing.T) { "Create journal entries on source databases", "Enable writes on keyspace ks2 tables t1,t2", "Switch routing from keyspace ks1 to keyspace ks2", - "Following rules will be deleted:", - " ks1.t1@rdonly => ks2.t1", - " ks1.t1@replica => ks2.t1", - " ks1.t2@rdonly => ks2.t2", - " ks1.t2@replica => ks2.t2", - " ks2.t1@rdonly => ks2.t1", - " ks2.t1@replica => ks2.t1", - " ks2.t2@rdonly => ks2.t2", - " ks2.t2@replica => ks2.t2", - " t1@rdonly => ks2.t1", - " t1@replica => ks2.t1", - " t2@rdonly => ks2.t2", - " t2@replica => ks2.t2", - "Following rules will be added:", - " ks1.t1 => ks2.t1", - " ks1.t2 => ks2.t2", - " t1 => ks2.t1", - " t2 => ks2.t2", + "Routing rules for tables t1,t2 will be updated", "SwitchWrites completed, freeze and delete vreplication streams on:", " tablet 20", " tablet 30", diff --git a/go/vt/wrangler/workflow.go b/go/vt/wrangler/workflow.go index e297ab7453f..56dede198cb 100644 --- a/go/vt/wrangler/workflow.go +++ b/go/vt/wrangler/workflow.go @@ -225,32 +225,41 @@ func (vrw *VReplicationWorkflow) GetStreamCount() (int64, int64, []*WorkflowErro } // SwitchTraffic switches traffic forward for tablet_types passed -func (vrw *VReplicationWorkflow) SwitchTraffic(direction TrafficSwitchDirection) error { +func (vrw *VReplicationWorkflow) SwitchTraffic(direction TrafficSwitchDirection) (*[]string, error) { + var dryRunResults []string + var rdDryRunResults, wrDryRunResults *[]string + var err error if !vrw.Exists() { - return fmt.Errorf("workflow has not yet been started") + return nil, fmt.Errorf("workflow has not yet been started") } vrw.params.Direction = direction hasReplica, hasRdonly, hasMaster, err := vrw.parseTabletTypes() if err != nil { - return err + return nil, err } if hasReplica || hasRdonly { - if err := vrw.switchReads(); err != nil { - return err + if rdDryRunResults, err = vrw.switchReads(); err != nil { + return nil, err } } + if rdDryRunResults != nil { + dryRunResults = append(dryRunResults, *rdDryRunResults...) + } if hasMaster { - if err := vrw.switchWrites(); err != nil { - return err + if wrDryRunResults, err = vrw.switchWrites(); err != nil { + return nil, err } } - return nil + if wrDryRunResults != nil { + dryRunResults = append(dryRunResults, *wrDryRunResults...) + } + return &dryRunResults, nil } // ReverseTraffic switches traffic backwards for tablet_types passed -func (vrw *VReplicationWorkflow) ReverseTraffic() error { +func (vrw *VReplicationWorkflow) ReverseTraffic() (*[]string, error) { if !vrw.Exists() { - return fmt.Errorf("workflow has not yet been started") + return nil, fmt.Errorf("workflow has not yet been started") } return vrw.SwitchTraffic(DirectionBackward) } @@ -262,10 +271,10 @@ const ( ) // Complete cleans up a successful workflow -func (vrw *VReplicationWorkflow) Complete() error { +func (vrw *VReplicationWorkflow) Complete() (*[]string, error) { ws := vrw.ws if !ws.WritesSwitched || len(ws.ReplicaCellsNotSwitched) > 0 || len(ws.RdonlyCellsNotSwitched) > 0 { - return fmt.Errorf(ErrWorkflowNotFullySwitched) + return nil, fmt.Errorf(ErrWorkflowNotFullySwitched) } var renameTable TableRemovalType if vrw.params.RenameTables { @@ -273,11 +282,13 @@ func (vrw *VReplicationWorkflow) Complete() error { } else { renameTable = DropTable } - if _, err := vrw.wr.DropSources(vrw.ctx, vrw.ws.TargetKeyspace, vrw.ws.Workflow, renameTable, vrw.params.KeepData, - false, false); err != nil { - return err + var dryRunResults *[]string + var err error + if dryRunResults, err = vrw.wr.DropSources(vrw.ctx, vrw.ws.TargetKeyspace, vrw.ws.Workflow, renameTable, vrw.params.KeepData, + false, vrw.params.DryRun); err != nil { + return nil, err } - return nil + return dryRunResults, nil } // Cancel deletes all artifacts from a workflow which has not yet been switched @@ -347,7 +358,7 @@ func (vrw *VReplicationWorkflow) initReshard() error { vrw.params.TargetShards, vrw.params.SkipSchemaCopy, vrw.params.Cells, vrw.params.TabletTypes) } -func (vrw *VReplicationWorkflow) switchReads() error { +func (vrw *VReplicationWorkflow) switchReads() (*[]string, error) { log.Infof("In VReplicationWorkflow.switchReads() for %+v", vrw) var tabletTypes []topodatapb.TabletType for _, tt := range vrw.getTabletTypes() { @@ -355,16 +366,20 @@ func (vrw *VReplicationWorkflow) switchReads() error { tabletTypes = append(tabletTypes, tt) } } - - _, err := vrw.wr.SwitchReads(vrw.ctx, vrw.params.TargetKeyspace, vrw.params.Workflow, tabletTypes, - vrw.getCellsAsArray(), vrw.params.Direction, false) + var dryRunResults *[]string + var err error + dryRunResults, err = vrw.wr.SwitchReads(vrw.ctx, vrw.params.TargetKeyspace, vrw.params.Workflow, tabletTypes, + vrw.getCellsAsArray(), vrw.params.Direction, vrw.params.DryRun) if err != nil { - return err + return nil, err } - return nil + return dryRunResults, nil } -func (vrw *VReplicationWorkflow) switchWrites() error { +func (vrw *VReplicationWorkflow) switchWrites() (*[]string, error) { + var journalID int64 + var dryRunResults *[]string + var err error log.Infof("In VReplicationWorkflow.switchWrites() for %+v", vrw) if vrw.params.Direction == DirectionBackward { keyspace := vrw.params.SourceKeyspace @@ -373,13 +388,13 @@ func (vrw *VReplicationWorkflow) switchWrites() error { vrw.params.Workflow = reverseName(vrw.params.Workflow) log.Infof("In VReplicationWorkflow.switchWrites(reverse) for %+v", vrw) } - journalID, _, err := vrw.wr.SwitchWrites(vrw.ctx, vrw.params.TargetKeyspace, vrw.params.Workflow, vrw.params.Timeout, - false, vrw.params.Direction == DirectionBackward, vrw.params.EnableReverseReplication, false) + journalID, dryRunResults, err = vrw.wr.SwitchWrites(vrw.ctx, vrw.params.TargetKeyspace, vrw.params.Workflow, vrw.params.Timeout, + false, vrw.params.Direction == DirectionBackward, vrw.params.EnableReverseReplication, vrw.params.DryRun) if err != nil { - return err + return nil, err } log.Infof("switchWrites succeeded with journal id %s", journalID) - return nil + return dryRunResults, nil } // endregion diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go index 0d236480db2..a9f3ebd5651 100644 --- a/go/vt/wrangler/workflow_test.go +++ b/go/vt/wrangler/workflow_test.go @@ -50,12 +50,16 @@ func getMoveTablesWorkflow(t *testing.T, cells, tabletTypes string) *VReplicatio return mtwf } +func testComplete(t *testing.T, vrwf *VReplicationWorkflow) error { + _, err := vrwf.Complete() + return err +} func TestReshardingWorkflowErrorsAndMisc(t *testing.T) { mtwf := getMoveTablesWorkflow(t, "cell1,cell2", "replica,rdonly") require.False(t, mtwf.Exists()) mtwf.ws = &workflowState{} require.True(t, mtwf.Exists()) - require.Errorf(t, mtwf.Complete(), ErrWorkflowNotFullySwitched) + require.Errorf(t, testComplete(t, mtwf), ErrWorkflowNotFullySwitched) mtwf.ws.WritesSwitched = true require.Errorf(t, mtwf.Cancel(), ErrWorkflowPartiallySwitched) @@ -165,12 +169,12 @@ func TestMoveTablesV2(t *testing.T) { tme.expectNoPreviousJournals() expectMoveTablesQueries(t, tme) tme.expectNoPreviousJournals() - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, WorkflowStateAllSwitched, wf.CurrentState()) tme.expectNoPreviousJournals() tme.expectNoPreviousReverseJournals() - require.NoError(t, wf.ReverseTraffic()) + require.NoError(t, testReverse(t, wf)) require.Equal(t, WorkflowStateNotSwitched, wf.CurrentState()) } @@ -211,7 +215,7 @@ func TestMoveTablesV2Complete(t *testing.T) { tme.expectNoPreviousJournals() expectMoveTablesQueries(t, tme) tme.expectNoPreviousJournals() - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, WorkflowStateAllSwitched, wf.CurrentState()) //16 rules, 8 per table t1,t2 eg: t1,t1@replica,t1@rdonly,ks1.t1,ks1.t1@replica,ks1.t1@rdonly,ks2.t1@replica,ks2.t1@rdonly @@ -220,7 +224,7 @@ func TestMoveTablesV2Complete(t *testing.T) { require.True(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks1", "t2")) require.True(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks2", "t1")) require.True(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks2", "t2")) - require.NoError(t, wf.Complete()) + require.NoError(t, testComplete(t, wf)) require.False(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks1", "t1")) require.False(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks1", "t2")) require.True(t, checkIfTableExistInVSchema(ctx, t, wf.wr.ts, "ks2", "t1")) @@ -229,6 +233,16 @@ func TestMoveTablesV2Complete(t *testing.T) { validateRoutingRuleCount(ctx, t, wf.wr.ts, 0) } +func testSwitchForward(t *testing.T, wf *VReplicationWorkflow) error { + _, err := wf.SwitchTraffic(DirectionForward) + return err +} + +func testReverse(t *testing.T, wf *VReplicationWorkflow) error { + _, err := wf.ReverseTraffic() + return err +} + func TestMoveTablesV2Partial(t *testing.T) { ctx := context.Background() p := &VReplicationWorkflowParams{ @@ -252,36 +266,36 @@ func TestMoveTablesV2Partial(t *testing.T) { tme.expectNoPreviousJournals() wf.params.TabletTypes = "replica" wf.params.Cells = "cell1" - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. Replica switched in cells: cell1. Rdonly not switched. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "replica" wf.params.Cells = "cell2" - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. All Replica Reads Switched. Rdonly not switched. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell1,cell2" - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, WorkflowStateReadsSwitched, wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "replica,rdonly" - require.NoError(t, wf.SwitchTraffic(DirectionBackward)) + require.NoError(t, testReverse(t, wf)) require.Equal(t, WorkflowStateNotSwitched, wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell1" - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. Replica not switched. Rdonly switched in cells: cell1. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell2" - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. Replica not switched. All Rdonly Reads Switched. Writes Not Switched", wf.CurrentState()) } @@ -345,9 +359,9 @@ func TestReshardV2(t *testing.T) { tme.expectNoPreviousJournals() expectReshardQueries(t, tme) tme.expectNoPreviousJournals() - require.NoError(t, wf.SwitchTraffic(DirectionForward)) + require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, WorkflowStateAllSwitched, wf.CurrentState()) - require.NoError(t, wf.Complete()) + require.NoError(t, testComplete(t, wf)) si, err := wf.wr.ts.GetShard(ctx, "ks", "-40") require.Contains(t, err.Error(), "node doesn't exist") require.Nil(t, si) From 41ced66167f6ce490aa697e035cae787b4d2bd66 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 14 Jan 2021 16:54:09 +0100 Subject: [PATCH 056/310] Addressed review comments Signed-off-by: Rohit Nayak --- .../vreplication/vreplication_test_env.go | 18 +++++++++--------- go/vt/wrangler/switcher_dry_run.go | 12 ++++++------ go/vt/wrangler/traffic_switcher_test.go | 14 +++++++------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index eb196227094..cbfd02f42cc 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -19,14 +19,14 @@ package vreplication var dryRunResultsSwitchWritesCustomerShard = []string{ "Lock keyspace product", "Lock keyspace customer", - "Stop writes on keyspace product, tables customer:", + "Stop writes on keyspace product, tables [customer]:", "/ Keyspace product, Shard 0 at Position", "Wait for VReplication on stopped streams to catchup for upto 30s", "Create reverse replication workflow p2c_reverse", "Create journal entries on source databases", - "Enable writes on keyspace customer tables customer", + "Enable writes on keyspace customer tables [customer]", "Switch routing from keyspace product to keyspace customer", - "Routing rules for tables customer will be updated", + "Routing rules for tables [customer] will be updated", "SwitchWrites completed, freeze and delete vreplication streams on:", " tablet 200 ", " tablet 300 ", @@ -41,8 +41,8 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ var dryRunResultsReadCustomerShard = []string{ "Lock keyspace product", - "Switch reads for tables customer to keyspace customer for tablet types REPLICA", - "Routing rules for tables customer will be updated", + "Switch reads for tables [customer] to keyspace customer for tablet types [REPLICA]", + "Routing rules for tables [customer] will be updated", "Unlock keyspace product", } @@ -57,13 +57,13 @@ var dryRunResultsSwitchWritesM2m3 = []string{ "/ Id 4 Keyspace customer Shard -80 Rules rules: at Position ", "/ Id 5 Keyspace customer Shard 80- Rules rules: at Position ", "/ Id 5 Keyspace customer Shard 80- Rules rules: at Position ", - "Stop writes on keyspace merchant, tables /.*:", + "Stop writes on keyspace merchant, tables [/.*]:", "/ Keyspace merchant, Shard -80 at Position", "/ Keyspace merchant, Shard 80- at Position", "Wait for VReplication on stopped streams to catchup for upto 30s", "Create reverse replication workflow m2m3_reverse", "Create journal entries on source databases", - "Enable writes on keyspace merchant tables /.*", + "Enable writes on keyspace merchant tables [/.*]", "Switch routing from keyspace merchant to keyspace merchant", "IsMasterServing will be set to false for:", " Shard -80, Tablet 400 ", @@ -91,7 +91,7 @@ var dryRunResultsDropSourcesDropCustomerShard = []string{ "Lock keyspace customer", "Dropping these tables from the database and removing them from the vschema for keyspace product:", " Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer", - "Blacklisted tables customer will be removed from:", + "Blacklisted tables [customer] will be removed from:", " Keyspace product Shard 0 Tablet 100", "Delete reverse vreplication streams on source:", " Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100", @@ -108,7 +108,7 @@ var dryRunResultsDropSourcesRenameCustomerShard = []string{ "Lock keyspace customer", "Renaming these tables from the database and removing them from the vschema for keyspace product:", " Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer", - "Blacklisted tables customer will be removed from:", + "Blacklisted tables [customer] will be removed from:", " Keyspace product Shard 0 Tablet 100", "Delete reverse vreplication streams on source:", " Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100", diff --git a/go/vt/wrangler/switcher_dry_run.go b/go/vt/wrangler/switcher_dry_run.go index 9e1e101fc7c..6f7a505ce6c 100644 --- a/go/vt/wrangler/switcher_dry_run.go +++ b/go/vt/wrangler/switcher_dry_run.go @@ -73,9 +73,9 @@ func (dr *switcherDryRun) switchTableReads(ctx context.Context, cells []string, tabletTypes = append(tabletTypes, servedType.String()) } tables := strings.Join(dr.ts.tables, ",") - dr.drLog.Log(fmt.Sprintf("Switch reads for tables %s to keyspace %s for tablet types %s", + dr.drLog.Log(fmt.Sprintf("Switch reads for tables [%s] to keyspace %s for tablet types [%s]", tables, ks, strings.Join(tabletTypes, ","))) - dr.drLog.Log(fmt.Sprintf("Routing rules for tables %s will be updated", tables)) + dr.drLog.Log(fmt.Sprintf("Routing rules for tables [%s] will be updated", tables)) return nil } @@ -89,7 +89,7 @@ func (dr *switcherDryRun) createJournals(ctx context.Context, sourceWorkflows [] } func (dr *switcherDryRun) allowTargetWrites(ctx context.Context) error { - dr.drLog.Log(fmt.Sprintf("Enable writes on keyspace %s tables %s", dr.ts.targetKeyspace, strings.Join(dr.ts.tables, ","))) + dr.drLog.Log(fmt.Sprintf("Enable writes on keyspace %s tables [%s]", dr.ts.targetKeyspace, strings.Join(dr.ts.tables, ","))) return nil } @@ -98,7 +98,7 @@ func (dr *switcherDryRun) changeRouting(ctx context.Context) error { var deleteLogs, addLogs []string if dr.ts.migrationType == binlogdatapb.MigrationType_TABLES { tables := strings.Join(dr.ts.tables, ",") - dr.drLog.Log(fmt.Sprintf("Routing rules for tables %s will be updated", tables)) + dr.drLog.Log(fmt.Sprintf("Routing rules for tables [%s] will be updated", tables)) return nil } deleteLogs = nil @@ -186,7 +186,7 @@ func (dr *switcherDryRun) stopSourceWrites(ctx context.Context) error { logs = append(logs, fmt.Sprintf("\tKeyspace %s, Shard %s at Position %s", dr.ts.sourceKeyspace, source.si.ShardName(), position)) } if len(logs) > 0 { - dr.drLog.Log(fmt.Sprintf("Stop writes on keyspace %s, tables %s:", dr.ts.sourceKeyspace, strings.Join(dr.ts.tables, ","))) + dr.drLog.Log(fmt.Sprintf("Stop writes on keyspace %s, tables [%s]:", dr.ts.sourceKeyspace, strings.Join(dr.ts.tables, ","))) dr.drLog.LogSlice(logs) } return nil @@ -307,7 +307,7 @@ func (dr *switcherDryRun) dropSourceBlacklistedTables(ctx context.Context) error logs = append(logs, fmt.Sprintf("\tKeyspace %s Shard %s Tablet %d", si.Keyspace(), si.ShardName(), si.MasterAlias.Uid)) } if len(logs) > 0 { - dr.drLog.Log(fmt.Sprintf("Blacklisted tables %s will be removed from:", strings.Join(dr.ts.tables, ","))) + dr.drLog.Log(fmt.Sprintf("Blacklisted tables [%s] will be removed from:", strings.Join(dr.ts.tables, ","))) dr.drLog.LogSlice(logs) } return nil diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go index e5e40aaf79a..5760220a8b8 100644 --- a/go/vt/wrangler/traffic_switcher_test.go +++ b/go/vt/wrangler/traffic_switcher_test.go @@ -861,7 +861,7 @@ func TestTableMigrateOneToMany(t *testing.T) { "Dropping these tables from the database and removing them from the vschema for keyspace ks1:", " Keyspace ks1 Shard 0 DbName vt_ks1 Tablet 10 Table t1", " Keyspace ks1 Shard 0 DbName vt_ks1 Tablet 10 Table t2", - "Blacklisted tables t1,t2 will be removed from:", + "Blacklisted tables [t1,t2] will be removed from:", " Keyspace ks1 Shard 0 Tablet 10", "Delete reverse vreplication streams on source:", " Keyspace ks1 Shard 0 Workflow test_reverse DbName vt_ks1 Tablet 10", @@ -888,7 +888,7 @@ func TestTableMigrateOneToMany(t *testing.T) { "Renaming these tables from the database and removing them from the vschema for keyspace ks1:", " " + "Keyspace ks1 Shard 0 DbName vt_ks1 Tablet 10 Table t1", " Keyspace ks1 Shard 0 DbName vt_ks1 Tablet 10 Table t2", - "Blacklisted tables t1,t2 will be removed from:", + "Blacklisted tables [t1,t2] will be removed from:", " Keyspace ks1 Shard 0 Tablet 10", "Delete reverse vreplication streams on source:", " Keyspace ks1 Shard 0 Workflow test_reverse DbName vt_ks1 Tablet 10", @@ -930,21 +930,21 @@ func TestTableMigrateOneToManyDryRun(t *testing.T) { wantdryRunReads := []string{ "Lock keyspace ks1", - "Switch reads for tables t1,t2 to keyspace ks2 for tablet types RDONLY", - "Routing rules for tables t1,t2 will be updated", + "Switch reads for tables [t1,t2] to keyspace ks2 for tablet types [RDONLY]", + "Routing rules for tables [t1,t2] will be updated", "Unlock keyspace ks1", } wantdryRunWrites := []string{ "Lock keyspace ks1", "Lock keyspace ks2", - "Stop writes on keyspace ks1, tables t1,t2:", + "Stop writes on keyspace ks1, tables [t1,t2]:", "\tKeyspace ks1, Shard 0 at Position MariaDB/5-456-892", "Wait for VReplication on stopped streams to catchup for upto 1s", "Create reverse replication workflow test_reverse", "Create journal entries on source databases", - "Enable writes on keyspace ks2 tables t1,t2", + "Enable writes on keyspace ks2 tables [t1,t2]", "Switch routing from keyspace ks1 to keyspace ks2", - "Routing rules for tables t1,t2 will be updated", + "Routing rules for tables [t1,t2] will be updated", "SwitchWrites completed, freeze and delete vreplication streams on:", " tablet 20", " tablet 30", From 3e7c0fe12dea4cf827e5f0f8aab3a285d8194e0c Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 19 Jan 2021 15:15:12 +0100 Subject: [PATCH 057/310] Address review comment Signed-off-by: Rohit Nayak --- go/vt/vtctl/vtctl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index adaa48db6f8..2d43dca3ba9 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1969,7 +1969,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla cells := subFlags.String("cells", "", "Cell(s) or CellAlias(es) (comma-separated) to replicate from.") tabletTypes := subFlags.String("tablet_types", "master,replica,rdonly", "Source tablet types to replicate from (e.g. master, replica, rdonly). Defaults to -vreplication_tablet_type parameter value for the tablet, which has the default value of replica.") - dryRun := subFlags.Bool("dry_run", false, "Does a dry run of SwitchReads and only reports the actions to be taken") + dryRun := subFlags.Bool("dry_run", false, "Does a dry run of SwitchReads and only reports the actions to be taken. -dry_run is only supported for SwitchTraffic, ReverseTraffic and Complete.") timeout := subFlags.Duration("timeout", 30*time.Second, "Specifies the maximum time to wait, in seconds, for vreplication to catch up on master migrations. The migration will be cancelled on a timeout.") reverseReplication := subFlags.Bool("reverse_replication", true, "Also reverse the replication") keepData := subFlags.Bool("keep_data", false, "Do not drop tables or shards (if true, only vreplication artifacts are cleaned up)") From 3fae163bf63f3641face1e848844046295b6e9ce Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 9 Jan 2021 09:18:54 +0100 Subject: [PATCH 058/310] Add master tablet type in addition to replica as default source tablet types Signed-off-by: Rohit Nayak --- go/vt/vttablet/tabletmanager/vreplication/engine.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index c507ee70f3c..406b49e8e55 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -72,7 +72,9 @@ func init() { withDDL = withddl.New(allddls) } -var tabletTypesStr = flag.String("vreplication_tablet_type", "REPLICA", "comma separated list of tablet types used as a source") +// this are the default tablet_types that will be used by the tablet picker to find sources for a vreplication stream +// it can be overridden by passing a different list to the MoveTables or Reshard commands +var tabletTypesStr = flag.String("vreplication_tablet_type", "MASTER,REPLICA", "comma separated list of tablet types used as a source") // waitRetryTime can be changed to a smaller value for tests. // A VReplication stream can be created by sending an insert statement From d650bc110c7b752a872ca35efb035b663724458f Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 9 Jan 2021 10:45:13 +0100 Subject: [PATCH 059/310] Add master tablet type in addition to replica as default source tablet types Signed-off-by: Rohit Nayak --- go.mod | 1 + go.sum | 2 + .../resharding_workflows_v2_test.go | 2 +- .../vreplication/vreplication_test.go | 4 +- go/vt/vtctl/vtctl.go | 1 + go/vt/vtgate/discoverygateway_test.go | 1 - go/vt/wrangler/traffic_switcher.go | 59 ++++++++++++++++++- go/vt/wrangler/traffic_switcher_test.go | 33 +++++------ go/vt/wrangler/workflow_test.go | 11 ++-- 9 files changed, 85 insertions(+), 29 deletions(-) diff --git a/go.mod b/go.mod index 4cb9a6c4e82..f074e7dbfc2 100644 --- a/go.mod +++ b/go.mod @@ -62,6 +62,7 @@ require ( github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 github.com/mattn/go-sqlite3 v1.14.0 github.com/minio/minio-go v0.0.0-20190131015406-c8a261de75c1 + github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/go-testing-interface v1.14.0 // indirect github.com/mitchellh/mapstructure v1.2.3 // indirect github.com/montanaflynn/stats v0.6.3 diff --git a/go.sum b/go.sum index 50b907dda98..efcf79e5849 100644 --- a/go.sum +++ b/go.sum @@ -488,6 +488,8 @@ github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXx github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go index ccc287d132a..ba9a5a88112 100644 --- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go +++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go @@ -523,7 +523,7 @@ func moveCustomerTableSwitchFlows(t *testing.T, cells []*Cell, sourceCellOrAlias switchWrites(t, ksWorkflow, false) validateWritesRouteToTarget(t) - switchWrites(t, ksWorkflow, true) + switchWrites(t, reverseKsWorkflow, true) validateWritesRouteToSource(t) validateReadsRouteToSource(t, "replica") diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index c6f722c5954..dde5228f238 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -637,7 +637,9 @@ func switchReadsDryRun(t *testing.T, cells, ksWorkflow string, dryRunResults []s } func switchReads(t *testing.T, cells, ksWorkflow string) { - output, err := vc.VtctlClient.ExecuteCommandWithOutput("SwitchReads", "-cells="+cells, "-tablet_type=rdonly", ksWorkflow) + var output string + var err error + output, err = vc.VtctlClient.ExecuteCommandWithOutput("SwitchReads", "-cells="+cells, "-tablet_type=rdonly", ksWorkflow) require.NoError(t, err, fmt.Sprintf("SwitchReads Error: %s: %s", err, output)) output, err = vc.VtctlClient.ExecuteCommandWithOutput("SwitchReads", "-cells="+cells, "-tablet_type=replica", ksWorkflow) require.NoError(t, err, fmt.Sprintf("SwitchReads Error: %s: %s", err, output)) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 2d43dca3ba9..c2077f67eca 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2200,6 +2200,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla case progress := <-progressCh: if progress.running == progress.total { wr.Logger().Printf("\nWorkflow started successfully with %d stream(s)\n", progress.total) + printDetails() return nil } wr.Logger().Printf("%d%% ... ", 100*progress.running/progress.total) diff --git a/go/vt/vtgate/discoverygateway_test.go b/go/vt/vtgate/discoverygateway_test.go index c91bc088b68..7acb8741f80 100644 --- a/go/vt/vtgate/discoverygateway_test.go +++ b/go/vt/vtgate/discoverygateway_test.go @@ -171,7 +171,6 @@ func TestDiscoveryGatewayWaitForTablets(t *testing.T) { }, }, } - dg := NewDiscoveryGateway(context.Background(), hc, srvTopo, "local", 2) // replica should only use local ones diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index e1fdb4aa6a9..d669f77ca41 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -25,6 +25,7 @@ import ( "strings" "sync" "time" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtgate/evalengine" @@ -346,6 +347,39 @@ func (wr *Wrangler) getWorkflowState(ctx context.Context, targetKeyspace, workfl return ts, ws, nil } +func (wr *Wrangler) doCellsHaveRdonlyTablets(ctx context.Context, cells []string) (bool, error) { + areAnyRdonly := func(tablets []*topo.TabletInfo) bool { + for _, tablet := range tablets { + if tablet.Type == topodatapb.TabletType_RDONLY { + return true + } + } + return false + } + + if len(cells) == 0 { + tablets, err := topotools.GetAllTabletsAcrossCells(ctx, wr.ts) + if err != nil { + return false, err + } + if areAnyRdonly(tablets) { + return true, nil + } + + } else { + for _, cell := range cells { + tablets, err := topotools.GetAllTablets(ctx, wr.ts, cell) + if err != nil { + return false, err + } + if areAnyRdonly(tablets) { + return true, nil + } + } + } + return false, nil +} + // SwitchReads is a generic way of switching read traffic for a resharding workflow. func (wr *Wrangler) SwitchReads(ctx context.Context, targetKeyspace, workflow string, servedTypes []topodatapb.TabletType, cells []string, direction TrafficSwitchDirection, dryRun bool) (*[]string, error) { @@ -360,7 +394,8 @@ func (wr *Wrangler) SwitchReads(ctx context.Context, targetKeyspace, workflow st wr.Logger().Errorf(errorMsg) return nil, fmt.Errorf(errorMsg) } - wr.Logger().Infof("SwitchReads: %s.%s tt %+v, cells %+v, workflow state: %+v", targetKeyspace, workflow, servedTypes, cells, ws) + log.Infof("SwitchReads: %s.%s tt %+v, cells %+v, workflow state: %+v", targetKeyspace, workflow, servedTypes, cells, ws) + var switchReplicas, switchRdonly bool for _, servedType := range servedTypes { if servedType != topodatapb.TabletType_REPLICA && servedType != topodatapb.TabletType_RDONLY { return nil, fmt.Errorf("tablet type must be REPLICA or RDONLY: %v", servedType) @@ -371,6 +406,26 @@ func (wr *Wrangler) SwitchReads(ctx context.Context, targetKeyspace, workflow st if direction == DirectionBackward && servedType == topodatapb.TabletType_RDONLY && len(ws.RdonlyCellsSwitched) == 0 { return nil, fmt.Errorf("requesting reversal of SwitchReads for RDONLYs but RDONLY reads have not been switched") } + switch servedType { + case topodatapb.TabletType_REPLICA: + switchReplicas = true + case topodatapb.TabletType_RDONLY: + switchRdonly = true + } + } + + // if there are no rdonly tablets in the cells ask to switch rdonly tablets as well so that routing rules + // are updated for rdonly as well. Otherwise vitess will not know that the workflow has completed and will + // incorrectly report that not all reads have been switched. User currently is forced to switch non-existent rdonly tablets + if switchReplicas && !switchRdonly { + var err error + rdonlyTabletsExist, err := wr.doCellsHaveRdonlyTablets(ctx, cells) + if err != nil { + return nil, err + } + if !rdonlyTabletsExist { + servedTypes = append(servedTypes, topodatapb.TabletType_RDONLY) + } } // If journals exist notify user and fail @@ -380,7 +435,7 @@ func (wr *Wrangler) SwitchReads(ctx context.Context, targetKeyspace, workflow st return nil, err } if journalsExist { - wr.Logger().Errorf("Found a previous journal entry for %d", ts.id) + log.Infof("Found a previous journal entry for %d", ts.id) } var sw iswitcher if dryRun { diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go index 5760220a8b8..092ce43fd18 100644 --- a/go/vt/wrangler/traffic_switcher_test.go +++ b/go/vt/wrangler/traffic_switcher_test.go @@ -177,12 +177,12 @@ func TestTableMigrateMainflow(t *testing.T) { "ks2.t1": {"ks1.t1"}, "t2": {"ks1.t2"}, "ks2.t2": {"ks1.t2"}, - "t1@rdonly": {"ks2.t1"}, - "ks2.t1@rdonly": {"ks2.t1"}, - "ks1.t1@rdonly": {"ks2.t1"}, - "t2@rdonly": {"ks2.t2"}, - "ks2.t2@rdonly": {"ks2.t2"}, - "ks1.t2@rdonly": {"ks2.t2"}, + "t1@rdonly": {"ks1.t1"}, + "ks2.t1@rdonly": {"ks1.t1"}, + "ks1.t1@rdonly": {"ks1.t1"}, + "t2@rdonly": {"ks1.t2"}, + "ks2.t2@rdonly": {"ks1.t2"}, + "ks1.t2@rdonly": {"ks1.t2"}, "t1@replica": {"ks1.t1"}, "ks2.t1@replica": {"ks1.t1"}, "ks1.t1@replica": {"ks1.t1"}, @@ -526,10 +526,10 @@ func TestShardMigrateMainflow(t *testing.T) { checkCellServedTypes(t, tme.ts, "ks:40-", "cell1", 2) checkCellServedTypes(t, tme.ts, "ks:-80", "cell1", 1) checkCellServedTypes(t, tme.ts, "ks:80-", "cell1", 1) - checkCellServedTypes(t, tme.ts, "ks:-40", "cell2", 2) - checkCellServedTypes(t, tme.ts, "ks:40-", "cell2", 2) - checkCellServedTypes(t, tme.ts, "ks:-80", "cell2", 1) - checkCellServedTypes(t, tme.ts, "ks:80-", "cell2", 1) + checkCellServedTypes(t, tme.ts, "ks:-40", "cell2", 1) + checkCellServedTypes(t, tme.ts, "ks:40-", "cell2", 1) + checkCellServedTypes(t, tme.ts, "ks:-80", "cell2", 2) + checkCellServedTypes(t, tme.ts, "ks:80-", "cell2", 2) verifyQueries(t, tme.allDBClients) tme.expectNoPreviousJournals() @@ -1764,7 +1764,7 @@ func checkCellRouting(t *testing.T, wr *Wrangler, cell string, want map[string][ got[rr.FromTable] = append(got[rr.FromTable], rr.ToTables...) } if !reflect.DeepEqual(got, want) { - t.Errorf("srv rules for cell %s:\n%v, want\n%v", cell, got, want) + t.Fatalf("ERROR: routing rules don't match for cell %s:got\n%v, want\n%v", cell, got, want) } } @@ -1799,10 +1799,8 @@ func checkServedTypes(t *testing.T, ts *topo.Server, keyspaceShard string, want if err != nil { t.Fatal(err) } - - if len(servedTypes) != want { - t.Errorf("shard %v has wrong served types: got: %v, want: %v", keyspaceShard, len(servedTypes), want) - } + require.Equal(t, want, len(servedTypes), fmt.Sprintf("shard %v has wrong served types: got: %v, want: %v", + keyspaceShard, len(servedTypes), want)) } func checkCellServedTypes(t *testing.T, ts *topo.Server, keyspaceShard, cell string, want int) { @@ -1823,9 +1821,8 @@ outer: } } } - if count != want { - t.Errorf("serving types for keyspaceShard %s, cell %s: %d, want %d", keyspaceShard, cell, count, want) - } + require.Equal(t, want, count, fmt.Sprintf("serving types for keyspaceShard %s, cell %s: %d, want %d", + keyspaceShard, cell, count, want)) } func checkIsMasterServing(t *testing.T, ts *topo.Server, keyspaceShard string, want bool) { diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go index a9f3ebd5651..9e1c5c9cd4c 100644 --- a/go/vt/wrangler/workflow_test.go +++ b/go/vt/wrangler/workflow_test.go @@ -264,19 +264,19 @@ func TestMoveTablesV2Partial(t *testing.T) { expectMoveTablesQueries(t, tme) tme.expectNoPreviousJournals() - wf.params.TabletTypes = "replica" + wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell1" require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. Replica switched in cells: cell1. Rdonly not switched. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() - wf.params.TabletTypes = "replica" + wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell2" require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. All Replica Reads Switched. Rdonly not switched. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() - wf.params.TabletTypes = "rdonly" + wf.params.TabletTypes = "replica" wf.params.Cells = "cell1,cell2" require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, WorkflowStateReadsSwitched, wf.CurrentState()) @@ -287,17 +287,16 @@ func TestMoveTablesV2Partial(t *testing.T) { require.Equal(t, WorkflowStateNotSwitched, wf.CurrentState()) tme.expectNoPreviousJournals() - wf.params.TabletTypes = "rdonly" + wf.params.TabletTypes = "replica" wf.params.Cells = "cell1" require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. Replica not switched. Rdonly switched in cells: cell1. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() - wf.params.TabletTypes = "rdonly" + wf.params.TabletTypes = "replica" wf.params.Cells = "cell2" require.NoError(t, testSwitchForward(t, wf)) require.Equal(t, "Reads partially switched. Replica not switched. All Rdonly Reads Switched. Writes Not Switched", wf.CurrentState()) - } func TestMoveTablesV2Cancel(t *testing.T) { From 99c1ffd5bc9f96bb6a449c2600fecf5ac1f8a8ad Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 9 Jan 2021 11:18:14 +0100 Subject: [PATCH 060/310] gofmted Signed-off-by: Rohit Nayak --- go/vt/wrangler/traffic_switcher.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index d669f77ca41..d380fd78835 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -25,6 +25,7 @@ import ( "strings" "sync" "time" + "vitess.io/vitess/go/vt/topotools" "vitess.io/vitess/go/vt/vtgate/evalengine" From 917f7bd12107d6a91dd87f890ea05a6b5dd08be8 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 9 Jan 2021 16:21:48 +0100 Subject: [PATCH 061/310] Rename workflow Start to Create Signed-off-by: Rohit Nayak --- .../resharding_workflows_v2_test.go | 18 +++++++++--------- go/vt/vtctl/vtctl.go | 10 +++++----- go/vt/wrangler/workflow.go | 16 ++++++++-------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go index ba9a5a88112..9541c154730 100644 --- a/go/test/endtoend/vreplication/resharding_workflows_v2_test.go +++ b/go/test/endtoend/vreplication/resharding_workflows_v2_test.go @@ -43,7 +43,7 @@ const ( ) const ( - workflowActionStart = "Start" + workflowActionCreate = "Create" workflowActionSwitchTraffic = "SwitchTraffic" workflowActionReverseTraffic = "ReverseTraffic" workflowActionComplete = "Complete" @@ -58,9 +58,9 @@ var ( currentWorkflowType wrangler.VReplicationWorkflowType ) -func reshard2Start(t *testing.T, sourceShards, targetShards string) error { +func createReshardWorkflow(t *testing.T, sourceShards, targetShards string) error { err := tstWorkflowExec(t, defaultCellName, workflowName, targetKs, targetKs, - "", workflowActionStart, "", sourceShards, targetShards) + "", workflowActionCreate, "", sourceShards, targetShards) require.NoError(t, err) time.Sleep(1 * time.Second) catchup(t, targetTab1, workflowName, "Reshard") @@ -69,12 +69,12 @@ func reshard2Start(t *testing.T, sourceShards, targetShards string) error { return nil } -func moveTables2Start(t *testing.T, tables string) error { +func createMoveTablesWorkflow(t *testing.T, tables string) error { if tables == "" { tables = tablesToMove } err := tstWorkflowExec(t, defaultCellName, workflowName, sourceKs, targetKs, - tables, workflowActionStart, "", "", "") + tables, workflowActionCreate, "", "", "") require.NoError(t, err) catchup(t, targetTab1, workflowName, "MoveTables") catchup(t, targetTab2, workflowName, "MoveTables") @@ -96,7 +96,7 @@ func tstWorkflowExec(t *testing.T, cells, workflow, sourceKs, targetKs, tables, } args = append(args, "-v2") switch action { - case workflowActionStart: + case workflowActionCreate: if currentWorkflowType == wrangler.MoveTablesWorkflow { args = append(args, "-source", sourceKs, "-tables", tables) } else { @@ -244,7 +244,7 @@ func testReshardV2Workflow(t *testing.T) { currentWorkflowType = wrangler.ReshardWorkflow createAdditionalCustomerShards(t, "-40,40-80,80-c0,c0-") - reshard2Start(t, "-80,80-", "-40,40-80,80-c0,c0-") + createReshardWorkflow(t, "-80,80-", "-40,40-80,80-c0,c0-") if !strings.Contains(lastOutput, "Workflow started successfully") { t.Fail() } @@ -259,7 +259,7 @@ func testMoveTablesV2Workflow(t *testing.T) { // test basic forward and reverse flows setupCustomerKeyspace(t) - moveTables2Start(t, "customer") + createMoveTablesWorkflow(t, "customer") if !strings.Contains(lastOutput, "Workflow started successfully") { t.Fail() } @@ -272,7 +272,7 @@ func testMoveTablesV2Workflow(t *testing.T) { output, _ := vc.VtctlClient.ExecuteCommandWithOutput(listAllArgs...) require.Contains(t, output, "No workflows found in keyspace customer") - moveTables2Start(t, "customer2") + createMoveTablesWorkflow(t, "customer2") output, _ = vc.VtctlClient.ExecuteCommandWithOutput(listAllArgs...) require.Contains(t, output, "Following workflow(s) found in keyspace customer: wf1") diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index c2077f67eca..fd05c15c3e5 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -1954,7 +1954,7 @@ func commandMoveTables(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla type VReplicationWorkflowAction string const ( - vReplicationWorkflowActionStart = "start" + vReplicationWorkflowActionCreate = "create" vReplicationWorkflowActionSwitchTraffic = "switchtraffic" vReplicationWorkflowActionReverseTraffic = "reversetraffic" vReplicationWorkflowActionComplete = "complete" @@ -2052,7 +2052,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla originalAction := action action = strings.ToLower(action) // allow users to input action in a case-insensitive manner switch action { - case vReplicationWorkflowActionStart: + case vReplicationWorkflowActionCreate: switch workflowType { case wrangler.MoveTablesWorkflow: if *sourceKeyspace == "" { @@ -2105,7 +2105,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla log.Warningf("NewVReplicationWorkflow returned error %+v", wf) return err } - if !wf.Exists() && action != vReplicationWorkflowActionStart { + if !wf.Exists() && action != vReplicationWorkflowActionCreate { return fmt.Errorf("workflow %s does not exist", ksWorkflow) } @@ -2154,8 +2154,8 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla return printDetails() case vReplicationWorkflowActionProgress: return printCopyProgress() - case vReplicationWorkflowActionStart: - err = wf.Start() + case vReplicationWorkflowActionCreate: + err = wf.Create() if err != nil { return err } diff --git a/go/vt/wrangler/workflow.go b/go/vt/wrangler/workflow.go index 56dede198cb..24a110653c5 100644 --- a/go/vt/wrangler/workflow.go +++ b/go/vt/wrangler/workflow.go @@ -26,7 +26,7 @@ const ( // Workflow state display strings const ( - WorkflowStateNotStarted = "Not Started" + WorkflowStateNotCreated = "Not Created" WorkflowStateNotSwitched = "Reads Not Switched. Writes Not Switched" WorkflowStateReadsSwitched = "All Reads Switched. Writes Not Switched" WorkflowStateWritesSwitched = "Reads Not Switched. Writes Switched" @@ -82,7 +82,7 @@ func (wr *Wrangler) NewVReplicationWorkflow(ctx context.Context, workflowType VR return nil, err } log.Infof("Workflow state is %+v", ws) - if ts != nil { //Other than on Start we need to get SourceKeyspace from the workflow + if ts != nil { //Other than on create we need to get SourceKeyspace from the workflow vrw.params.TargetKeyspace = ts.targetKeyspace vrw.params.Workflow = ts.workflow vrw.params.SourceKeyspace = ts.sourceKeyspace @@ -120,7 +120,7 @@ func (vrw *VReplicationWorkflow) stateAsString(ws *workflowState) string { var stateInfo []string s := "" if !vrw.Exists() { - stateInfo = append(stateInfo, WorkflowStateNotStarted) + stateInfo = append(stateInfo, WorkflowStateNotCreated) } else { if len(ws.RdonlyCellsNotSwitched) == 0 && len(ws.ReplicaCellsNotSwitched) == 0 && len(ws.ReplicaCellsSwitched) > 0 { s = "All Reads Switched" @@ -155,14 +155,14 @@ func (vrw *VReplicationWorkflow) stateAsString(ws *workflowState) string { return strings.Join(stateInfo, ". ") } -// Start initiates a workflow -func (vrw *VReplicationWorkflow) Start() error { +// Create initiates a workflow +func (vrw *VReplicationWorkflow) Create() error { var err error if vrw.Exists() { - return fmt.Errorf("workflow already exists found") + return fmt.Errorf("workflow already exists") } - if vrw.CachedState() != WorkflowStateNotStarted { - return fmt.Errorf("workflow has already been started, state is %s", vrw.CachedState()) + if vrw.CachedState() != WorkflowStateNotCreated { + return fmt.Errorf("workflow has already been created, state is %s", vrw.CachedState()) } switch vrw.workflowType { case MoveTablesWorkflow: From 82f00bb7a742617f9113df90567ac5d17d1f68d0 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 14 Jan 2021 23:13:33 +0100 Subject: [PATCH 062/310] Check that workflow is not in copy phase when switching traffic Signed-off-by: Rohit Nayak --- go/vt/vtctl/vtctl.go | 5 ++++- go/vt/wrangler/workflow.go | 33 ++++++++++++++++++++++++++++++++- go/vt/wrangler/workflow_test.go | 18 ++++++++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index fd05c15c3e5..05f7a10e8b5 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2085,6 +2085,9 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla case vReplicationWorkflowActionSwitchTraffic, vReplicationWorkflowActionReverseTraffic: vrwp.Cells = *cells vrwp.TabletTypes = *tabletTypes + if vrwp.TabletTypes == "" { + vrwp.TabletTypes = "master,replica,rdonly" + } vrwp.Timeout = *timeout vrwp.EnableReverseReplication = *reverseReplication case vReplicationWorkflowActionCancel: @@ -2117,7 +2120,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla if copyProgress == nil { wr.Logger().Printf("\nCopy Completed.\n") } else { - wr.Logger().Printf("\nCopy Progress (approx.):\n") + wr.Logger().Printf("\nCopy Progress (approx):\n") var tables []string for table := range *copyProgress { tables = append(tables, table) diff --git a/go/vt/wrangler/workflow.go b/go/vt/wrangler/workflow.go index 24a110653c5..c1cf3469bdb 100644 --- a/go/vt/wrangler/workflow.go +++ b/go/vt/wrangler/workflow.go @@ -228,12 +228,24 @@ func (vrw *VReplicationWorkflow) GetStreamCount() (int64, int64, []*WorkflowErro func (vrw *VReplicationWorkflow) SwitchTraffic(direction TrafficSwitchDirection) (*[]string, error) { var dryRunResults []string var rdDryRunResults, wrDryRunResults *[]string + var isCopyInProgress bool var err error + var hasReplica, hasRdonly, hasMaster bool + if !vrw.Exists() { return nil, fmt.Errorf("workflow has not yet been started") } + + isCopyInProgress, err = vrw.IsCopyInProgress() + if err != nil { + return nil, err + } + if isCopyInProgress { + return nil, fmt.Errorf("cannot switch traffic at this time, copy is still in progress for this workflow") + } + vrw.params.Direction = direction - hasReplica, hasRdonly, hasMaster, err := vrw.parseTabletTypes() + hasReplica, hasRdonly, hasMaster, err = vrw.parseTabletTypes() if err != nil { return nil, err } @@ -410,6 +422,25 @@ type TableCopyProgress struct { // CopyProgress stores the TableCopyProgress for all tables still being copied type CopyProgress map[string]*TableCopyProgress +// IsCopyInProgress returns true if any table remains to be copied +func (vrw *VReplicationWorkflow) IsCopyInProgress() (bool, error) { + ctx := context.Background() + getTablesQuery := "select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = %d" + for _, target := range vrw.ts.targets { + for id := range target.sources { + query := fmt.Sprintf(getTablesQuery, id) + p3qr, err := vrw.wr.tmc.ExecuteFetchAsDba(ctx, target.master.Tablet, true, []byte(query), 1, false, false) + if err != nil { + return false, err + } + if len(p3qr.Rows) > 0 { + return true, nil + } + } + } + return false, nil +} + // GetCopyProgress returns the progress of all tables being copied in the workflow func (vrw *VReplicationWorkflow) GetCopyProgress() (*CopyProgress, error) { ctx := context.Background() diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go index 9e1c5c9cd4c..95f2c61fb36 100644 --- a/go/vt/wrangler/workflow_test.go +++ b/go/vt/wrangler/workflow_test.go @@ -104,8 +104,9 @@ func TestCopyProgress(t *testing.T) { expectCopyProgressQueries(t, tme) - cp, err2 := wf.GetCopyProgress() - require.NoError(t, err2) + var cp *CopyProgress + cp, err = wf.GetCopyProgress() + require.NoError(t, err) log.Infof("CopyProgress is %+v,%+v", (*cp)["t1"], (*cp)["t2"]) require.Equal(t, int64(800), (*cp)["t1"].SourceRowCount) @@ -117,6 +118,11 @@ func TestCopyProgress(t *testing.T) { require.Equal(t, int64(400), (*cp)["t2"].TargetRowCount) require.Equal(t, int64(4000), (*cp)["t2"].SourceTableSize) require.Equal(t, int64(1000), (*cp)["t2"].TargetTableSize) + + var isCopyInProgress bool + isCopyInProgress, err = wf.IsCopyInProgress() + require.NoError(t, err) + require.True(t, isCopyInProgress) } func expectCopyProgressQueries(t *testing.T, tme *testMigraterEnv) { @@ -147,6 +153,14 @@ func expectCopyProgressQueries(t *testing.T, tme *testMigraterEnv) { "t2|1000|2000") db.AddQuery(query, result) + for _, id := range []int{1, 2} { + query = fmt.Sprintf("select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = %d", id) + result = sqltypes.MakeTestResult(sqltypes.MakeTestFields( + "dummy", + "int64"), + "1") + db.AddQuery(query, result) + } } func TestMoveTablesV2(t *testing.T) { From 724d1ab4ef287f6b1ddbc83e051151f9e34713be Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Fri, 15 Jan 2021 00:05:04 +0100 Subject: [PATCH 063/310] Fix tests Signed-off-by: Rohit Nayak --- go/vt/wrangler/traffic_switcher_env_test.go | 5 +++-- go/vt/wrangler/workflow_test.go | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/go/vt/wrangler/traffic_switcher_env_test.go b/go/vt/wrangler/traffic_switcher_env_test.go index b71dab625a1..2c8531b4e9a 100644 --- a/go/vt/wrangler/traffic_switcher_env_test.go +++ b/go/vt/wrangler/traffic_switcher_env_test.go @@ -242,10 +242,11 @@ func newTestShardMigrater(ctx context.Context, t *testing.T, sourceShards, targe tme.wr = New(logutil.NewConsoleLogger(), tme.ts, tmclient.NewTabletManagerClient()) tme.sourceShards = sourceShards tme.targetShards = targetShards + tme.tmeDB = fakesqldb.New(t) tabletID := 10 for _, shard := range sourceShards { - tme.sourceMasters = append(tme.sourceMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", shard))) + tme.sourceMasters = append(tme.sourceMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, tme.tmeDB, TabletKeyspaceShard(t, "ks", shard))) tabletID += 10 _, sourceKeyRange, err := topo.ValidateShardName(shard) @@ -261,7 +262,7 @@ func newTestShardMigrater(ctx context.Context, t *testing.T, sourceShards, targe } for _, shard := range targetShards { - tme.targetMasters = append(tme.targetMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, nil, TabletKeyspaceShard(t, "ks", shard))) + tme.targetMasters = append(tme.targetMasters, newFakeTablet(t, tme.wr, "cell1", uint32(tabletID), topodatapb.TabletType_MASTER, tme.tmeDB, TabletKeyspaceShard(t, "ks", shard))) tabletID += 10 _, targetKeyRange, err := topo.ValidateShardName(shard) diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go index 95f2c61fb36..63da455d91f 100644 --- a/go/vt/wrangler/workflow_test.go +++ b/go/vt/wrangler/workflow_test.go @@ -428,7 +428,6 @@ func expectReshardQueries(t *testing.T, tme *testShardMigraterEnv) { dbclient.addInvariant("select * from _vt.vreplication where id = 1", runningResult(1)) dbclient.addInvariant("select * from _vt.vreplication where id = 2", runningResult(2)) dbclient.addInvariant("insert into _vt.resharding_journal", noResult) - } targetQueries := []string{ @@ -455,8 +454,10 @@ func expectReshardQueries(t *testing.T, tme *testShardMigraterEnv) { dbclient.addInvariant("update _vt.vreplication set message = 'FROZEN'", noResult) dbclient.addInvariant("delete from _vt.vreplication where id in (1)", noResult) dbclient.addInvariant("delete from _vt.copy_state where vrepl_id in (1)", noResult) - } + tme.tmeDB.AddQuery("select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = 1", noResult) + tme.tmeDB.AddQuery("select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = 2", noResult) + } func expectMoveTablesQueries(t *testing.T, tme *testMigraterEnv) { @@ -487,7 +488,6 @@ func expectMoveTablesQueries(t *testing.T, tme *testMigraterEnv) { "int64|varchar|varchar|varchar|varchar"), ""), ) - //select pos, state, message from _vt.vreplication where id=1 } for _, dbclient := range tme.dbSourceClients { @@ -530,4 +530,7 @@ func expectMoveTablesQueries(t *testing.T, tme *testMigraterEnv) { tme.tmeDB.AddQuery("drop table vt_ks2.t1", noResult) tme.tmeDB.AddQuery("drop table vt_ks2.t2", noResult) tme.tmeDB.AddQuery("update _vt.vreplication set message='Picked source tablet: cell:\"cell1\" uid:10 ' where id=1", noResult) + tme.tmeDB.AddQuery("select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = 1", noResult) + tme.tmeDB.AddQuery("select 1 from _vt.copy_state cs, _vt.vreplication vr where vr.id = cs.vrepl_id and vr.id = 2", noResult) + } From 35a41f34e24c7057066170fd55985b1a0c3ac70e Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Wed, 20 Jan 2021 18:07:27 +0100 Subject: [PATCH 064/310] Fix unit test merge issues Signed-off-by: Rohit Nayak --- go/vt/wrangler/workflow_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/wrangler/workflow_test.go b/go/vt/wrangler/workflow_test.go index 63da455d91f..849ffffb890 100644 --- a/go/vt/wrangler/workflow_test.go +++ b/go/vt/wrangler/workflow_test.go @@ -281,13 +281,13 @@ func TestMoveTablesV2Partial(t *testing.T) { wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell1" require.NoError(t, testSwitchForward(t, wf)) - require.Equal(t, "Reads partially switched. Replica switched in cells: cell1. Rdonly not switched. Writes Not Switched", wf.CurrentState()) + require.Equal(t, "Reads partially switched. Replica not switched. Rdonly switched in cells: cell1. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "rdonly" wf.params.Cells = "cell2" require.NoError(t, testSwitchForward(t, wf)) - require.Equal(t, "Reads partially switched. All Replica Reads Switched. Rdonly not switched. Writes Not Switched", wf.CurrentState()) + require.Equal(t, "Reads partially switched. Replica not switched. All Rdonly Reads Switched. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "replica" @@ -304,13 +304,13 @@ func TestMoveTablesV2Partial(t *testing.T) { wf.params.TabletTypes = "replica" wf.params.Cells = "cell1" require.NoError(t, testSwitchForward(t, wf)) - require.Equal(t, "Reads partially switched. Replica not switched. Rdonly switched in cells: cell1. Writes Not Switched", wf.CurrentState()) + require.Equal(t, "Reads partially switched. Replica switched in cells: cell1. Rdonly switched in cells: cell1. Writes Not Switched", wf.CurrentState()) tme.expectNoPreviousJournals() wf.params.TabletTypes = "replica" wf.params.Cells = "cell2" require.NoError(t, testSwitchForward(t, wf)) - require.Equal(t, "Reads partially switched. Replica not switched. All Rdonly Reads Switched. Writes Not Switched", wf.CurrentState()) + require.Equal(t, "All Reads Switched. Writes Not Switched", wf.CurrentState()) } func TestMoveTablesV2Cancel(t *testing.T) { From 422cac3c53dd5e3a1353f1bd595db3627698a27e Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Wed, 20 Jan 2021 19:04:05 +0100 Subject: [PATCH 065/310] Fix e2e test merge issue Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/vreplication_test_env.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index cbfd02f42cc..e618432a7ef 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -41,7 +41,7 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ var dryRunResultsReadCustomerShard = []string{ "Lock keyspace product", - "Switch reads for tables [customer] to keyspace customer for tablet types [REPLICA]", + "Switch reads for tables [customer] to keyspace customer for tablet types [REPLICA,RDONLY]", "Routing rules for tables [customer] will be updated", "Unlock keyspace product", } From 5c2b2574846d095b55a03c3bbb2afd3f1b9038fc Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 21 Jan 2021 21:16:03 +0100 Subject: [PATCH 066/310] Use timeUpdated to determine lag instead of transactionTimestamp. Remove unused column MaxReplicationLag Signed-off-by: Rohit Nayak --- go/vt/wrangler/vexec.go | 13 +++--------- go/vt/wrangler/vexec_plan.go | 4 ++-- go/vt/wrangler/vexec_test.go | 38 +++++++++++++++++------------------- 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/go/vt/wrangler/vexec.go b/go/vt/wrangler/vexec.go index 5c7c9eb1d21..5b7259800a5 100644 --- a/go/vt/wrangler/vexec.go +++ b/go/vt/wrangler/vexec.go @@ -378,8 +378,6 @@ type ReplicationStatus struct { StopPos string // State represents the state column from the _vt.vreplication table. State string - // MaxReplicationLag represents the max_replication_lag column from the _vt.vreplication table. - MaxReplicationLag int64 // DbName represents the db_name column from the _vt.vreplication table. DBName string // TransactionTimestamp represents the transaction_timestamp column from the _vt.vreplication table. @@ -395,7 +393,7 @@ type ReplicationStatus struct { func (wr *Wrangler) getReplicationStatusFromRow(ctx context.Context, row []sqltypes.Value, master *topo.TabletInfo) (*ReplicationStatus, string, error) { var err error - var id, maxReplicationLag, timeUpdated, transactionTimestamp int64 + var id, timeUpdated, transactionTimestamp int64 var state, dbName, pos, stopPos, message string var bls binlogdatapb.BinlogSource id, err = evalengine.ToInt64(row[0]) @@ -407,10 +405,6 @@ func (wr *Wrangler) getReplicationStatusFromRow(ctx context.Context, row []sqlty } pos = row[2].ToString() stopPos = row[3].ToString() - maxReplicationLag, err = evalengine.ToInt64(row[4]) - if err != nil { - return nil, "", err - } state = row[5].ToString() dbName = row[6].ToString() timeUpdated, err = evalengine.ToInt64(row[7]) @@ -431,7 +425,6 @@ func (wr *Wrangler) getReplicationStatusFromRow(ctx context.Context, row []sqlty StopPos: stopPos, State: state, DBName: dbName, - MaxReplicationLag: maxReplicationLag, TransactionTimestamp: transactionTimestamp, TimeUpdated: timeUpdated, Message: message, @@ -477,8 +470,8 @@ func (wr *Wrangler) getStreams(ctx context.Context, workflow, keyspace string) ( sourceShards.Insert(status.Bls.Shard) rsrStatus = append(rsrStatus, status) - transactionTimestamp := time.Unix(status.TransactionTimestamp, 0) - replicationLag := time.Since(transactionTimestamp) + timeUpdated := time.Unix(status.TimeUpdated, 0) + replicationLag := time.Since(timeUpdated) if replicationLag.Seconds() > float64(rsr.MaxVReplicationLag) { rsr.MaxVReplicationLag = int64(replicationLag.Seconds()) } diff --git a/go/vt/wrangler/vexec_plan.go b/go/vt/wrangler/vexec_plan.go index d5958ac2216..4beb5be4fd9 100644 --- a/go/vt/wrangler/vexec_plan.go +++ b/go/vt/wrangler/vexec_plan.go @@ -92,11 +92,11 @@ func (p vreplicationPlanner) dryRun(ctx context.Context) error { p.vx.plannedQuery, p.vx.keyspace, p.vx.workflow) tableString := &strings.Builder{} table := tablewriter.NewWriter(tableString) - table.SetHeader([]string{"Tablet", "ID", "BinLogSource", "State", "DBName", "Current GTID", "MaxReplicationLag"}) + table.SetHeader([]string{"Tablet", "ID", "BinLogSource", "State", "DBName", "Current GTID"}) for _, master := range p.vx.masters { key := fmt.Sprintf("%s/%s", master.Shard, master.AliasString()) for _, stream := range rsr.ShardStatuses[key].MasterReplicationStatuses { - table.Append([]string{key, fmt.Sprintf("%d", stream.ID), stream.Bls.String(), stream.State, stream.DBName, stream.Pos, fmt.Sprintf("%d", stream.MaxReplicationLag)}) + table.Append([]string{key, fmt.Sprintf("%d", stream.ID), stream.Bls.String(), stream.State, stream.DBName, stream.Pos}) } } table.SetAutoMergeCellsByColumnIndex([]int{0}) diff --git a/go/vt/wrangler/vexec_test.go b/go/vt/wrangler/vexec_test.go index cb8db52661b..c4d64b4a536 100644 --- a/go/vt/wrangler/vexec_test.go +++ b/go/vt/wrangler/vexec_test.go @@ -149,15 +149,15 @@ func TestVExec(t *testing.T) { dryRunResults := []string{ "Query: delete from _vt.vreplication where db_name = 'vt_target' and workflow = 'wrWorkflow'", "will be run on the following streams in keyspace target for workflow wrWorkflow:\n\n", - "+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+", - "| TABLET | ID | BINLOGSOURCE | STATE | DBNAME | CURRENT GTID | MAXREPLICATIONLAG |", - "+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+", - "| -80/zone1-0000000200 | 1 | keyspace:\"source\" shard:\"0\" | Copying | vt_target | pos | 0 |", - "| | | filter: > | | | | |", - "+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+", - "| 80-/zone1-0000000210 | 1 | keyspace:\"source\" shard:\"0\" | Copying | vt_target | pos | 0 |", - "| | | filter: > | | | | |", - "+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+", + "+----------------------+----+--------------------------------+---------+-----------+--------------+", + "| TABLET | ID | BINLOGSOURCE | STATE | DBNAME | CURRENT GTID |", + "+----------------------+----+--------------------------------+---------+-----------+--------------+", + "| -80/zone1-0000000200 | 1 | keyspace:\"source\" shard:\"0\" | Copying | vt_target | pos |", + "| | | filter: > | | | |", + "+----------------------+----+--------------------------------+---------+-----------+--------------+", + "| 80-/zone1-0000000210 | 1 | keyspace:\"source\" shard:\"0\" | Copying | vt_target | pos |", + "| | | filter: > | | | |", + "+----------------------+----+--------------------------------+---------+-----------+--------------+", } require.Equal(t, strings.Join(dryRunResults, "\n")+"\n\n\n\n\n", logger.String()) } @@ -227,7 +227,6 @@ func TestWorkflowListStreams(t *testing.T) { "Pos": "pos", "StopPos": "", "State": "Copying", - "MaxReplicationLag": 0, "DBName": "vt_target", "TransactionTimestamp": 0, "TimeUpdated": 1234, @@ -263,7 +262,6 @@ func TestWorkflowListStreams(t *testing.T) { "Pos": "pos", "StopPos": "", "State": "Copying", - "MaxReplicationLag": 0, "DBName": "vt_target", "TransactionTimestamp": 0, "TimeUpdated": 1234, @@ -310,15 +308,15 @@ func TestWorkflowListStreams(t *testing.T) { will be run on the following streams in keyspace target for workflow wrWorkflow: -+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+ -| TABLET | ID | BINLOGSOURCE | STATE | DBNAME | CURRENT GTID | MAXREPLICATIONLAG | -+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+ -| -80/zone1-0000000200 | 1 | keyspace:"source" shard:"0" | Copying | vt_target | pos | 0 | -| | | filter: > | | | | | -+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+ -| 80-/zone1-0000000210 | 1 | keyspace:"source" shard:"0" | Copying | vt_target | pos | 0 | -| | | filter: > | | | | | -+----------------------+----+--------------------------------+---------+-----------+--------------+-------------------+ ++----------------------+----+--------------------------------+---------+-----------+--------------+ +| TABLET | ID | BINLOGSOURCE | STATE | DBNAME | CURRENT GTID | ++----------------------+----+--------------------------------+---------+-----------+--------------+ +| -80/zone1-0000000200 | 1 | keyspace:"source" shard:"0" | Copying | vt_target | pos | +| | | filter: > | | | | ++----------------------+----+--------------------------------+---------+-----------+--------------+ +| 80-/zone1-0000000210 | 1 | keyspace:"source" shard:"0" | Copying | vt_target | pos | +| | | filter: > | | | | ++----------------------+----+--------------------------------+---------+-----------+--------------+ From 67b380e1faa9c1912b36f14eaba55d890a488d18 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 21 Jan 2021 22:24:17 +0100 Subject: [PATCH 067/310] update tests for max lag Signed-off-by: Rohit Nayak --- go/vt/wrangler/vexec_test.go | 12 ++++++++---- go/vt/wrangler/wrangler_env_test.go | 7 +++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/go/vt/wrangler/vexec_test.go b/go/vt/wrangler/vexec_test.go index c4d64b4a536..1ed3ccdc1d1 100644 --- a/go/vt/wrangler/vexec_test.go +++ b/go/vt/wrangler/vexec_test.go @@ -37,7 +37,7 @@ func TestVExec(t *testing.T) { workflow := "wrWorkflow" keyspace := "target" query := "update _vt.vreplication set state = 'Running'" - env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil) + env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil, time.Now().Unix()) defer env.close() var logger = logutil.NewMemoryLogger() wr := New(logger, env.topoServ, env.tmc) @@ -74,6 +74,10 @@ func TestVExec(t *testing.T) { vx.plannedQuery = plan.parsedQuery.Query vx.exec() + res, err := wr.getStreams(ctx, workflow, keyspace) + require.NoError(t, err) + require.Less(t, res.MaxVReplicationLag, int64(3 /*seconds*/)) // lag should be very small + type TestCase struct { name string query string @@ -174,7 +178,7 @@ func TestWorkflowListStreams(t *testing.T) { ctx := context.Background() workflow := "wrWorkflow" keyspace := "target" - env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil) + env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil, 1234) defer env.close() logger := logutil.NewMemoryLogger() wr := New(logger, env.topoServ, env.tmc) @@ -329,7 +333,7 @@ func TestWorkflowListAll(t *testing.T) { ctx := context.Background() keyspace := "target" workflow := "wrWorkflow" - env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil) + env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil, 0) defer env.close() logger := logutil.NewMemoryLogger() wr := New(logger, env.topoServ, env.tmc) @@ -348,7 +352,7 @@ func TestVExecValidations(t *testing.T) { workflow := "wf" keyspace := "ks" query := "" - env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil) + env := newWranglerTestEnv([]string{"0"}, []string{"-80", "80-"}, "", nil, 0) defer env.close() wr := New(logutil.NewConsoleLogger(), env.topoServ, env.tmc) diff --git a/go/vt/wrangler/wrangler_env_test.go b/go/vt/wrangler/wrangler_env_test.go index fd5fb24f776..14cbfaf7b8c 100644 --- a/go/vt/wrangler/wrangler_env_test.go +++ b/go/vt/wrangler/wrangler_env_test.go @@ -17,12 +17,11 @@ limitations under the License. package wrangler import ( + "context" "flag" "fmt" "sync" - "context" - "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/log" @@ -76,7 +75,7 @@ func init() { //---------------------------------------------- // testWranglerEnv -func newWranglerTestEnv(sourceShards, targetShards []string, query string, positions map[string]string) *testWranglerEnv { +func newWranglerTestEnv(sourceShards, targetShards []string, query string, positions map[string]string, timeUpdated int64) *testWranglerEnv { flag.Set("tablet_protocol", "WranglerTest") env := &testWranglerEnv{ workflow: "wrWorkflow", @@ -147,7 +146,7 @@ func newWranglerTestEnv(sourceShards, targetShards []string, query string, posit result := sqltypes.MakeTestResult(sqltypes.MakeTestFields( "id|source|pos|stop_pos|max_replication_lag|state|db_name|time_updated|transaction_timestamp|message", "int64|varchar|varchar|varchar|int64|varchar|varchar|int64|int64|varchar"), - fmt.Sprintf("1|%v|pos||0|Running|vt_target|1234|0|", bls), + fmt.Sprintf("1|%v|pos||0|Running|vt_target|%d|0|", bls, timeUpdated), ) env.tmc.setVRResults(master.tablet, "select id, source, pos, stop_pos, max_replication_lag, state, db_name, time_updated, transaction_timestamp, message from _vt.vreplication where db_name = 'vt_target' and workflow = 'wrWorkflow'", result) env.tmc.setVRResults( From 5b780feb8e05117766682f6d802ca22e0d842083 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 23 Jan 2021 13:05:28 -0800 Subject: [PATCH 068/310] examples/operator: fix tags Signed-off-by: Sugu Sougoumarane --- examples/operator/101_initial_cluster.yaml | 10 +++++----- examples/operator/201_customer_tablets.yaml | 10 +++++----- examples/operator/302_new_shards.yaml | 10 +++++----- examples/operator/306_down_shard_0.yaml | 10 +++++----- .../operator/{orc_cluster.yaml => vtorc_example.yaml} | 0 5 files changed, 20 insertions(+), 20 deletions(-) rename examples/operator/{orc_cluster.yaml => vtorc_example.yaml} (100%) diff --git a/examples/operator/101_initial_cluster.yaml b/examples/operator/101_initial_cluster.yaml index dd28b66fe3f..8df5c19c8e1 100644 --- a/examples/operator/101_initial_cluster.yaml +++ b/examples/operator/101_initial_cluster.yaml @@ -8,12 +8,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:v8.0.0 - vtgate: vitess/lite:v8.0.0 - vttablet: vitess/lite:v8.0.0 - vtbackup: vitess/lite:v8.0.0 + vtctld: vitess/lite:latest + vtgate: vitess/lite:latest + vttablet: vitess/lite:latest + vtbackup: vitess/lite:latest mysqld: - mysql56Compatible: vitess/lite:v6.0.20-20200429 + mysql56Compatible: vitess/lite:latest mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/201_customer_tablets.yaml b/examples/operator/201_customer_tablets.yaml index 87aff91e050..44938131139 100644 --- a/examples/operator/201_customer_tablets.yaml +++ b/examples/operator/201_customer_tablets.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:v8.0.0 - vtgate: vitess/lite:v8.0.0 - vttablet: vitess/lite:v8.0.0 - vtbackup: vitess/lite:v8.0.0 + vtctld: vitess/lite:latest + vtgate: vitess/lite:latest + vttablet: vitess/lite:latest + vtbackup: vitess/lite:latest mysqld: - mysql56Compatible: vitess/lite:v6.0.20-20200429 + mysql56Compatible: vitess/lite:latest mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/302_new_shards.yaml b/examples/operator/302_new_shards.yaml index 1647da4a9b2..2ea942bfdb4 100644 --- a/examples/operator/302_new_shards.yaml +++ b/examples/operator/302_new_shards.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:v8.0.0 - vtgate: vitess/lite:v8.0.0 - vttablet: vitess/lite:v8.0.0 - vtbackup: vitess/lite:v8.0.0 + vtctld: vitess/lite:latest + vtgate: vitess/lite:latest + vttablet: vitess/lite:latest + vtbackup: vitess/lite:latest mysqld: - mysql56Compatible: vitess/lite:v8.0.0 + mysql56Compatible: vitess/lite:latest mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/306_down_shard_0.yaml b/examples/operator/306_down_shard_0.yaml index 2629b57fa06..4f0fc6dee60 100644 --- a/examples/operator/306_down_shard_0.yaml +++ b/examples/operator/306_down_shard_0.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:v8.0.0 - vtgate: vitess/lite:v8.0.0 - vttablet: vitess/lite:v8.0.0 - vtbackup: vitess/lite:v8.0.0 + vtctld: vitess/lite:latest + vtgate: vitess/lite:latest + vttablet: vitess/lite:latest + vtbackup: vitess/lite:latest mysqld: - mysql56Compatible: us.gcr.io/planetscale-vitess/lite:2020-04-24.228e6fe + mysql56Compatible: us.gcr.io/planetscale-vitess/lite:latest mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/orc_cluster.yaml b/examples/operator/vtorc_example.yaml similarity index 100% rename from examples/operator/orc_cluster.yaml rename to examples/operator/vtorc_example.yaml From 1bb983d11e58cbb120ce881f6627ce65f5cd6786 Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Tue, 6 Oct 2020 21:24:08 -0700 Subject: [PATCH 069/310] examples/operator: add vtorc support Signed-off-by: Sugu Sougoumarane --- examples/operator/operator.yaml | 2 +- examples/operator/orcpf.sh | 2 +- examples/operator/vtorc_example.yaml | 36 +++++++++++++--------------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/examples/operator/operator.yaml b/examples/operator/operator.yaml index 3bb6f6c4d31..0549856ee01 100644 --- a/examples/operator/operator.yaml +++ b/examples/operator/operator.yaml @@ -5773,7 +5773,7 @@ spec: fieldPath: metadata.name - name: OPERATOR_NAME value: vitess-operator - image: planetscale/vitess-operator:v2.2.0 + image: planetscale/vitess-operator:latest imagePullPolicy: IfNotPresent name: vitess-operator resources: diff --git a/examples/operator/orcpf.sh b/examples/operator/orcpf.sh index 692cab3e74e..dc4438e0137 100755 --- a/examples/operator/orcpf.sh +++ b/examples/operator/orcpf.sh @@ -4,7 +4,7 @@ kubectl port-forward --address localhost "$(kubectl get service --selector="plan process_id1=$! kubectl port-forward --address localhost "$(kubectl get service --selector="planetscale.com/component=vtgate,!planetscale.com/cell" -o name | head -n1)" 15306:3306 & process_id2=$! -kubectl port-forward --address localhost "$(kubectl get service --selector="planetscale.com/component=orchestrator" -o name | head -n1)" 3000 & +kubectl port-forward --address localhost "$(kubectl get pod --selector="planetscale.com/component=vtorc" -o name | head -n1)" 3000 & process_id3=$! sleep 2 echo "You may point your browser to http://localhost:15000 for vtctld, http://localhost:3000 for orchestrator, and use the following aliases as shortcuts:" diff --git a/examples/operator/vtorc_example.yaml b/examples/operator/vtorc_example.yaml index 1cff45c99d2..ccaa74bc295 100644 --- a/examples/operator/vtorc_example.yaml +++ b/examples/operator/vtorc_example.yaml @@ -8,13 +8,13 @@ metadata: name: example spec: images: - vtctld: vitess/orctest:v1 - orchestrator: vitess/orctest:v1 - vtgate: vitess/orctest:v1 - vttablet: vitess/orctest:v1 - vtbackup: vitess/orctest:v1 + vtctld: vitess/lite:latest + vtorc: vitess/lite:latest + vtgate: vitess/lite:latest + vttablet: vitess/lite:latest + vtbackup: vitess/lite:latest mysqld: - mysql56Compatible: vitess/lite:v6.0.20-20200429 + mysql56Compatible: vitess/lite:latest mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 @@ -43,23 +43,20 @@ spec: requests: cpu: 100m memory: 128Mi - vitessOrchestrator: - cells: - - zone1 - configSecret: - name: example-cluster-config - key: orc_config.json - replicas: 1 - resources: - limits: - memory: 128Mi - requests: - cpu: 100m - memory: 128Mi keyspaces: - name: commerce turndownPolicy: Immediate + vitessOrchestrator: + configSecret: + name: example-cluster-config + key: orc_config.json + resources: + limits: + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi partitionings: - equal: parts: 1 @@ -77,6 +74,7 @@ spec: extraFlags: db_charset: utf8mb4 disable_active_reparents: "true" + enable_semi_sync: "false" resources: requests: cpu: 100m From 91fa15fbe38c731f5328b0086ac0f32a5ea42e4b Mon Sep 17 00:00:00 2001 From: Sugu Sougoumarane Date: Sat, 23 Jan 2021 13:36:37 -0800 Subject: [PATCH 070/310] examples/operator: fix tags Signed-off-by: Sugu Sougoumarane --- examples/operator/101_initial_cluster.yaml | 10 +++++----- examples/operator/201_customer_tablets.yaml | 10 +++++----- examples/operator/302_new_shards.yaml | 10 +++++----- examples/operator/306_down_shard_0.yaml | 10 +++++----- examples/operator/operator.yaml | 2 +- examples/operator/vtorc_example.yaml | 12 ++++++------ 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/examples/operator/101_initial_cluster.yaml b/examples/operator/101_initial_cluster.yaml index 8df5c19c8e1..2fe2b020de9 100644 --- a/examples/operator/101_initial_cluster.yaml +++ b/examples/operator/101_initial_cluster.yaml @@ -8,12 +8,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v9.0.0 + vtgate: vitess/lite:v9.0.0 + vttablet: vitess/lite:v9.0.0 + vtbackup: vitess/lite:v9.0.0 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v9.0.0 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/201_customer_tablets.yaml b/examples/operator/201_customer_tablets.yaml index 44938131139..81ec63e8e78 100644 --- a/examples/operator/201_customer_tablets.yaml +++ b/examples/operator/201_customer_tablets.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v9.0.0 + vtgate: vitess/lite:v9.0.0 + vttablet: vitess/lite:v9.0.0 + vtbackup: vitess/lite:v9.0.0 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v9.0.0 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/302_new_shards.yaml b/examples/operator/302_new_shards.yaml index 2ea942bfdb4..d02c2e41a25 100644 --- a/examples/operator/302_new_shards.yaml +++ b/examples/operator/302_new_shards.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v9.0.0 + vtgate: vitess/lite:v9.0.0 + vttablet: vitess/lite:v9.0.0 + vtbackup: vitess/lite:v9.0.0 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v9.0.0 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/306_down_shard_0.yaml b/examples/operator/306_down_shard_0.yaml index 4f0fc6dee60..28a4d71d160 100644 --- a/examples/operator/306_down_shard_0.yaml +++ b/examples/operator/306_down_shard_0.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v9.0.0 + vtgate: vitess/lite:v9.0.0 + vttablet: vitess/lite:v9.0.0 + vtbackup: vitess/lite:v9.0.0 mysqld: - mysql56Compatible: us.gcr.io/planetscale-vitess/lite:latest + mysql56Compatible: vitess/lite:v9.0.0 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/operator.yaml b/examples/operator/operator.yaml index 0549856ee01..916102603c6 100644 --- a/examples/operator/operator.yaml +++ b/examples/operator/operator.yaml @@ -5773,7 +5773,7 @@ spec: fieldPath: metadata.name - name: OPERATOR_NAME value: vitess-operator - image: planetscale/vitess-operator:latest + image: planetscale/vitess-operator:v2.3.0 imagePullPolicy: IfNotPresent name: vitess-operator resources: diff --git a/examples/operator/vtorc_example.yaml b/examples/operator/vtorc_example.yaml index ccaa74bc295..63d01861267 100644 --- a/examples/operator/vtorc_example.yaml +++ b/examples/operator/vtorc_example.yaml @@ -8,13 +8,13 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtorc: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v9.0.0 + vtorc: vitess/lite:v9.0.0 + vtgate: vitess/lite:v9.0.0 + vttablet: vitess/lite:v9.0.0 + vtbackup: vitess/lite:v9.0.0 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v9.0.0 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 From 138bc89d52c9aa87ad66eafb480209f485cd0d1a Mon Sep 17 00:00:00 2001 From: Jordan Moldow Date: Sat, 23 Jan 2021 15:44:03 -0800 Subject: [PATCH 071/310] vtctl: Add missing err checks for VReplication v2 Return error immediately if the target keyspace is unknown. Do the same for the source keyspace. Currently, the code will attempt to continue with a bad keyspace name. Signed-off-by: Jordan Moldow --- go/vt/vtctl/vtctl.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 05f7a10e8b5..28e7ee221d2 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2002,6 +2002,7 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla _, err = wr.TopoServer().GetKeyspace(ctx, target) if err != nil { wr.Logger().Errorf("keyspace %s not found", target) + return err } vrwp := &wrangler.VReplicationWorkflowParams{ @@ -2058,6 +2059,11 @@ func commandVRWorkflow(ctx context.Context, wr *wrangler.Wrangler, subFlags *fla if *sourceKeyspace == "" { return fmt.Errorf("source keyspace is not specified") } + _, err := wr.TopoServer().GetKeyspace(ctx, *sourceKeyspace) + if err != nil { + wr.Logger().Errorf("keyspace %s not found", *sourceKeyspace) + return err + } if !*allTables && *tables == "" { return fmt.Errorf("no tables specified to move") } From 632a72ae705ed52ee5de74ff3903d9fda448fd61 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 25 Jan 2021 12:36:01 +0530 Subject: [PATCH 072/310] Updated java version to 9.0 for release Signed-off-by: Harshit Gangal --- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/client/pom.xml b/java/client/pom.xml index df8953a3f7d..ca4cac809b7 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0-SNAPSHOT + 9.0.0 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index 803073c9eed..d691745622e 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0-SNAPSHOT + 9.0.0 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 8903e036b46..9209c9f480b 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0-SNAPSHOT + 9.0.0 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 51eeec69ea8..8fbede6e6b4 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0-SNAPSHOT + 9.0.0 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 14ac3c512ce..4b469b9efbf 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 9.0.0-SNAPSHOT + 9.0.0 pom Vitess Java Client libraries [Parent] From dd85b607d7a44ff90977d7941bb0f50158ecf0c9 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 26 Jan 2021 14:59:17 +0300 Subject: [PATCH 073/310] 9.0.0 Release Notes Signed-off-by: Alkin Tezuysal --- doc/releasenotes/9_0_0_release_notes.md | 245 ++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 doc/releasenotes/9_0_0_release_notes.md diff --git a/doc/releasenotes/9_0_0_release_notes.md b/doc/releasenotes/9_0_0_release_notes.md new file mode 100644 index 00000000000..7d8b5f99e24 --- /dev/null +++ b/doc/releasenotes/9_0_0_release_notes.md @@ -0,0 +1,245 @@ +This release complies with VEP-3 which removes the upgrade order requirement. Components can be upgraded in any order. It is recommended that the upgrade order should still be followed if possible, except to canary test the new version of VTGate before upgrading the rest of the components. + +## Incompatible Changes + +The following PRs made changes to behaviors that clients might rely on. They should be reviewed carefully so that client code can be changed in concert with a Vitess release deployment. +* The update to golang 1.15 (#7204) might break systems that use TLS certificates with a common name. A fix is documented here (https://github.com/golang/go/issues/40748#issuecomment-673612108) + +Vitess 9.0 is not compatible with the previous release of the Vitess Kubernetes Operator (2.2.0). A new version of the Operator (2.3.0) is available that is compatible. + +## Bugs Fixed + +### VTGate / MySQL compatibility +* Set Global #6957 +* Set udv allow more expressions #6964 +* Bug which caused the connection to not close in case of error writing an error packet #6977 +* Bug fix #7048 for SelectNone in StreamExecute route engine #7050 + +### Other +* Binary PK: fix bug where padding of binary columns was being done incorrectly #6963 +* Pad non-fractional part of DECIMAL type #6967 +* Bug fix regression in /healthz #7090 +* Fix metadata related operation hangs when zk down #7228 +* Fix accidentally-broken legacy vtctl output format #7285 + +## Functionality Added or Changed + +### VTGate / MySQL compatibility + +* VTGate: Allow INSERT with all defaults #6969 +* VTGate: Allow YEAR column type with length specified #6975 +* VTGate: Retry Execute when reserved connection is lost #6983 +* VTGate: Use ephemeral buffer when reading rows #6990 +* VTGate: Allow time_zone in reserved connection #6998 +* VTGate: Improved support for UNION #7007 +* VTGate: Add DDL parser support for FULLTEXT indexes. #7001 +* VTGate: Extend comparability of EvalResult to support hash codes #7016 +* VTGate: Use proto equal method #7017 +* VTGate: Fix COM_STMT_EXECUTE packet decode #7020 +* VTGate: Adds Planning and Parsing Support for Create Index of MySQL 5.7 #7024 +* VTGate: UNION DISTINCT support on vtgate #7029 +* VTGate: Improve database ddl plan #7034 +* VTGate: Support for hex & shard in vindex query #7044 +* VTGate: Use distinct primitive to solve more queries #7047 +* VTGate: Route using vindex for composite IN clause #7049 +* VTGate: Optimise struct field layout #7052 +* VTGate: Refactoring of plan building #7054 +* VTGate: Rewrite joins written with the USING construct #6660 +* VTGate: Add option to GetSchema to only send the row count and data length over the wire +#6985 +* VTGate: Adds Planning and Parsing Support for Create Database of MySQL 5.7 #7068 +* VTGate: Make sure to check all GROUP BY columns #7080 +* VTGate: Separate sub-query and derived table into different structs #7081 +* VTGate: Adds Planning and Parsing Support for Alter Database of MySQL 5.7 #7086 +* VTGate: Convert usages of DDL struct to DDLStatement interface #7096 +* VTGate: Adds Planning and Parsing Support for Drop Database of MySQL 5.7 #7098 +* VTGate: Restore SHOW SCHEMAS support; fixes #7100 #7102 +* VTGate: Refactor Code to create a separate struct for CREATE TABLE #7116 +* VTGate: Allows for vttestserver and vtcombo to respond to VtGateExecute. #7121 +* VTGate: Support for lock and unlock tables #7139 +* VTGate: Merge SelectDBA routes when possible #7140 +* VTGate: Adds support for all the rails queries using information_schema #7143 +* VTGate: Add support for unary expression in order by column #7163 +* VTGate: Skip query rewriting for dual table #7164 +* VTGate: Refactor Code to create a separate struct for ALTER VSCHEMA #7173 +* VTGate: Refactor Show plans #7185 +* VTGate: Show privilege support #7194 +* VTGate: Planning and Parsing Support for Drop Table, Drop View and Alter View #7178 +* VTGate: Cache only dml and select plans #7196 +* VTGate: Planning and Parsing Support for Alter Table #7199 +* VTGate: Add FindAllShardsInKeyspace to vtctldserver #7201 +* VTGate: improve-log: FAILED_PRECONDITION #7215 +* VTGate: Planner refactoring #7103 +* VTGate: Migrate `vtctlclient InitShardMaster` => `vtctldclient InitShardPrimary` #7220 +* VTGate: Add Planning and Parsing Support for Truncate, Rename, Drop Index and Flush #7242 +* VTGate: Fix create table format function to include if not exists #7250 +* VTGate: Added default databases when calling 'show databases' #7256 +* VTGate : Add Update.AddWhere to mirror Select.AddWhere #7277 +* VTGate :Rremoved resolver usage from StreamExecute #7281 +* VTGate: Adding a MySQL connection at Vtgate to run queries on it directly in case of testing mode #7291 +* VTGate: Added vitess_version as variable #7295 +* VTGate: Default to false for system settings to be changed per session at the database connection level #7299 +* VTGate: Gen4: Add Limit clause support #7312 +* VTGate: Gen4: Handling subquery in query graph #7313 +* VTGate: Addition of @@enable_system_settings #7300 +* VTGate: Route INFORMATION_SCHEMA queries #6932 +* VTGate: Adds Planning and Parsing Support for Create Index of MySQL 5.7 #7024 +* VTGate: Log sql which exceeds max memory rows #7055 +* VTExplain: Add sequence table support for vtexplain #7186 +* VSchema: Support back-quoted names #7073 +* Healthcheck: healthy list should be recomputed when a tablet is removed #7176 + +### Set Statement Support + +Set statement support has been added in Vitess. There are [some system variables](https://github.com/vitessio/vitess/blob/master/go/vt/sysvars/sysvars.go#L147,L190) which are disabled by default and can be enabled using flag `-enable_system_settings` on VTGate. These system variables are set on the mysql server. Because they change the mysql session, using them leads to the Vitess connection no longer using the connection pool and forcing dedicated connections. + + +### VReplication + +* VReplication: refactored and enhanced support for JSON columns #6829 +* VReplication: Don't update tx timestamp on heartbeat #6930 +* VReplication E2E Tests: Refactored tests for readability and attempting to fix flakiness #6991 +* VRepl/Tablet Picker: improve observability of selected tablet #6999 +* VReplication: Handle comment statement type in vstreamer #7092 +* VReplication e2e: Fine tuned test to reduce flakiness and added more logging to debug future flakiness #7138 +* VReplication: Make relay log size & rows configurable. #6992 +* VReplication: New workflows cli UX. Allow reads/writes to be switched independently #7071 +* VReplication: DropSources: change table rename logic #7230 +* VReplication: MoveTables: delete routing rules and update vschema on Complete and Abort #7234 +* VReplication: V2 Workflow Start: wait for streams to start and report errors if any while starting a workflow #7248 +* VReplication: Ignore temp tables created by onlineddl #7159 +* VReplication V2 Workflows: rename Abort to Cancel #7276 +* VReplication DryRun: Report current dry run results for v2 commands #7255 +* VReplication: Miscellaneous improvements #7275 +* VReplication: Tablet throttle support "/throttle/check-self" available on all tablets #7319 +* VStreamer Events: remove preceding zeroes from decimals in Row Events #7297 +* Workflow Show: use timeUpdated to calculate vreplication lag #7342 +* vtctl: Add missing err checks for VReplication v2 #7361 +* VStreamer Field Event: add allowed values for set/enum #6981 +* VDiff: lock keyspace while snapshoting, restart target in case of errors #7012 +* [vtctld]: fix error state in Workflow Show #6970 +* [vtctld] Workflow command: minor fixes #7008 +* [vtctl] Add missing err checks for VReplication v2 #7361 + +### VTTablet + +* VTTablet: fast and reliable state transitions #7011 +* VTTablet: don't shutdown on too many connections #7039 +* VTTablet: debug/env page to change variables in real-time #7189 +* VTTablet: Adds better errors when there are timeouts in resource pools #7002 +* VTTablet: Return to re-using server IDs for binlog connections #6941 +* VTTablet: Correctly initialize the TabletType stats #6989 +* Backup: Use provided xtrabackup_root_path to find xbstream #7359 +* Backup: Use pargzip instead of pgzip for compression. #7037 +* Backup: Add s3 server-side encryption and decryption with customer provided key #7088 + +### OnlineDDL + +* Online DDL: follow ups in multiple trajectories #6901 +* Online DDL: cancel running migrations executed by another tablet #7006 +* OnlineDDL: Adding `ddl_strategy` session variable #7042 +* Online DDL: ddl_strategy session variable and vtctl command line argument #7045 +* Online DDL: Removing online ddl query hint from ALTER TABLE #7069 +* Online DDL: vtgate -ddl-strategy flag renamed to -ddl_strategy #7074 +Automatically retry migration that was interrupted during master failover +Automatically terminate migrations run by a failed tablet +* Online DDL:request_context/migration_context #7082 +* Online DDL: Support CREATE, DROP statements in ApplySchema and online DDL #7083 +* Online DDL: ddl_type column #7097 +* OnlineDDL: "cancel-all" command to cancel all pending migrations in keyspace #7099 +* OnlineDDL: Support `vtctl OnlineDDL show ` #7145 +* OnlineDDL: Normalizing Online-DDL queries #7153 +* Online DDL: ddl_strategy=direct #7172 +* Online DDL: Executor database pool size increase #7206 +* Online DDL: DROP TABLE translated to RENAME TABLE statement #7221 +* Online DDL: Adding @@session_uuid to vtgate; used as 'context' #7263 +* Online DDL: ignore errors if extracted gh-ost binary is identical to installed binary #6928 +* Online DDL: Table lifecycle: skip time hint for unspecified states #7151 + + +### VTadmin + +* VTadmin: Initial vtadmin-api, clusters, and service discovery #7187 +* VTadmin: The tiniest possible first implementation of vtadmin-web #7218 +* VTadmin: Add cluster protos to discovery and vtsql package constructors #7224 +* VTadmin: Add static file service discovery implementation #7229 +* VTadmin: Query vtadmin-api from vtadmin-web with fetch + react-query #7239 +* VTadmin: Add vtctld proxy to vtadmin API, add GetKeyspaces endpoint #7266 +* VTadmin: [vtctld] Expose vtctld gRPC port in local Docker example + update VTAdmin README #7306 +* VTadmin: Add CSS variables + fonts to VTAdmin #7309 +* VTadmin: Add React Router + a skeleton /debug page to VTAdmin #7310 +* VTadmin: Add NavRail component #7316 +* VTadmin: Add Button + Icon components #7350 +* [vtctld]: vtctldclient generator #7238 +* [vtctld] Migrate cell getters #7302 +* [vtctld] Migrate tablet getters #7311 +* [vtctld] Migrate GetSchema #7346 +* [vtctld] vtctldclient command pkg #7321 +* [vtctld] Add GetSrvVSchema command #7334 +* [vtctld] Migrate ListBackups as GetBackups in new vtctld server #7352 + Merged +* [vtctld] Migrate GetVSchema to VtctldServer #7360 + +### Other + +* Fix comment typo #6974 +* Fix all occurrences of `fmt.Sprint(x)` where x is `int` #7244 +* Fix incorrect comments #7257 +* Fix comment for IDPool #7212 +* IsInternalOperationTableName: see if a table is used internally by vitess #7104 + +## Examples / Tutorials + +* Update demo #7205 +* Delete select_commerce_data.sql #7245 +* Docker/vttestserver: Add MYSQL_BIND_HOST env #7293 +* Examples/operator: fix tags and add vtorc example #7358 +* local docker: copy examples/common into /vt/common to match MoveTables user guide #7252 +* Update docker-compose examples to take advantage of improvements in Vitess #7009 + +## Documentation + +* Vitess Slack Guidelines v1.0 #6961 +* Do vschema_customer_sharded.json before create_customer_sharded.sql #7210 +* Added readme for the demo example #7226 +* Pull Request template: link to contribution guide #7314 + +## Build Environment Changes + +* Clean up plan building test cases #7057 +* Fix unit test error #6953, #6993 +* Fixing the 5.6 builds of vitess/lite #6960 +* Pin mariadb to use mariadb-server-10.2 #6966 +* Replace vitess:base with vitess:lite images for docker-compose services #7004 +* Fix flakey TestParallelRunnerApprovalFirstRunningSecondRunning test #7014 +* Allow custom image tags in compose #7043 +* Support statsd for vitess #7072 +* Add vtctl to make install-local #7125 +* Updating Java unit tests for JDK9+ compatibility #7144 +* Add Go Version to Bootstrap Image #7182 +* Update Vitess v8.0 images #7174 +* Fix broken package ref in UBI docker build #7183 +* Convert CentOS extra packages installation to yum instead of downloading #7188 +* Make docker_local: fix missing mysql_server package #7213 +* Add unit test case to improve test coverage for go/sqltypes/result.go #7227 +* Update Golang to 1.15 #7204 +* Add linter configuration #7247 +* Tracking failed check runs #7026 +* Github Actions CI Builds: convert matrix strategy for unit and cluster tests to individual tests #7258 +* Add Update.AddWhere to mirror Select.AddWhere #7277 +* Descriptive names for CI checks #7289 +* Testing upgrade path from / downgrade path to v8.0.0 #7294 +* Add mysqlctl to docker images #7326 + +## Functionality Neutral Changes + +* Healthcheck: add unit test for multi-cell replica configurations #6978 +* Adds timeout to checking for tablets. #7106 +* Remove deprecated vtctl commands, flags and vttablet rpcs #7115 +* Fixes comment to mention the existence of reference tables. #7122 +* Updated pull request template to add more clarity #7193 +* Redact password #7198 +* action_repository: no need for http.Request #7124 +* Testing version upgrade/downgrade path from/to 8.0 #7323 +* Use `context` from Go's standard library #7235 + From 0533e30ca775e90c5e8d968b106ddc3ca98e717d Mon Sep 17 00:00:00 2001 From: David Weitzman Date: Mon, 2 Nov 2020 17:41:57 -0800 Subject: [PATCH 074/310] Correctly initialize the TabletType stats Fixes https://github.com/vitessio/vitess/issues/6988 Signed-off-by: David Weitzman --- go/vt/vttablet/tabletmanager/tm_init.go | 1 + go/vt/vttablet/tabletmanager/tm_init_test.go | 3 +++ go/vt/vttablet/tabletmanager/tm_state_test.go | 2 ++ 3 files changed, 6 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 8c88333bc4d..787bc7ff823 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -631,6 +631,7 @@ func (tm *TabletManager) exportStats() { tablet := tm.Tablet() statsKeyspace.Set(tablet.Keyspace) statsShard.Set(tablet.Shard) + statsTabletType.Set(topoproto.TabletTypeLString(tm.tmState.tablet.Type)) if key.KeyRangeIsPartial(tablet.KeyRange) { statsKeyRangeStart.Set(hex.EncodeToString(tablet.KeyRange.Start)) statsKeyRangeEnd.Set(hex.EncodeToString(tablet.KeyRange.End)) diff --git a/go/vt/vttablet/tabletmanager/tm_init_test.go b/go/vt/vttablet/tabletmanager/tm_init_test.go index 4ff49654c34..4accc2fd25f 100644 --- a/go/vt/vttablet/tabletmanager/tm_init_test.go +++ b/go/vt/vttablet/tabletmanager/tm_init_test.go @@ -124,6 +124,8 @@ func TestStartCreateKeyspaceShard(t *testing.T) { tm := newTestTM(t, ts, 1, "ks", "0") defer tm.Stop() + assert.Equal(t, "replica", statsTabletType.Get()) + _, err := ts.GetShard(ctx, "ks", "0") require.NoError(t, err) @@ -235,6 +237,7 @@ func TestCheckMastership(t *testing.T) { assert.Equal(t, topodatapb.TabletType_MASTER, ti.Type) ter0 := ti.GetMasterTermStartTime() assert.Equal(t, now, ter0) + assert.Equal(t, "master", statsTabletType.Get()) tm.Stop() // 3. Delete the tablet record. The shard record still says that we are the diff --git a/go/vt/vttablet/tabletmanager/tm_state_test.go b/go/vt/vttablet/tabletmanager/tm_state_test.go index 4de8c87d557..cc72c7d8e46 100644 --- a/go/vt/vttablet/tabletmanager/tm_state_test.go +++ b/go/vt/vttablet/tabletmanager/tm_state_test.go @@ -182,6 +182,7 @@ func TestStateChangeTabletType(t *testing.T) { require.NoError(t, err) assert.Equal(t, topodatapb.TabletType_MASTER, ti.Type) assert.NotNil(t, ti.MasterTermStartTime) + assert.Equal(t, "master", statsTabletType.Get()) err = tm.tmState.ChangeTabletType(ctx, topodatapb.TabletType_REPLICA, DBActionNone) require.NoError(t, err) @@ -189,6 +190,7 @@ func TestStateChangeTabletType(t *testing.T) { require.NoError(t, err) assert.Equal(t, topodatapb.TabletType_REPLICA, ti.Type) assert.Nil(t, ti.MasterTermStartTime) + assert.Equal(t, "replica", statsTabletType.Get()) } func TestPublishStateNew(t *testing.T) { From 4b3ebcb23aa192661eadc23bb7bcd53809062c0b Mon Sep 17 00:00:00 2001 From: deepthi Date: Sat, 30 Jan 2021 17:50:47 -0800 Subject: [PATCH 075/310] Add VT_BASE_VER to vtexplain/Dockerfile so that it can be built off a branch instead of always using latest Signed-off-by: deepthi --- docker/k8s/vtexplain/Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docker/k8s/vtexplain/Dockerfile b/docker/k8s/vtexplain/Dockerfile index 0fcdf4599a2..45c7b7ec781 100644 --- a/docker/k8s/vtexplain/Dockerfile +++ b/docker/k8s/vtexplain/Dockerfile @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM vitess/base AS base +ARG VT_BASE_VER=latest + +FROM vitess/base:${VT_BASE_VER} AS base FROM debian:buster-slim From 9c7727aa74d66c7b5acbc6891cfbc3e0a04ff115 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 15 Feb 2021 22:53:23 +0530 Subject: [PATCH 076/310] fix table parsing for VSchema generation to include reserved and non reserved keywords Signed-off-by: Harshit Gangal --- go/vt/sqlparser/parse_table.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/go/vt/sqlparser/parse_table.go b/go/vt/sqlparser/parse_table.go index a8431aacc01..8766994ecfd 100644 --- a/go/vt/sqlparser/parse_table.go +++ b/go/vt/sqlparser/parse_table.go @@ -32,7 +32,10 @@ func ParseTable(input string) (keyspace, table string, err error) { case ID: table = string(value) default: - return "", "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid table name: %s", input) + table = KeywordString(token) + if table == "" { + return "", "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid table name: %s", input) + } } // Seen first ID, want '.' or 0 @@ -52,7 +55,10 @@ func ParseTable(input string) (keyspace, table string, err error) { case ID: table = string(value) default: - return "", "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid table name: %s", input) + table = KeywordString(token) + if table == "" { + return "", "", vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid table name: %s", input) + } } // Seen second ID, want 0 From 7e0cd636acb71b24cd557bb87716e3da92b410c6 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 18 Feb 2021 12:53:30 +0530 Subject: [PATCH 077/310] added parse table tests Signed-off-by: Harshit Gangal --- go/vt/sqlparser/parse_table_test.go | 40 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/go/vt/sqlparser/parse_table_test.go b/go/vt/sqlparser/parse_table_test.go index 09e7ea44177..48045c0a96b 100644 --- a/go/vt/sqlparser/parse_table_test.go +++ b/go/vt/sqlparser/parse_table_test.go @@ -19,6 +19,8 @@ package sqlparser import ( "testing" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/assert" ) @@ -55,15 +57,37 @@ func TestParseTable(t *testing.T) { }, { input: "k.t.", err: true, + }, { + input: "k.language", + keyspace: "k", + table: "language", + }, { + input: "language", + keyspace: "", + table: "language", + }, { + input: "language.tables", + keyspace: "language", + table: "tables", + }, { + input: "language.t", + keyspace: "language", + table: "t", + }, { + input: "`from`.`table`", + keyspace: "from", + table: "table", }} for _, tcase := range testcases { - keyspace, table, err := ParseTable(tcase.input) - assert.Equal(t, tcase.keyspace, keyspace) - assert.Equal(t, tcase.table, table) - if tcase.err { - assert.Error(t, err) - } else { - assert.NoError(t, err) - } + t.Run(tcase.input, func(t *testing.T) { + keyspace, table, err := ParseTable(tcase.input) + if tcase.err { + require.Error(t, err) + } else { + require.NoError(t, err) + } + assert.Equal(t, tcase.keyspace, keyspace) + assert.Equal(t, tcase.table, table) + }) } } From 1ca335d60a27eb7dd5306930d5b432bc1f618fb7 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 22 Feb 2021 13:53:25 +0530 Subject: [PATCH 078/310] show planner to use any keyspace over first sorted keyspace. First Sorted keyspace does not account for default selected keyspace on that session. Signed-off-by: Harshit Gangal --- go/vt/vtgate/planbuilder/show.go | 2 +- .../vtgate/planbuilder/testdata/show_cases.txt | 2 -- .../show_cases_no_default_keyspace.txt | 18 ++++++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/go/vt/vtgate/planbuilder/show.go b/go/vt/vtgate/planbuilder/show.go index a94ada32e27..ab365b3d993 100644 --- a/go/vt/vtgate/planbuilder/show.go +++ b/go/vt/vtgate/planbuilder/show.go @@ -88,7 +88,7 @@ func buildShowBasicPlan(show *sqlparser.ShowBasic, vschema ContextVSchema) (engi } func showSendAnywhere(show *sqlparser.ShowBasic, vschema ContextVSchema) (engine.Primitive, error) { - ks, err := vschema.FirstSortedKeyspace() + ks, err := vschema.AnyKeyspace() if err != nil { return nil, err } diff --git a/go/vt/vtgate/planbuilder/testdata/show_cases.txt b/go/vt/vtgate/planbuilder/testdata/show_cases.txt index 77f8a2b566e..517d48187c3 100644 --- a/go/vt/vtgate/planbuilder/testdata/show_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/show_cases.txt @@ -214,7 +214,6 @@ } } - # show variables "show variables" { @@ -233,7 +232,6 @@ } } - # show databases "show databases" { diff --git a/go/vt/vtgate/planbuilder/testdata/show_cases_no_default_keyspace.txt b/go/vt/vtgate/planbuilder/testdata/show_cases_no_default_keyspace.txt index 899c530bacf..8a837a8a889 100644 --- a/go/vt/vtgate/planbuilder/testdata/show_cases_no_default_keyspace.txt +++ b/go/vt/vtgate/planbuilder/testdata/show_cases_no_default_keyspace.txt @@ -33,3 +33,21 @@ "SingleShardOnly": true } } + +# show variables +"show variables" +{ + "QueryType": "SHOW", + "Original": "show variables", + "Instructions": { + "OperatorType": "Send", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetDestination": "AnyShard()", + "IsDML": false, + "Query": "show variables", + "SingleShardOnly": true + } +} From fbd9430b0516c36884903529cf1f9f08614f266b Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 22 Feb 2021 15:00:01 +0530 Subject: [PATCH 079/310] fix show executor unit test Signed-off-by: Harshit Gangal --- go/vt/vtgate/executor_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/executor_test.go b/go/vt/vtgate/executor_test.go index 0b9d42e6c9a..869a4823baf 100644 --- a/go/vt/vtgate/executor_test.go +++ b/go/vt/vtgate/executor_test.go @@ -435,7 +435,7 @@ func TestExecutorShowColumns(t *testing.T) { func TestExecutorShow(t *testing.T) { executor, _, _, sbclookup := createLegacyExecutorEnv() - session := NewSafeSession(&vtgatepb.Session{TargetString: "@master"}) + session := NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}) for _, query := range []string{"show databases", "show vitess_keyspaces", "show keyspaces", "show DATABASES", "show schemas", "show SCHEMAS"} { qr, err := executor.Execute(ctx, "TestExecute", session, query, nil) @@ -449,6 +449,8 @@ func TestExecutorShow(t *testing.T) { _, err = executor.Execute(ctx, "TestExecute", session, "show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'", nil) require.NoError(t, err) + _, err = executor.Execute(ctx, "TestExecute", session, "use @master", nil) + require.NoError(t, err) _, err = executor.Execute(ctx, "TestExecute", session, "show tables", nil) assert.EqualError(t, err, errNoKeyspace.Error(), "'show tables' should fail without a keyspace") assert.Empty(t, sbclookup.Queries, "sbclookup unexpectedly has queries already") From f54e5292d9d006fe024582092aeee02eb7d78397 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 23 Feb 2021 13:13:50 +0530 Subject: [PATCH 080/310] consider connection closed when transaction is not found and reset the session Signed-off-by: Harshit Gangal --- go/vt/vtgate/scatter_conn.go | 2 +- go/vt/vtgate/scatter_conn_test.go | 52 +++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index f2910ed31fc..12565c6af09 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -266,7 +266,7 @@ func (stc *ScatterConn) ExecuteMultiShard( return qr, allErrors.GetErrors() } -var errRegx = regexp.MustCompile("transaction ([a-z0-9:]+) ended") +var errRegx = regexp.MustCompile("transaction ([a-z0-9:]+) (?:ended|not found)") func checkAndResetShardSession(info *shardActionInfo, err error, session *SafeSession) bool { if info.reservedID != 0 && info.transactionID == 0 && wasConnectionClosed(err) { diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index 28baeb77db7..49b85b1123a 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -295,12 +295,64 @@ func TestReservedConnFail(t *testing.T) { session := NewSafeSession(&vtgatepb.Session{InTransaction: false, InReservedConn: true}) destinations := []key.Destination{key.DestinationShard("0")} + executeOnShards(t, res, keyspace, sc, session, destinations) assert.Equal(t, 1, len(session.ShardSessions)) oldRId := session.Session.ShardSessions[0].ReservedId + sbc0.EphemeralShardErr = mysql.NewSQLError(mysql.CRServerGone, mysql.SSUnknownSQLState, "lost connection") _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) assert.Equal(t, 3, len(sbc0.Queries), "1 for the successful run, one for the failed attempt, and one for the retry") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + + sbc0.Queries = nil + sbc0.EphemeralShardErr = mysql.NewSQLError(mysql.ERQueryInterrupted, mysql.SSUnknownSQLState, "transaction 123 not found") + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + + sbc0.Queries = nil + sbc0.EphemeralShardErr = mysql.NewSQLError(mysql.ERQueryInterrupted, mysql.SSUnknownSQLState, "transaction 123 ended at 2020-01-20") + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") +} + +func TestIsConnClosed(t *testing.T) { + var testCases = []struct { + name string + err error + conClosed bool + }{{ + "server gone", + mysql.NewSQLError(mysql.CRServerGone, mysql.SSServerShutdown, ""), + true, + }, { + "connection lost", + mysql.NewSQLError(mysql.CRServerLost, mysql.SSServerShutdown, ""), + true, + }, { + "tx ended", + mysql.NewSQLError(mysql.ERQueryInterrupted, mysql.SSUnknownSQLState, "transaction 111 ended at ..."), + true, + }, { + "tx not found", + mysql.NewSQLError(mysql.ERQueryInterrupted, mysql.SSUnknownSQLState, "transaction 111 not found ..."), + true, + }, { + "tx not found missing tx id", + mysql.NewSQLError(mysql.ERQueryInterrupted, mysql.SSUnknownSQLState, "transaction not found"), + false, + }} + + for _, tCase := range testCases { + t.Run(tCase.name, func(t *testing.T) { + assert.Equal(t, tCase.conClosed, wasConnectionClosed(tCase.err)) + }) + } } From 1aae1b6499a06a24d959d5f15fb2b059e7ff257e Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 15 Mar 2021 13:33:36 +0100 Subject: [PATCH 081/310] fix regression - should be able to plan subquery on top of subquery Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/filtering.go | 2 + .../planbuilder/testdata/filter_cases.txt | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/go/vt/vtgate/planbuilder/filtering.go b/go/vt/vtgate/planbuilder/filtering.go index 6193f66b5ec..4e22a3cdbc6 100644 --- a/go/vt/vtgate/planbuilder/filtering.go +++ b/go/vt/vtgate/planbuilder/filtering.go @@ -63,6 +63,8 @@ func planFilter(pb *primitiveBuilder, input logicalPlan, filter sqlparser.Expr, } node.UpdatePlan(pb, filter) return node, nil + case *pulloutSubquery: + return planFilter(pb, node.underlying, filter, whereType, origin) case *vindexFunc: return filterVindexFunc(node, filter) case *subquery: diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt index 48682ad7d6d..038e498bc60 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt @@ -1773,3 +1773,46 @@ "SysTableTableSchema": "VARBINARY(\"ks\")" } } + +# pullout sq after pullout sq +"select id from user where not id in (select user_extra.col from user_extra where user_extra.user_id = 42) and id in (select user_extra.col from user_extra where user_extra.user_id = 411)" +{ + "QueryType": "SELECT", + "Original": "select id from user where not id in (select user_extra.col from user_extra where user_extra.user_id = 42) and id in (select user_extra.col from user_extra where user_extra.user_id = 411)", + "Instructions": { + "OperatorType": "Subquery", + "Variant": "PulloutIn", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "SelectEqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select user_extra.col from user_extra where 1 != 1", + "Query": "select user_extra.col from user_extra where user_extra.user_id = 42", + "Table": "user_extra", + "Values": [ + 42 + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "SelectIN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id from user where 1 != 1", + "Query": "select id from user where :__sq_has_values1 = 1 and id in ::__vals and not (:__sq_has_values2 = 1 and id in ::__sq2)", + "Table": "user", + "Values": [ + "::__sq1" + ], + "Vindex": "user_index" + } + ] + } +} From 5643642fd3c5f3e858171d495605d0886f140356 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 16 Mar 2021 11:38:43 +0200 Subject: [PATCH 082/310] ubuntu-18.04 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .github/workflows/unit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index ba58c5af400..e40b4921ab1 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 strategy: matrix: name: [percona56, mysql57, mysql80, mariadb101, mariadb102, mariadb103] From 2115fa64c42e405931c44b4a7c09cb1d39789c5c Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Tue, 16 Mar 2021 11:49:16 +0200 Subject: [PATCH 083/310] all ubuntu-latest => ubuntu-18.04 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .github/workflows/check_formatting.yml | 2 +- .github/workflows/check_make_parser.yml | 2 +- .github/workflows/check_make_visitor.yml | 2 +- .github/workflows/cluster_endtoend.yml | 2 +- .github/workflows/cluster_endtoend_upgrade.yml | 2 +- .github/workflows/cluster_initial_sharding_multi.yml | 2 +- .github/workflows/create_release.yml | 2 +- .github/workflows/docker_test_1.yml | 4 ++-- .github/workflows/docker_test_2.yml | 4 ++-- .github/workflows/docker_test_3.yml | 2 +- .github/workflows/e2e_race.yml | 2 +- .github/workflows/endtoend.yml | 2 +- .github/workflows/ensure_bootstrap_updated.yml | 2 +- .github/workflows/golangci-linter.yml | 2 +- .github/workflows/sonar_analysis.yml | 2 +- .github/workflows/unit_race.yml | 2 +- 16 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/check_formatting.yml b/.github/workflows/check_formatting.yml index 3f2334dd4bb..9c64b18ced4 100644 --- a/.github/workflows/check_formatting.yml +++ b/.github/workflows/check_formatting.yml @@ -4,7 +4,7 @@ jobs: build: name: Check Formatting - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/check_make_parser.yml b/.github/workflows/check_make_parser.yml index 805cf2fe494..c856da3e580 100644 --- a/.github/workflows/check_make_parser.yml +++ b/.github/workflows/check_make_parser.yml @@ -4,7 +4,7 @@ jobs: build: name: Check Make Parser - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/check_make_visitor.yml b/.github/workflows/check_make_visitor.yml index 219e1ece2dc..b72fbbaf514 100644 --- a/.github/workflows/check_make_visitor.yml +++ b/.github/workflows/check_make_visitor.yml @@ -4,7 +4,7 @@ jobs: build: name: Check Make Visitor - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/cluster_endtoend.yml b/.github/workflows/cluster_endtoend.yml index 60edd6e3405..4ec4671d62f 100644 --- a/.github/workflows/cluster_endtoend.yml +++ b/.github/workflows/cluster_endtoend.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 strategy: matrix: name: [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27] diff --git a/.github/workflows/cluster_endtoend_upgrade.yml b/.github/workflows/cluster_endtoend_upgrade.yml index 185b9fbbe09..e7ad8653838 100644 --- a/.github/workflows/cluster_endtoend_upgrade.yml +++ b/.github/workflows/cluster_endtoend_upgrade.yml @@ -4,7 +4,7 @@ jobs: build: name: Run endtoend tests on Cluster (upgrade) - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/cluster_initial_sharding_multi.yml b/.github/workflows/cluster_initial_sharding_multi.yml index 147b8e7e1cf..494dfca2bb6 100644 --- a/.github/workflows/cluster_initial_sharding_multi.yml +++ b/.github/workflows/cluster_initial_sharding_multi.yml @@ -4,7 +4,7 @@ jobs: build: name: cluster initial sharding multi - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 85a4d098d5c..f126dd76e35 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -10,7 +10,7 @@ on: jobs: build: name: Create Release - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/docker_test_1.yml b/.github/workflows/docker_test_1.yml index f15e3a3f9bd..11a53e1a48b 100644 --- a/.github/workflows/docker_test_1.yml +++ b/.github/workflows/docker_test_1.yml @@ -4,7 +4,7 @@ jobs: build: name: Docker Test 1 - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: @@ -18,4 +18,4 @@ jobs: - name: Run tests which require docker - 1 run: | - go run test.go -docker=true --follow -shard 10 \ No newline at end of file + go run test.go -docker=true --follow -shard 10 diff --git a/.github/workflows/docker_test_2.yml b/.github/workflows/docker_test_2.yml index 84ea569d5de..46d04889bbd 100644 --- a/.github/workflows/docker_test_2.yml +++ b/.github/workflows/docker_test_2.yml @@ -4,7 +4,7 @@ jobs: build: name: Docker Test 2 - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: @@ -18,4 +18,4 @@ jobs: - name: Run tests which require docker - 2 run: | - go run test.go -docker=true --follow -shard 25 \ No newline at end of file + go run test.go -docker=true --follow -shard 25 diff --git a/.github/workflows/docker_test_3.yml b/.github/workflows/docker_test_3.yml index 92c9e0cbe5f..6cc880e992f 100644 --- a/.github/workflows/docker_test_3.yml +++ b/.github/workflows/docker_test_3.yml @@ -4,7 +4,7 @@ jobs: build: name: Docker Test 3 - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index b6ce4793970..1b66cdcbe13 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -4,7 +4,7 @@ jobs: build: name: End-to-End Test (Race) - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index 026e8f1f4ef..8be2dbb3179 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -4,7 +4,7 @@ jobs: build: name: End-to-End Test - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/ensure_bootstrap_updated.yml b/.github/workflows/ensure_bootstrap_updated.yml index 3ec8261c9b6..6bb1af2eb76 100644 --- a/.github/workflows/ensure_bootstrap_updated.yml +++ b/.github/workflows/ensure_bootstrap_updated.yml @@ -4,7 +4,7 @@ jobs: build: name: Check Bootstrap Updated - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/golangci-linter.yml b/.github/workflows/golangci-linter.yml index b91b8d06a47..bc6799331ff 100644 --- a/.github/workflows/golangci-linter.yml +++ b/.github/workflows/golangci-linter.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: build: name: Build - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go 1.15 uses: actions/setup-go@v1 diff --git a/.github/workflows/sonar_analysis.yml b/.github/workflows/sonar_analysis.yml index 3381d93b223..af59daa03b7 100644 --- a/.github/workflows/sonar_analysis.yml +++ b/.github/workflows/sonar_analysis.yml @@ -6,7 +6,7 @@ on: jobs: build: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index 7e71449de83..d280afe62a6 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -4,7 +4,7 @@ jobs: build: name: Unit Test (Race) - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go From b6e31d24b5b66c4013973b3e674dc8fd17d756c5 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 16:12:15 +0530 Subject: [PATCH 084/310] added e2e test for unsharded reserved connection transaction Signed-off-by: Harshit Gangal --- .../endtoend/vtgate/unsharded/main_test.go | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/go/test/endtoend/vtgate/unsharded/main_test.go b/go/test/endtoend/vtgate/unsharded/main_test.go index f5c3ebce188..2dd99bca9b9 100644 --- a/go/test/endtoend/vtgate/unsharded/main_test.go +++ b/go/test/endtoend/vtgate/unsharded/main_test.go @@ -22,6 +22,7 @@ import ( "fmt" "os" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" @@ -215,6 +216,29 @@ func TestDDLUnsharded(t *testing.T) { assertMatches(t, conn, "show tables", `[[VARCHAR("allDefaults")] [VARCHAR("t1")]]`) } +func TestReservedConnDML(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, `set default_week_format = 1`) + exec(t, conn, `begin`) + exec(t, conn, `insert into allDefaults () values ()`) + exec(t, conn, `commit`) + + time.Sleep(35 * time.Second) + + exec(t, conn, `begin`) + exec(t, conn, `insert into allDefaults () values ()`) + exec(t, conn, `commit`) +} + func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { t.Helper() qr, err := conn.ExecuteFetch(query, 1000, true) From 7db4e526f62f009d5a777bc877944d57e3bd4ba4 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 18:43:06 +0530 Subject: [PATCH 085/310] added unit test for reserved conn issue Signed-off-by: Harshit Gangal --- go/vt/vtgate/executor_dml_test.go | 53 +++++++++++++++++++++++ go/vt/vttablet/sandboxconn/sandboxconn.go | 2 +- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/executor_dml_test.go b/go/vt/vtgate/executor_dml_test.go index 0902738fefc..11bee5a489c 100644 --- a/go/vt/vtgate/executor_dml_test.go +++ b/go/vt/vtgate/executor_dml_test.go @@ -23,6 +23,8 @@ import ( "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/utils" "github.com/stretchr/testify/require" @@ -1737,3 +1739,54 @@ func TestDeleteLookupOwnedEqual(t *testing.T) { utils.MustMatch(t, sbc1.Queries, sbc1wantQueries, "") utils.MustMatch(t, sbc2.Queries, sbc2wantQueries, "") } + +func TestReservedConnDML(t *testing.T) { + executor, _, _, sbc := createExecutorEnv() + + logChan := QueryLogger.Subscribe("TestReservedConnDML") + defer QueryLogger.Unsubscribe(logChan) + + ctx := context.Background() + session := NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true}) + + _, err := executor.Execute(ctx, "TestReservedConnDML", session, "use "+KsTestUnsharded, nil) + require.NoError(t, err) + + wantQueries := []*querypb.BoundQuery{ + {Sql: "select 1 from dual where @@default_week_format != 1", BindVariables: map[string]*querypb.BindVariable{}}, + } + sbc.SetResults([]*sqltypes.Result{ + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id", "int64"), "1"), + }) + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "set default_week_format = 1", nil) + require.NoError(t, err) + utils.MustMatch(t, wantQueries, sbc.Queries) + + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "begin", nil) + require.NoError(t, err) + + wantQueries = append(wantQueries, + &querypb.BoundQuery{Sql: "set @@default_week_format = 1", BindVariables: map[string]*querypb.BindVariable{}}, + &querypb.BoundQuery{Sql: "insert into simple values ()", BindVariables: map[string]*querypb.BindVariable{}}) + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "insert into simple() values ()", nil) + require.NoError(t, err) + utils.MustMatch(t, wantQueries, sbc.Queries) + + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "commit", nil) + require.NoError(t, err) + + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "begin", nil) + require.NoError(t, err) + + sbc.EphemeralShardErr = mysql.NewSQLError(mysql.CRServerGone, mysql.SSNetError, "connection gone") + // as the first time the query fails due to connection loss i.e. reserved conn lost. It will be recreated to set statement will be executed again. + wantQueries = append(wantQueries, + &querypb.BoundQuery{Sql: "set @@default_week_format = 1", BindVariables: map[string]*querypb.BindVariable{}}, + &querypb.BoundQuery{Sql: "insert into simple values ()", BindVariables: map[string]*querypb.BindVariable{}}) + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "insert into simple() values ()", nil) + require.NoError(t, err) + utils.MustMatch(t, wantQueries, sbc.Queries) + + _, err = executor.Execute(ctx, "TestReservedConnDML", session, "commit", nil) + require.NoError(t, err) +} diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 3a9816118b1..823cb312de1 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -441,7 +441,7 @@ func (sbc *SandboxConn) HandlePanic(err *error) { //ReserveBeginExecute implements the QueryService interface func (sbc *SandboxConn) ReserveBeginExecute(ctx context.Context, target *querypb.Target, preQueries []string, sql string, bindVariables map[string]*querypb.BindVariable, options *querypb.ExecuteOptions) (*sqltypes.Result, int64, int64, *topodatapb.TabletAlias, error) { reservedID := sbc.reserve(ctx, target, preQueries, bindVariables, 0, options) - result, transactionID, alias, err := sbc.BeginExecute(ctx, target, preQueries, sql, bindVariables, reservedID, options) + result, transactionID, alias, err := sbc.BeginExecute(ctx, target, nil, sql, bindVariables, reservedID, options) if transactionID != 0 { sbc.txIDToRID[transactionID] = reservedID } From b6056dab7c06bea1bbc0b11e44024db4a06776dd Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 19:01:57 +0530 Subject: [PATCH 086/310] Two changes here: 1. Update the shard sessions only if there is any update i.e. updated transaction id or updated reserved id 2. If there is failure to execute BeginExecute api and the connection is reserved conn then check if shard session can be reset and execute ReserveBeginExecute api Signed-off-by: Harshit Gangal --- go/vt/vtgate/scatter_conn.go | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index 12565c6af09..e63f5499f80 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -227,13 +227,25 @@ func (stc *ScatterConn) ExecuteMultiShard( innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, 0 /*transactionId*/, opts) } if err != nil { - return nil, err + return info.updateReservedID(reservedID, alias), err } } case begin: innerqr, transactionID, alias, err = qs.BeginExecute(ctx, rs.Target, session.Savepoints, queries[i].Sql, queries[i].BindVariables, info.reservedID, opts) if err != nil { - return info.updateTransactionID(transactionID, alias), err + if transactionID != 0 { + return info.updateTransactionID(transactionID, alias), err + } + shouldRetry := checkAndResetShardSession(info, err, session) + if shouldRetry { + // we seem to have lost our connection. if it was a reserved connection, let's try to recreate it + info.actionNeeded = reserveBegin + innerqr, transactionID, reservedID, alias, err = qs.ReserveBeginExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, opts) + } + if err != nil { + return info.updateTransactionAndReservedID(transactionID, reservedID, alias), err + } + } case reserve: innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, info.transactionID, opts) @@ -727,14 +739,26 @@ type shardActionInfo struct { } func (sai *shardActionInfo) updateTransactionID(txID int64, alias *topodatapb.TabletAlias) *shardActionInfo { + if txID == 0 { + // As transaction id is ZERO, there is nothing to update in session shard sessions. + return nil + } return sai.updateTransactionAndReservedID(txID, sai.reservedID, alias) } func (sai *shardActionInfo) updateReservedID(rID int64, alias *topodatapb.TabletAlias) *shardActionInfo { + if rID == 0 { + // As reserved id is ZERO, there is nothing to update in session shard sessions. + return nil + } return sai.updateTransactionAndReservedID(sai.transactionID, rID, alias) } func (sai *shardActionInfo) updateTransactionAndReservedID(txID int64, rID int64, alias *topodatapb.TabletAlias) *shardActionInfo { + if txID == 0 && rID == 0 { + // As transaction id and reserved id is ZERO, there is nothing to update in session shard sessions. + return nil + } newInfo := *sai newInfo.reservedID = rID newInfo.transactionID = txID From 51644530f640e11f762e4933eed162a1db333035 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 19:02:50 +0530 Subject: [PATCH 087/310] return code_aborted if connection not found in case of Begin with reserve connection Signed-off-by: Harshit Gangal --- go/vt/vttablet/tabletserver/tx_pool.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/vttablet/tabletserver/tx_pool.go b/go/vt/vttablet/tabletserver/tx_pool.go index 1a884038939..7962207137b 100644 --- a/go/vt/vttablet/tabletserver/tx_pool.go +++ b/go/vt/vttablet/tabletserver/tx_pool.go @@ -231,6 +231,9 @@ func (tp *TxPool) Begin(ctx context.Context, options *querypb.ExecuteOptions, re var err error if reservedID != 0 { conn, err = tp.scp.GetAndLock(reservedID, "start transaction on reserve conn") + if err != nil { + return nil, "", vterrors.Errorf(vtrpcpb.Code_ABORTED, "transaction %d: %v", reservedID, err) + } } else { immediateCaller := callerid.ImmediateCallerIDFromContext(ctx) effectiveCaller := callerid.EffectiveCallerIDFromContext(ctx) From 453f5a890ed66f187a0b8e1d93b2346b34ff0e87 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 9 Mar 2021 19:32:00 +0530 Subject: [PATCH 088/310] make e2e test to run faster Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/unsharded/main_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/test/endtoend/vtgate/unsharded/main_test.go b/go/test/endtoend/vtgate/unsharded/main_test.go index 2dd99bca9b9..4dc3fd70287 100644 --- a/go/test/endtoend/vtgate/unsharded/main_test.go +++ b/go/test/endtoend/vtgate/unsharded/main_test.go @@ -114,6 +114,7 @@ func TestMain(m *testing.M) { SchemaSQL: SchemaSQL, VSchema: VSchema, } + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-transaction-timeout", "3"} if err := clusterInstance.StartUnshardedKeyspace(*Keyspace, 0, false); err != nil { return 1 } @@ -232,7 +233,7 @@ func TestReservedConnDML(t *testing.T) { exec(t, conn, `insert into allDefaults () values ()`) exec(t, conn, `commit`) - time.Sleep(35 * time.Second) + time.Sleep(6 * time.Second) exec(t, conn, `begin`) exec(t, conn, `insert into allDefaults () values ()`) From 5115a9402052f1a2eb0c06d9a7319087c23afc59 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 12 Mar 2021 11:42:25 +0530 Subject: [PATCH 089/310] fix unit test Signed-off-by: Harshit Gangal --- go/vt/vtgate/executor_dml_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/executor_dml_test.go b/go/vt/vtgate/executor_dml_test.go index 11bee5a489c..1219fd4c96f 100644 --- a/go/vt/vtgate/executor_dml_test.go +++ b/go/vt/vtgate/executor_dml_test.go @@ -1747,7 +1747,8 @@ func TestReservedConnDML(t *testing.T) { defer QueryLogger.Unsubscribe(logChan) ctx := context.Background() - session := NewAutocommitSession(&vtgatepb.Session{EnableSystemSettings: true}) + *sysVarSetEnabled = true + session := NewAutocommitSession(&vtgatepb.Session{}) _, err := executor.Execute(ctx, "TestReservedConnDML", session, "use "+KsTestUnsharded, nil) require.NoError(t, err) @@ -1778,7 +1779,7 @@ func TestReservedConnDML(t *testing.T) { _, err = executor.Execute(ctx, "TestReservedConnDML", session, "begin", nil) require.NoError(t, err) - sbc.EphemeralShardErr = mysql.NewSQLError(mysql.CRServerGone, mysql.SSNetError, "connection gone") + sbc.EphemeralShardErr = mysql.NewSQLError(mysql.CRServerGone, mysql.SSUnknownSQLState, "connection gone") // as the first time the query fails due to connection loss i.e. reserved conn lost. It will be recreated to set statement will be executed again. wantQueries = append(wantQueries, &querypb.BoundQuery{Sql: "set @@default_week_format = 1", BindVariables: map[string]*querypb.BindVariable{}}, From 9ced2ddcea919b17413702f531b120c15a0d66fd Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 17 Mar 2021 15:02:39 +0530 Subject: [PATCH 090/310] add current_user parse test Signed-off-by: Harshit Gangal --- go/vt/sqlparser/parse_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 6878ebe4bda..f64a3b072bb 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -2080,6 +2080,9 @@ func TestKeywords(t *testing.T) { }, { input: "select Variables from t", output: "select `Variables` from t", + }, { + input: "select current_user, current_user() from dual", + output: "select current_user(), current_user() from dual", }} for _, tcase := range validSQL { From 77a633b1279e8c38f63ae2a2edaa99e66834dfa6 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 17 Mar 2021 15:04:34 +0530 Subject: [PATCH 091/310] added parsing support for current_user function Signed-off-by: Harshit Gangal --- go/vt/sqlparser/sql.go | 5895 ++++++++++++++++++++-------------------- go/vt/sqlparser/sql.y | 22 +- 2 files changed, 2961 insertions(+), 2956 deletions(-) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index fcd8343aa4e..6c521afb8b9 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1036,7 +1036,7 @@ var yyExca = [...]int{ 1, -1, -2, 0, -1, 42, - 163, 906, + 163, 907, -2, 89, -1, 43, 1, 107, @@ -1073,1262 +1073,642 @@ var yyExca = [...]int{ 252, 113, 300, 113, -2, 334, - -1, 549, - 149, 917, - -2, 913, -1, 550, 149, 918, -2, 914, - -1, 567, + -1, 551, + 149, 919, + -2, 915, + -1, 568, 55, 531, -2, 543, - -1, 568, + -1, 569, 55, 532, -2, 544, - -1, 588, - 117, 1244, - -2, 82, -1, 589, - 117, 1131, + 117, 1245, + -2, 82, + -1, 590, + 117, 1132, -2, 83, - -1, 595, - 117, 1179, - -2, 891, - -1, 729, - 117, 1073, - -2, 888, - -1, 761, + -1, 596, + 117, 1180, + -2, 892, + -1, 730, + 117, 1074, + -2, 889, + -1, 762, 174, 36, 179, 36, -2, 241, - -1, 840, + -1, 841, 1, 372, 451, 372, -2, 113, - -1, 1055, + -1, 1057, 1, 268, 451, 268, -2, 113, - -1, 1128, + -1, 1130, 168, 230, 169, 230, -2, 319, - -1, 1137, + -1, 1139, 174, 37, 179, 37, -2, 242, - -1, 1331, - 149, 920, - -2, 916, - -1, 1421, + -1, 1333, + 149, 921, + -2, 917, + -1, 1423, 73, 64, 81, 64, -2, 68, - -1, 1442, + -1, 1444, 1, 269, 451, 269, -2, 113, - -1, 1829, - 5, 785, - 18, 785, - 20, 785, - 32, 785, - 82, 785, + -1, 1831, + 5, 786, + 18, 786, + 20, 786, + 32, 786, + 82, 786, -2, 569, - -1, 2041, - 45, 859, - -2, 857, + -1, 2043, + 45, 860, + -2, 858, } const yyPrivate = 57344 -const yyLast = 26381 +const yyLast = 26340 var yyAct = [...]int{ - 549, 2127, 1876, 2114, 2041, 1747, 2091, 2054, 493, 1645, - 1987, 1716, 1965, 893, 79, 3, 1809, 1504, 1810, 522, - 1439, 1613, 1368, 1720, 508, 1873, 1003, 1646, 1354, 1806, - 1474, 959, 491, 1010, 1459, 1704, 1703, 1632, 1479, 1418, - 1821, 852, 142, 1768, 1573, 891, 1153, 173, 1325, 593, - 185, 1317, 458, 185, 733, 1246, 791, 1135, 474, 1259, - 185, 1502, 128, 1696, 1481, 77, 1047, 1040, 1031, 569, - 1400, 1370, 756, 1407, 1008, 1013, 1033, 31, 997, 495, - 1351, 554, 1294, 1551, 1142, 740, 1037, 1482, 474, 1030, - 737, 474, 185, 474, 741, 484, 1225, 762, 757, 758, - 1383, 590, 1046, 1423, 1044, 75, 1020, 1262, 563, 172, - 1470, 833, 759, 111, 112, 1127, 560, 769, 972, 1460, - 74, 8, 481, 7, 105, 145, 106, 973, 6, 1739, - 1738, 1989, 1533, 1365, 1366, 1212, 2083, 1611, 2038, 1280, - 1944, 2016, 2015, 1852, 795, 1960, 794, 534, 1961, 540, - 541, 538, 539, 555, 537, 536, 535, 2133, 575, 579, - 113, 577, 2088, 734, 542, 543, 2126, 1486, 185, 107, - 76, 436, 2065, 2117, 1877, 1521, 796, 2087, 185, 1785, - 846, 2064, 1906, 185, 482, 483, 33, 793, 1484, 68, - 37, 38, 587, 174, 175, 176, 748, 1612, 1540, 80, - 807, 808, 1539, 811, 812, 813, 814, 594, 97, 817, - 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, - 828, 829, 830, 831, 1835, 485, 1328, 751, 772, 750, - 107, 749, 1433, 773, 82, 83, 84, 85, 86, 87, - 102, 178, 179, 180, 1836, 1837, 889, 797, 798, 799, - 1048, 1676, 1049, 449, 1675, 1367, 462, 1677, 862, 804, - 67, 810, 450, 102, 94, 809, 752, 1483, 1434, 1435, - 98, 860, 447, 99, 100, 871, 872, 553, 552, 174, - 175, 176, 171, 1687, 174, 175, 176, 1453, 166, 1937, - 1749, 1897, 33, 34, 35, 68, 37, 38, 107, 1281, - 1282, 1283, 873, 1895, 461, 472, 874, 871, 872, 2067, - 1279, 444, 72, 108, 1769, 476, 470, 39, 65, 66, - 456, 63, 1202, 150, 888, 1721, 1536, 64, 1503, 2028, - 921, 920, 930, 931, 923, 924, 925, 926, 927, 928, - 929, 922, 1743, 1226, 932, 2116, 863, 887, 834, 1744, - 1234, 2084, 1235, 1236, 868, 1231, 52, 1771, 880, 861, - 882, 1750, 462, 1203, 1680, 1204, 67, 102, 167, 866, - 867, 462, 864, 865, 841, 1752, 462, 147, 1548, 148, - 816, 815, 1230, 1955, 771, 1751, 1228, 1112, 165, 437, - 438, 439, 101, 454, 455, 465, 780, 879, 881, 451, - 453, 466, 440, 441, 468, 467, 1851, 443, 442, 1232, - 461, 446, 463, 2012, 1773, 101, 1777, 753, 1772, 461, - 1770, 1505, 771, 1229, 461, 1775, 1401, 789, 778, 1485, - 788, 787, 786, 1538, 1774, 785, 185, 784, 42, 45, - 48, 47, 50, 783, 62, 2063, 151, 1776, 1778, 782, - 875, 878, 777, 462, 1121, 790, 156, 1956, 1555, 474, - 474, 474, 844, 738, 1424, 885, 2134, 2103, 765, 51, - 71, 70, 738, 104, 60, 61, 49, 474, 474, 855, - 856, 857, 858, 859, 764, 738, 845, 771, 781, 736, - 170, 771, 745, 903, 877, 1753, 2131, 1141, 1140, 890, - 2055, 461, 69, 581, 1527, 894, 895, 1614, 1616, 876, - 53, 54, 2004, 55, 56, 57, 58, 2068, 770, 101, - 779, 1239, 897, 800, 1713, 764, 767, 768, 1535, 738, - 1794, 771, 1793, 761, 765, 806, 464, 2029, 1792, 746, - 1731, 771, 435, 459, 1214, 1213, 1215, 1216, 1217, 177, - 1523, 1592, 760, 185, 1553, 2045, 770, 143, 460, 1552, - 1553, 1547, 774, 764, 1546, 1552, 944, 945, 838, 1589, - 942, 1001, 775, 1926, 1834, 1637, 1581, 1513, 474, 1429, - 869, 185, 1024, 185, 185, 957, 474, 850, 1000, 1440, - 776, 932, 474, 922, 884, 1672, 932, 1379, 854, 590, - 906, 960, 904, 1615, 1276, 2020, 886, 905, 69, 921, - 920, 930, 931, 923, 924, 925, 926, 927, 928, 929, - 922, 770, 1029, 932, 912, 770, 792, 774, 764, 998, - 1819, 1260, 764, 767, 768, 1263, 738, 775, 1227, 1014, - 761, 765, 2129, 847, 848, 2130, 840, 2128, 835, 913, - 836, 2005, 2003, 837, 975, 977, 979, 981, 983, 985, - 986, 1352, 1050, 976, 978, 770, 982, 984, 1574, 987, - 911, 909, 907, 1522, 995, 770, 839, 805, 925, 926, - 927, 928, 929, 922, 1787, 485, 932, 912, 1116, 944, - 945, 174, 175, 176, 970, 1319, 923, 924, 925, 926, - 927, 928, 929, 922, 90, 594, 932, 944, 945, 1520, - 853, 144, 149, 146, 152, 153, 154, 155, 157, 158, - 159, 160, 1518, 1006, 1009, 1301, 780, 161, 162, 163, - 164, 1450, 778, 185, 174, 175, 176, 1108, 909, 1299, - 1300, 1298, 1701, 1451, 1685, 185, 1261, 1117, 1118, 91, - 1264, 1320, 2048, 744, 912, 1381, 1352, 1002, 1599, 1017, - 474, 67, 1137, 2135, 1587, 169, 910, 911, 909, 2121, - 1146, 1515, 1586, 1297, 1150, 1384, 1385, 474, 474, 2120, - 474, 1147, 474, 474, 912, 474, 474, 474, 474, 474, - 474, 1943, 1515, 1012, 1692, 1519, 1942, 910, 911, 909, - 474, 910, 911, 909, 185, 1186, 1181, 1182, 1119, 1120, - 1289, 1291, 1292, 1857, 1133, 912, 1517, 1380, 1126, 912, - 1199, 2110, 1290, 1700, 1155, 1699, 1156, 1145, 1158, 1160, - 2136, 474, 1164, 1166, 1168, 1170, 1172, 2118, 2099, 185, - 1489, 564, 910, 911, 909, 185, 1107, 2077, 185, 1245, - 747, 185, 1222, 1144, 1183, 1114, 910, 911, 909, 743, - 912, 1207, 185, 1206, 185, 2119, 1189, 1190, 1124, 1122, - 1123, 1136, 1195, 1196, 912, 1588, 474, 474, 185, 474, - 474, 185, 474, 474, 1796, 1143, 1143, 921, 920, 930, - 931, 923, 924, 925, 926, 927, 928, 929, 922, 1205, - 1248, 932, 1251, 1221, 1253, 1219, 1255, 1256, 1257, 1258, - 2108, 910, 911, 909, 1566, 1567, 1568, 1197, 1191, 1789, - 1184, 1266, 1267, 1759, 1269, 1270, 1209, 1272, 1273, 912, - 1265, 1240, 1797, 1318, 1188, 1295, 1187, 1162, 2109, 1045, - 1978, 1940, 1321, 921, 920, 930, 931, 923, 924, 925, - 926, 927, 928, 929, 922, 1914, 474, 932, 910, 911, - 909, 1220, 580, 1218, 1798, 750, 107, 749, 174, 175, - 176, 1329, 1679, 1709, 1340, 1343, 912, 1322, 1323, 1697, - 1353, 174, 175, 176, 1208, 1497, 1563, 1333, 1334, 474, - 474, 1274, 1531, 1530, 1335, 1296, 1249, 174, 175, 176, - 185, 1495, 174, 175, 176, 1210, 1200, 1331, 174, 175, - 176, 1198, 474, 1330, 1194, 1193, 1250, 1192, 1746, 185, - 564, 960, 474, 1862, 2102, 76, 185, 585, 185, 2010, - 1375, 1862, 2061, 1862, 2046, 2009, 185, 185, 1329, 1909, - 1359, 1360, 1875, 474, 1862, 564, 474, 1633, 582, 583, - 1419, 1862, 2018, 1958, 564, 1723, 590, 474, 1712, 590, - 1515, 564, 1924, 564, 1332, 1862, 1867, 1849, 1848, 1425, - 1284, 1285, 1286, 1287, 1331, 1845, 1846, 1845, 1844, 1425, - 1398, 1392, 564, 1448, 1394, 33, 921, 920, 930, 931, - 923, 924, 925, 926, 927, 928, 929, 922, 1443, 1633, - 932, 1393, 564, 1424, 1740, 1461, 1462, 1463, 1111, 1725, - 1640, 1444, 474, 1718, 1719, 1404, 550, 1374, 1404, 564, - 1494, 1496, 1807, 1422, 1945, 1338, 1339, 1386, 1396, 1447, - 1426, 1818, 1641, 474, 908, 564, 1666, 1476, 1428, 474, - 1426, 1516, 1427, 1146, 1424, 1146, 1431, 1430, 1424, 1111, - 1110, 1056, 1055, 1514, 33, 1446, 1445, 78, 1818, 67, - 1403, 1921, 594, 908, 33, 594, 186, 1818, 2019, 186, - 1392, 1946, 1947, 1948, 475, 2053, 186, 1862, 1847, 1404, - 1432, 1604, 1603, 474, 557, 1318, 1392, 1501, 1336, 1337, - 1318, 1318, 1342, 1345, 1346, 1515, 1515, 1498, 1477, 1177, - 1511, 1994, 1512, 1382, 475, 1493, 1487, 475, 186, 475, - 1404, 1490, 1438, 1488, 1472, 1473, 1363, 1358, 1238, 1042, - 1361, 1362, 1392, 755, 1507, 185, 1510, 1477, 67, 185, - 185, 185, 185, 185, 1506, 754, 1526, 1524, 67, 185, - 185, 1528, 1529, 185, 772, 1525, 1178, 1179, 1180, 773, - 67, 1967, 1874, 1932, 1113, 1475, 1745, 1508, 67, 1143, - 1471, 185, 185, 185, 1465, 511, 510, 513, 514, 515, - 516, 1478, 1464, 1224, 512, 185, 517, 1138, 185, 474, - 1134, 1109, 92, 1706, 186, 488, 1409, 1412, 1413, 1414, - 1410, 171, 1411, 1415, 186, 1748, 1822, 1823, 1968, 186, - 1705, 1557, 1949, 1486, 1174, 1822, 1823, 1561, 2123, 2115, - 1840, 1534, 916, 1825, 919, 1807, 1714, 1277, 1295, 1242, - 933, 934, 935, 936, 937, 938, 939, 1556, 917, 918, - 915, 921, 920, 930, 931, 923, 924, 925, 926, 927, - 928, 929, 922, 1828, 1706, 932, 1950, 1951, 1175, 1176, - 1576, 1827, 1654, 1653, 1577, 1409, 1412, 1413, 1414, 1410, - 2105, 1411, 1415, 1657, 185, 1584, 1585, 1659, 1658, 1413, - 1414, 1591, 185, 2086, 1594, 1595, 1011, 1799, 1296, 1622, - 1655, 1569, 1601, 1925, 1602, 1656, 1865, 1605, 1606, 1607, - 1608, 1609, 1631, 1630, 185, 2073, 2070, 2107, 2090, 2092, - 96, 1619, 2098, 1620, 2097, 185, 185, 185, 185, 185, - 555, 1621, 1647, 1626, 1582, 1642, 2042, 185, 2040, 1237, - 551, 185, 1710, 802, 185, 185, 801, 1004, 185, 185, - 185, 1598, 1705, 1635, 896, 1664, 1348, 1638, 1733, 1005, - 998, 1678, 1610, 1618, 1919, 1732, 168, 1662, 1663, 181, - 1349, 1454, 1583, 1455, 1456, 1457, 1458, 1625, 1684, 108, - 2050, 1691, 2049, 1667, 1636, 1992, 1509, 1669, 1634, 1466, - 1467, 1468, 1469, 1152, 1649, 1650, 1151, 1652, 1139, 1248, - 1690, 1377, 1693, 1694, 1695, 1681, 1491, 474, 1241, 1660, - 1688, 1689, 1665, 570, 1648, 2011, 1670, 1651, 1962, 1673, - 474, 1384, 1385, 1417, 558, 559, 474, 571, 561, 474, - 1629, 1146, 1722, 2112, 1600, 1917, 474, 1682, 1628, 2111, - 1726, 570, 2095, 2074, 1918, 1861, 1499, 1728, 1737, 1698, - 1015, 1016, 573, 562, 572, 571, 185, 78, 1802, 1633, - 1708, 1593, 1623, 1624, 1009, 1707, 1590, 1736, 1025, 1735, - 2125, 2124, 186, 1578, 1579, 474, 185, 1018, 567, 568, - 573, 1126, 572, 1331, 2125, 2043, 1938, 1378, 1727, 1330, - 557, 76, 81, 73, 1596, 475, 475, 475, 1, 445, - 1364, 996, 474, 457, 2113, 1211, 1734, 1201, 1318, 1878, - 1964, 1868, 1492, 475, 475, 1765, 1702, 1480, 763, 133, - 1754, 1441, 1442, 2057, 89, 731, 88, 1762, 1763, 766, - 1767, 883, 1500, 2002, 1959, 1758, 1766, 1686, 474, 1452, - 1756, 1936, 1757, 1839, 1683, 2047, 1062, 1060, 185, 1764, - 1786, 1061, 1780, 1059, 1064, 1063, 1058, 1278, 474, 1779, - 471, 1416, 1051, 1019, 474, 474, 803, 1850, 1449, 1647, - 1808, 1765, 1275, 1532, 452, 870, 448, 940, 1627, 1674, - 591, 1811, 584, 1813, 1795, 95, 2096, 185, 2071, 186, - 2069, 2039, 1814, 930, 931, 923, 924, 925, 926, 927, - 928, 929, 922, 1817, 1988, 932, 2072, 521, 2037, 2106, - 2089, 1816, 1826, 1829, 475, 1376, 1007, 186, 1916, 186, - 186, 1801, 475, 1830, 1597, 1832, 1831, 1833, 475, 1842, - 1843, 1858, 969, 1350, 185, 185, 1034, 494, 1288, 474, - 509, 506, 507, 1838, 1387, 1639, 914, 492, 486, 1026, - 1864, 1408, 185, 1406, 1405, 1243, 1038, 184, 1824, 1853, - 469, 1854, 1820, 1032, 1391, 1537, 1742, 184, 1869, 1879, - 474, 474, 474, 566, 185, 1805, 93, 1347, 1872, 2027, - 1905, 1788, 1855, 1856, 1866, 1908, 1871, 565, 59, 36, - 578, 578, 478, 1863, 2082, 899, 574, 30, 29, 184, - 28, 23, 946, 947, 948, 949, 950, 951, 952, 953, - 954, 955, 22, 1887, 21, 1803, 20, 1889, 1884, 1885, - 19, 25, 18, 17, 1893, 16, 103, 46, 1898, 1899, - 43, 41, 921, 920, 930, 931, 923, 924, 925, 926, - 927, 928, 929, 922, 1913, 110, 932, 1647, 109, 44, - 40, 842, 1915, 27, 26, 15, 14, 13, 1920, 12, - 11, 1922, 1923, 10, 9, 1927, 1929, 5, 4, 186, - 902, 1928, 24, 958, 2, 184, 0, 0, 0, 0, - 0, 186, 474, 474, 1934, 184, 0, 0, 0, 1935, - 184, 0, 0, 1953, 0, 474, 475, 0, 474, 1939, - 0, 1941, 166, 1888, 0, 1952, 1963, 0, 0, 0, - 0, 1966, 1971, 475, 475, 0, 475, 1957, 475, 475, - 0, 475, 475, 475, 475, 475, 475, 108, 0, 0, - 0, 474, 474, 474, 185, 1969, 475, 150, 0, 0, - 186, 0, 1981, 1983, 1984, 474, 1970, 474, 0, 0, - 0, 0, 0, 474, 0, 0, 1985, 0, 1995, 1982, - 1993, 1811, 1997, 0, 2000, 1811, 0, 475, 0, 1986, - 1991, 1907, 0, 0, 0, 186, 0, 185, 0, 0, - 2007, 186, 2008, 2006, 186, 0, 0, 186, 474, 185, - 0, 147, 0, 148, 485, 0, 2014, 2017, 186, 2021, - 186, 1930, 165, 0, 1931, 1903, 0, 1933, 0, 0, - 0, 0, 475, 475, 186, 475, 475, 186, 475, 475, - 0, 2023, 2024, 2025, 2026, 0, 2030, 2036, 2031, 2032, - 2033, 2044, 2034, 2035, 1811, 0, 0, 0, 0, 0, - 474, 474, 1977, 0, 0, 0, 2051, 0, 0, 0, - 0, 0, 2056, 1966, 2058, 0, 0, 0, 0, 0, - 151, 0, 0, 0, 0, 1999, 474, 0, 2066, 0, - 156, 2001, 1647, 2075, 474, 0, 2062, 0, 0, 2078, - 0, 0, 0, 0, 0, 2081, 1902, 2085, 0, 0, - 0, 0, 475, 0, 2094, 2093, 0, 0, 0, 1990, - 485, 0, 0, 0, 0, 0, 0, 0, 2104, 0, - 0, 0, 0, 921, 920, 930, 931, 923, 924, 925, - 926, 927, 928, 929, 922, 475, 475, 932, 2100, 2101, - 0, 0, 0, 0, 0, 0, 186, 2122, 0, 0, - 0, 0, 0, 184, 0, 0, 0, 2132, 475, 0, - 0, 0, 0, 0, 0, 186, 0, 0, 475, 0, - 0, 0, 186, 0, 186, 0, 0, 0, 0, 0, - 0, 143, 186, 186, 0, 0, 0, 1890, 1891, 475, - 1892, 0, 475, 1894, 1901, 1896, 0, 0, 0, 0, - 0, 0, 0, 475, 921, 920, 930, 931, 923, 924, - 925, 926, 927, 928, 929, 922, 0, 0, 932, 920, - 930, 931, 923, 924, 925, 926, 927, 928, 929, 922, - 1293, 0, 932, 1302, 1303, 1304, 1305, 1306, 1307, 1308, - 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1900, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 475, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 184, 0, 0, 0, 0, 0, 0, 0, 0, 475, - 0, 0, 0, 0, 578, 475, 0, 0, 0, 0, - 1355, 0, 0, 0, 0, 0, 0, 1575, 184, 0, - 184, 1041, 921, 920, 930, 931, 923, 924, 925, 926, - 927, 928, 929, 922, 0, 0, 932, 921, 920, 930, - 931, 923, 924, 925, 926, 927, 928, 929, 922, 475, - 0, 932, 0, 0, 0, 144, 149, 146, 152, 153, + 550, 2129, 2116, 1878, 2043, 1749, 2093, 2056, 493, 1647, + 1989, 1718, 1967, 894, 79, 3, 1811, 1506, 1812, 522, + 1441, 1615, 1370, 1875, 561, 1648, 508, 1808, 1356, 1005, + 1476, 960, 1722, 1012, 1461, 1706, 734, 1634, 491, 1481, + 1705, 853, 142, 1823, 1770, 1420, 1575, 173, 1327, 1261, + 185, 1319, 458, 185, 1504, 1137, 792, 1248, 474, 594, + 185, 128, 757, 1698, 892, 77, 1049, 1483, 1042, 1033, + 1402, 570, 1409, 1010, 1015, 1353, 1035, 1372, 999, 495, + 1296, 1553, 741, 763, 1144, 555, 1330, 738, 474, 31, + 1032, 474, 185, 474, 1039, 484, 1484, 1385, 1227, 742, + 1472, 591, 758, 759, 1048, 1425, 1046, 1022, 564, 75, + 1129, 1155, 760, 1264, 111, 112, 770, 834, 8, 481, + 973, 105, 145, 74, 106, 7, 172, 976, 6, 1741, + 1740, 1535, 1991, 1214, 80, 1613, 1462, 1367, 1368, 2085, + 1282, 2040, 1946, 1854, 2018, 2017, 1962, 796, 795, 1963, + 2135, 2090, 2128, 735, 1488, 113, 76, 576, 580, 2067, + 2119, 578, 1879, 1523, 2089, 556, 107, 2066, 185, 82, + 83, 84, 85, 86, 87, 1486, 797, 1787, 185, 1908, + 847, 482, 483, 185, 749, 1614, 33, 794, 436, 68, + 37, 38, 1838, 1839, 588, 174, 175, 176, 1542, 1837, + 808, 809, 1541, 812, 813, 814, 815, 171, 1435, 818, + 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, + 829, 830, 831, 832, 595, 485, 751, 107, 773, 750, + 1436, 1437, 774, 1050, 535, 1051, 541, 542, 539, 540, + 462, 538, 537, 536, 752, 554, 1114, 798, 799, 800, + 166, 543, 544, 553, 1485, 811, 863, 861, 805, 1369, + 67, 1717, 102, 178, 179, 180, 1455, 1678, 872, 873, + 1677, 753, 166, 1679, 881, 108, 883, 130, 890, 174, + 175, 176, 810, 1127, 1689, 150, 1751, 1939, 461, 2069, + 1899, 1897, 102, 167, 472, 107, 1281, 108, 476, 130, + 1283, 1284, 1285, 470, 874, 1538, 1723, 150, 875, 872, + 873, 97, 1204, 880, 882, 1505, 140, 1236, 1228, 1237, + 1238, 129, 2030, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 1771, 1233, 933, 140, 147, + 2118, 148, 835, 129, 864, 862, 1131, 1132, 139, 138, + 165, 1745, 888, 1205, 2086, 1206, 889, 1752, 1746, 1754, + 869, 147, 842, 148, 1550, 462, 102, 94, 1131, 1132, + 139, 138, 165, 98, 867, 868, 99, 100, 1773, 865, + 866, 462, 817, 816, 1753, 1230, 2014, 1232, 772, 1957, + 1234, 1507, 781, 779, 1403, 790, 789, 788, 134, 1133, + 141, 787, 1130, 786, 135, 136, 1853, 785, 151, 784, + 878, 783, 778, 461, 101, 170, 1487, 754, 156, 1557, + 134, 1133, 141, 1123, 1130, 877, 135, 136, 1231, 461, + 151, 2065, 791, 1540, 1958, 1775, 185, 1779, 1426, 1774, + 156, 1772, 845, 2105, 101, 2133, 1777, 739, 462, 739, + 876, 879, 766, 737, 2136, 1776, 739, 886, 104, 474, + 474, 474, 1143, 1142, 846, 765, 746, 772, 1778, 1780, + 1616, 1618, 582, 1755, 1529, 2006, 1241, 474, 474, 856, + 857, 858, 859, 860, 782, 780, 2057, 772, 898, 801, + 1715, 772, 1537, 904, 1796, 1795, 461, 2070, 1794, 891, + 747, 1733, 69, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 1555, 772, 933, 101, 143, + 1554, 1525, 771, 435, 895, 896, 177, 1442, 775, 765, + 2031, 2047, 1549, 1928, 1555, 1548, 945, 946, 776, 1554, + 1836, 143, 1216, 1215, 1217, 1218, 1219, 1639, 1594, 933, + 1583, 1515, 1431, 1026, 185, 958, 777, 851, 174, 175, + 176, 923, 1576, 839, 933, 1674, 1617, 807, 137, 1262, + 943, 1381, 1003, 772, 911, 912, 910, 1591, 1278, 474, + 131, 870, 185, 132, 185, 185, 885, 474, 913, 1002, + 137, 2131, 913, 474, 2132, 1265, 2130, 907, 887, 2022, + 591, 771, 131, 910, 905, 132, 90, 906, 765, 768, + 769, 793, 739, 961, 2007, 2005, 762, 766, 1694, 913, + 1821, 771, 1229, 848, 849, 771, 1052, 775, 765, 1031, + 1000, 841, 765, 768, 769, 761, 739, 776, 912, 910, + 762, 766, 1016, 836, 1524, 837, 908, 840, 838, 914, + 771, 91, 855, 1789, 1014, 913, 975, 978, 980, 982, + 983, 985, 987, 988, 979, 981, 1354, 984, 986, 1354, + 989, 1601, 997, 144, 149, 146, 152, 153, 154, 155, + 157, 158, 159, 160, 1263, 485, 945, 946, 1118, 161, + 162, 163, 164, 1004, 971, 144, 149, 146, 152, 153, + 154, 155, 157, 158, 159, 160, 1522, 771, 1452, 806, + 1266, 161, 162, 163, 164, 945, 946, 174, 175, 176, + 1453, 1321, 1520, 595, 1008, 1011, 924, 925, 926, 927, + 928, 929, 930, 923, 185, 781, 933, 779, 1110, 926, + 927, 928, 929, 930, 923, 1517, 185, 933, 1119, 1120, + 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, + 2137, 474, 933, 1139, 854, 1589, 2050, 1687, 1517, 1521, + 1019, 1148, 1223, 1588, 2120, 1152, 2110, 1322, 474, 474, + 1303, 474, 1149, 474, 474, 1945, 474, 474, 474, 474, + 474, 474, 1519, 169, 1301, 1302, 1300, 1135, 911, 912, + 910, 474, 2121, 1944, 2111, 185, 1188, 1183, 1184, 1121, + 1122, 911, 912, 910, 1221, 745, 913, 1703, 1128, 1791, + 1859, 1201, 1568, 1569, 1570, 1702, 1147, 2138, 1798, 913, + 1222, 1701, 474, 67, 1386, 1387, 1491, 1185, 1211, 1224, + 185, 911, 912, 910, 1209, 1299, 185, 1208, 1207, 185, + 1247, 1199, 185, 1193, 1146, 1190, 174, 175, 176, 913, + 1681, 2123, 1116, 185, 1109, 185, 1125, 1191, 1192, 1590, + 1126, 1124, 1220, 1197, 1198, 1189, 1799, 474, 474, 185, + 474, 474, 185, 474, 474, 1145, 1145, 744, 1164, 1138, + 1157, 1047, 1158, 2122, 1160, 1162, 1210, 2112, 1166, 1168, + 1170, 1172, 1174, 1253, 2101, 1255, 2079, 1257, 1258, 1259, + 1260, 1250, 748, 1980, 1942, 911, 912, 910, 1383, 1916, + 1800, 1267, 921, 931, 932, 924, 925, 926, 927, 928, + 929, 930, 923, 913, 1320, 933, 1297, 1711, 1186, 581, + 1242, 1268, 1269, 1323, 1271, 1272, 1699, 1274, 1275, 1291, + 1293, 1294, 911, 912, 910, 1565, 1533, 474, 174, 175, + 176, 1292, 1499, 751, 107, 1532, 750, 174, 175, 176, + 913, 1497, 1331, 1251, 1212, 1342, 1345, 1200, 1196, 586, + 1382, 1355, 1195, 1194, 1324, 1325, 1748, 565, 1335, 1336, + 2012, 474, 474, 1864, 2104, 1337, 1298, 2011, 1276, 174, + 175, 176, 185, 1202, 1877, 911, 912, 910, 174, 175, + 176, 1864, 2063, 76, 474, 1725, 1332, 1252, 1333, 1864, + 2048, 185, 1714, 913, 474, 583, 584, 1376, 185, 1450, + 185, 1635, 1377, 1668, 961, 1864, 565, 1388, 185, 185, + 1331, 1426, 1361, 1362, 1820, 474, 1864, 2020, 474, 1338, + 1339, 1809, 1421, 1344, 1347, 1348, 1960, 565, 591, 474, + 1820, 591, 1517, 565, 1926, 565, 1864, 1869, 1923, 1334, + 1635, 1286, 1287, 1288, 1289, 1851, 1850, 1847, 1848, 1360, + 1847, 1846, 1363, 1364, 1400, 33, 1333, 1427, 1396, 1395, + 565, 1394, 565, 1426, 1742, 1446, 1427, 1113, 1727, 1406, + 1445, 511, 510, 513, 514, 515, 516, 1463, 1464, 1465, + 512, 909, 517, 78, 474, 1720, 1721, 551, 1406, 565, + 1518, 1449, 1496, 1498, 909, 565, 1340, 1341, 2021, 33, + 1405, 1398, 1996, 1424, 1864, 474, 1113, 1112, 1820, 1478, + 1849, 474, 1058, 1057, 33, 1148, 1429, 1148, 1428, 1406, + 1433, 1432, 1434, 1606, 1642, 1516, 1430, 1428, 1394, 67, + 2055, 1448, 1447, 1605, 1394, 1426, 1517, 186, 1500, 1384, + 186, 1503, 1365, 558, 1517, 475, 1643, 186, 1394, 1240, + 1406, 595, 1044, 756, 595, 474, 755, 1320, 67, 1969, + 1876, 1934, 1320, 1320, 1115, 1477, 1747, 1479, 1510, 1473, + 1513, 1467, 1514, 67, 1947, 475, 1474, 1475, 475, 186, + 475, 1466, 1490, 1489, 1440, 1492, 1495, 1226, 67, 1179, + 1140, 1526, 1508, 1509, 1136, 1111, 1479, 185, 1512, 92, + 1951, 185, 185, 185, 185, 185, 1708, 171, 1528, 1707, + 1527, 185, 185, 1530, 1531, 185, 773, 67, 1176, 1750, + 774, 1948, 1949, 1950, 1970, 1411, 1414, 1415, 1416, 1412, + 1145, 1413, 1417, 185, 185, 185, 1180, 1181, 1182, 1824, + 1825, 1488, 2107, 1480, 1952, 1953, 2125, 185, 1830, 2088, + 185, 474, 2117, 1708, 1842, 186, 488, 1827, 565, 1809, + 1829, 1716, 1177, 1178, 1279, 186, 1244, 1659, 1656, 1657, + 186, 1655, 1660, 1559, 1658, 1661, 1801, 1415, 1416, 1563, + 1624, 1013, 1456, 1927, 1457, 1458, 1459, 1460, 1867, 1633, + 1297, 1536, 1632, 2075, 2072, 2109, 2092, 1558, 2094, 2100, + 1468, 1469, 1470, 1471, 922, 921, 931, 932, 924, 925, + 926, 927, 928, 929, 930, 923, 1622, 2099, 933, 2044, + 1239, 2042, 1578, 552, 1623, 96, 1579, 1712, 1350, 803, + 802, 571, 1585, 1707, 897, 1735, 185, 1586, 1587, 2052, + 1006, 1734, 1351, 1593, 185, 572, 1596, 1597, 1686, 108, + 1298, 1571, 1007, 2051, 1603, 1994, 1604, 1511, 1154, 1607, + 1608, 1609, 1610, 1611, 1153, 1141, 185, 1921, 1017, 1018, + 574, 168, 573, 1379, 181, 1493, 1621, 185, 185, 185, + 185, 185, 1386, 1387, 1649, 1580, 1581, 1644, 1628, 185, + 1584, 1243, 2013, 185, 556, 1964, 185, 185, 1600, 1419, + 185, 185, 185, 559, 560, 562, 1598, 1666, 1631, 1640, + 2114, 1637, 1000, 1680, 1612, 2113, 1630, 2097, 2076, 1664, + 1665, 1620, 1920, 1863, 1501, 563, 78, 1919, 1627, 1804, + 1635, 2127, 2126, 1693, 1595, 1592, 1027, 1020, 1638, 1636, + 2127, 1669, 2045, 1940, 1380, 1671, 558, 1651, 1652, 81, + 1654, 76, 1692, 73, 1695, 1696, 1697, 1683, 1, 474, + 1662, 1250, 1690, 1691, 1667, 445, 571, 1650, 1366, 1672, + 1653, 1675, 474, 998, 457, 2115, 1213, 1203, 474, 1684, + 572, 474, 1880, 1148, 1724, 1966, 1602, 1870, 474, 1494, + 1704, 1482, 1728, 764, 133, 1443, 1444, 2059, 89, 1730, + 1739, 1700, 732, 568, 569, 574, 88, 573, 185, 767, + 884, 1502, 1710, 2004, 1625, 1626, 1011, 1961, 1688, 1738, + 1709, 1454, 1938, 186, 1841, 1685, 2049, 474, 185, 1064, + 1737, 1062, 1128, 1063, 1061, 1066, 1065, 1060, 1729, 1280, + 471, 1418, 1053, 1332, 1021, 1333, 475, 475, 475, 804, + 1852, 1736, 1451, 1277, 474, 1534, 452, 871, 448, 941, + 1320, 1629, 1676, 592, 475, 475, 585, 1767, 1815, 95, + 2098, 2073, 2071, 2041, 1990, 2074, 2039, 2108, 2091, 1764, + 1765, 1378, 1758, 1009, 1759, 1769, 1918, 1803, 1768, 1760, + 474, 1756, 1599, 970, 1352, 1036, 494, 1290, 509, 506, + 185, 1766, 1788, 507, 1389, 1782, 1641, 915, 492, 486, + 474, 1781, 1028, 1410, 1408, 1407, 474, 474, 1245, 1040, + 1826, 1649, 1810, 1767, 1822, 1034, 1393, 1539, 1744, 567, + 93, 1349, 2029, 1813, 1907, 1807, 566, 59, 36, 185, + 478, 186, 2084, 900, 1816, 575, 1411, 1414, 1415, 1416, + 1412, 30, 1413, 1417, 29, 1819, 1824, 1825, 28, 521, + 23, 22, 21, 20, 19, 1831, 475, 1828, 25, 186, + 18, 186, 186, 17, 475, 1832, 16, 1834, 103, 1835, + 475, 1844, 1845, 1860, 1833, 46, 185, 185, 43, 41, + 110, 474, 109, 44, 40, 1840, 843, 27, 26, 15, + 14, 1797, 1866, 13, 185, 12, 11, 10, 9, 184, + 5, 1855, 469, 4, 903, 24, 959, 1856, 2, 184, + 1871, 1881, 474, 474, 474, 0, 185, 1865, 1818, 0, + 0, 0, 0, 1790, 1857, 1858, 1911, 1868, 0, 1874, + 0, 0, 579, 579, 1873, 0, 0, 0, 0, 0, + 0, 184, 0, 947, 948, 949, 950, 951, 952, 953, + 954, 955, 956, 1890, 0, 1889, 0, 1805, 0, 1891, + 1886, 1887, 0, 0, 0, 0, 1895, 0, 0, 0, + 1900, 1901, 0, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 0, 1915, 933, 0, 1649, + 0, 0, 0, 0, 1917, 0, 0, 0, 1922, 0, + 0, 0, 0, 1924, 1925, 0, 1931, 1929, 0, 0, + 0, 186, 0, 1930, 0, 0, 0, 184, 0, 0, + 0, 0, 0, 186, 474, 474, 1936, 184, 0, 0, + 0, 1937, 184, 0, 0, 1955, 0, 474, 475, 0, + 474, 1941, 0, 1943, 0, 1954, 0, 0, 1965, 0, + 0, 0, 0, 1968, 1973, 475, 475, 0, 475, 1959, + 475, 475, 0, 475, 475, 475, 475, 475, 475, 0, + 0, 0, 0, 474, 474, 474, 185, 0, 475, 0, + 1971, 0, 186, 0, 1983, 1985, 1986, 474, 1972, 474, + 0, 0, 1979, 0, 0, 474, 0, 0, 1987, 0, + 1997, 1984, 1995, 1813, 1999, 0, 2002, 1813, 0, 475, + 0, 1988, 1993, 1909, 0, 2001, 0, 186, 0, 185, + 0, 2003, 2009, 186, 2010, 0, 186, 2008, 0, 186, + 474, 185, 0, 0, 0, 0, 485, 0, 2016, 2019, + 186, 2023, 186, 1932, 0, 0, 1933, 0, 0, 1935, + 0, 0, 0, 0, 475, 475, 186, 475, 475, 186, + 475, 475, 0, 2025, 2026, 2027, 2028, 0, 2032, 2038, + 2033, 2034, 2035, 2046, 2036, 2037, 1813, 0, 1892, 1893, + 0, 1894, 474, 474, 1896, 0, 1898, 0, 2053, 0, + 0, 0, 0, 0, 2058, 1968, 2060, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, + 2068, 0, 0, 0, 1649, 2077, 474, 0, 2064, 0, + 0, 2080, 0, 0, 0, 0, 0, 2083, 0, 2087, + 0, 0, 0, 0, 475, 0, 2096, 2095, 0, 0, + 0, 1992, 485, 0, 0, 0, 0, 0, 0, 0, + 0, 2106, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 174, 175, 176, 0, 0, 475, 475, + 2102, 2103, 0, 0, 0, 0, 0, 0, 2124, 186, + 0, 0, 0, 0, 0, 184, 0, 0, 0, 2134, + 0, 475, 0, 0, 0, 0, 1910, 0, 186, 0, + 0, 475, 0, 0, 0, 186, 0, 186, 0, 0, + 0, 0, 0, 0, 0, 186, 186, 0, 0, 0, + 0, 0, 475, 449, 0, 475, 0, 1905, 0, 0, + 0, 0, 450, 0, 0, 0, 475, 0, 0, 0, + 0, 0, 447, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 0, 0, 933, 0, 0, + 0, 0, 1295, 0, 0, 1304, 1305, 1306, 1307, 1308, + 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, + 0, 444, 0, 0, 0, 0, 0, 0, 0, 0, + 456, 475, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, + 0, 0, 475, 0, 0, 0, 0, 579, 475, 0, + 0, 0, 0, 0, 1357, 0, 0, 0, 0, 0, + 0, 184, 462, 184, 1043, 922, 921, 931, 932, 924, + 925, 926, 927, 928, 929, 930, 923, 0, 0, 933, + 0, 0, 0, 1904, 0, 0, 0, 0, 0, 437, + 438, 439, 475, 454, 455, 465, 1761, 0, 0, 451, + 453, 466, 440, 441, 468, 467, 0, 443, 442, 0, + 461, 446, 463, 0, 0, 0, 922, 921, 931, 932, + 924, 925, 926, 927, 928, 929, 930, 923, 0, 0, + 933, 0, 166, 0, 186, 0, 0, 0, 186, 186, + 186, 186, 186, 0, 0, 0, 0, 0, 186, 186, + 0, 0, 186, 0, 0, 166, 0, 108, 0, 0, + 0, 520, 0, 0, 0, 0, 0, 150, 0, 0, + 186, 186, 186, 0, 0, 0, 0, 0, 0, 0, + 108, 0, 0, 0, 186, 0, 0, 186, 475, 0, + 150, 922, 921, 931, 932, 924, 925, 926, 927, 928, + 929, 930, 923, 0, 0, 933, 0, 0, 1682, 0, + 0, 0, 0, 184, 0, 0, 0, 0, 0, 473, + 1001, 147, 0, 148, 0, 184, 0, 0, 0, 0, + 0, 0, 165, 0, 0, 0, 464, 1903, 0, 0, + 0, 0, 0, 459, 147, 0, 148, 0, 0, 593, + 0, 0, 736, 1151, 743, 165, 0, 0, 460, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 183, 0, 0, 186, 0, 0, 0, 0, 1151, 1151, + 477, 186, 0, 0, 184, 0, 0, 0, 0, 0, + 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 156, 0, 0, 186, 0, 0, 0, 0, 0, 0, + 0, 0, 740, 151, 186, 186, 186, 186, 186, 184, + 0, 0, 0, 156, 0, 184, 186, 0, 184, 0, + 186, 1249, 0, 186, 186, 0, 0, 186, 186, 186, + 0, 0, 184, 1577, 184, 922, 921, 931, 932, 924, + 925, 926, 927, 928, 929, 930, 923, 0, 184, 933, + 0, 184, 0, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 0, 0, 933, 1572, 1573, + 1574, 0, 0, 0, 0, 0, 0, 0, 833, 0, + 0, 0, 0, 0, 0, 0, 475, 0, 844, 0, + 0, 143, 0, 850, 0, 0, 0, 0, 0, 475, + 0, 0, 0, 0, 0, 475, 0, 0, 475, 0, + 0, 0, 0, 0, 143, 475, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 579, 1249, 0, + 0, 0, 579, 579, 0, 186, 579, 579, 579, 0, + 0, 0, 1151, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 475, 186, 0, 0, 0, 0, + 0, 0, 579, 579, 579, 579, 579, 0, 0, 0, + 0, 1374, 0, 0, 0, 0, 0, 0, 0, 0, + 1902, 475, 0, 0, 0, 0, 0, 0, 0, 0, + 184, 0, 0, 0, 0, 0, 1249, 184, 0, 184, + 0, 0, 0, 0, 0, 0, 0, 184, 184, 0, + 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, + 0, 0, 0, 475, 475, 144, 149, 146, 152, 153, 154, 155, 157, 158, 159, 160, 0, 0, 0, 0, - 0, 161, 162, 163, 164, 0, 921, 920, 930, 931, - 923, 924, 925, 926, 927, 928, 929, 922, 0, 0, - 932, 186, 0, 0, 0, 186, 186, 186, 186, 186, - 0, 0, 0, 0, 0, 186, 186, 0, 0, 186, - 0, 0, 0, 0, 0, 0, 0, 0, 520, 0, - 0, 0, 0, 0, 0, 0, 0, 186, 186, 186, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 186, 0, 0, 186, 475, 921, 920, 930, 931, - 923, 924, 925, 926, 927, 928, 929, 922, 0, 0, - 932, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 184, 0, 0, 0, 0, 0, 473, 0, 0, 0, - 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 592, 0, 0, 735, - 1149, 742, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 186, 0, 0, 0, 0, 1149, 1149, 0, 186, 0, - 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 186, 186, 186, 186, 186, 184, 0, 0, 0, - 0, 0, 184, 186, 0, 184, 0, 186, 1247, 0, - 186, 186, 0, 0, 186, 186, 186, 0, 0, 184, - 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 184, 0, 0, 184, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1079, 1570, 1571, 1572, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 999, 0, 475, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, - 0, 0, 475, 0, 0, 475, 0, 0, 0, 0, - 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 578, 1247, 0, 0, 0, 578, - 578, 183, 186, 578, 578, 578, 0, 0, 0, 1149, - 0, 477, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 475, 186, 0, 0, 0, 0, 0, 578, 578, - 578, 578, 578, 0, 0, 0, 0, 1372, 0, 0, - 0, 0, 0, 739, 0, 0, 1067, 0, 475, 0, + 0, 161, 162, 163, 164, 0, 186, 0, 144, 149, + 146, 152, 153, 154, 155, 157, 158, 159, 160, 0, + 0, 0, 0, 0, 161, 162, 163, 164, 922, 921, + 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, + 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, + 593, 593, 593, 186, 186, 0, 0, 0, 475, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 899, 901, + 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1762, 1763, 0, 852, 0, 0, 475, + 475, 475, 0, 186, 0, 0, 0, 0, 1783, 1784, + 0, 1785, 1786, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1792, 1793, 922, 921, 931, 932, 924, 925, + 926, 927, 928, 929, 930, 923, 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, - 0, 0, 1247, 184, 0, 184, 0, 0, 0, 0, - 0, 0, 0, 184, 184, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 475, 0, 0, 0, 0, 1080, - 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, - 475, 475, 0, 0, 0, 0, 0, 0, 0, 832, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 843, - 0, 0, 0, 186, 849, 1093, 1096, 1097, 1098, 1099, - 1100, 1101, 0, 1102, 1103, 1104, 1105, 1106, 1081, 1082, - 1083, 1084, 1065, 1066, 1094, 0, 1068, 0, 1069, 1070, - 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1085, 1086, - 1087, 1088, 1089, 1090, 1091, 1092, 0, 592, 592, 592, - 186, 186, 0, 0, 0, 475, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 898, 900, 0, 186, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1760, 1761, 0, 0, 0, 0, 475, 475, 475, 0, - 186, 0, 0, 0, 0, 1781, 1782, 0, 1783, 1784, - 0, 0, 0, 0, 0, 0, 1095, 0, 0, 1790, - 1791, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 184, 0, 0, 0, 184, 184, 184, 184, - 184, 0, 0, 0, 0, 0, 184, 184, 0, 0, - 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1022, 0, 1558, 1559, - 184, 0, 0, 0, 592, 0, 0, 0, 0, 0, - 1052, 0, 184, 0, 0, 184, 0, 0, 0, 0, - 1841, 0, 0, 0, 0, 0, 0, 0, 475, 475, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 475, 0, 0, 475, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 578, 578, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 475, 475, 475, - 186, 523, 32, 0, 0, 578, 0, 851, 0, 0, - 0, 475, 0, 475, 0, 1886, 0, 0, 0, 475, - 0, 184, 0, 0, 0, 0, 0, 0, 0, 1372, - 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, - 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, - 578, 184, 0, 0, 475, 186, 0, 0, 0, 0, - 0, 1149, 184, 184, 184, 184, 184, 0, 0, 0, - 0, 0, 0, 0, 1661, 0, 0, 556, 184, 0, - 0, 184, 184, 0, 0, 184, 1671, 1247, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 735, 0, - 0, 0, 0, 0, 0, 0, 475, 475, 0, 0, - 0, 1148, 0, 0, 0, 1154, 1154, 0, 1154, 0, - 1154, 1154, 0, 1163, 1154, 1154, 1154, 1154, 1154, 0, - 0, 0, 475, 0, 0, 0, 1148, 1148, 735, 0, - 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1028, 0, 0, 1039, 1972, 1973, 1974, 1975, - 1976, 1149, 0, 0, 1979, 1980, 0, 0, 0, 1223, - 0, 1247, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 184, 592, 592, 0, 592, 592, 0, - 592, 592, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 578, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 166, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1715, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 108, 0, 130, 0, 0, 0, - 0, 0, 0, 0, 150, 184, 0, 0, 0, 0, - 0, 0, 0, 0, 1324, 0, 592, 0, 1149, 0, - 0, 0, 0, 0, 1057, 0, 0, 0, 2079, 0, - 1148, 0, 0, 0, 0, 140, 1115, 0, 0, 0, - 129, 0, 0, 0, 184, 0, 0, 1356, 1357, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 147, 0, - 148, 0, 0, 0, 0, 1129, 1130, 139, 138, 165, - 1388, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1022, 0, 0, 592, 0, 0, 0, 0, 0, 0, - 0, 184, 184, 0, 0, 1185, 0, 0, 0, 1149, - 0, 592, 0, 0, 592, 0, 0, 0, 0, 184, - 0, 0, 0, 0, 0, 735, 0, 134, 1131, 141, - 0, 1128, 0, 135, 136, 0, 0, 151, 0, 0, - 1233, 184, 0, 0, 0, 0, 1039, 156, 0, 1244, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1252, 0, 1254, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1268, - 742, 0, 1271, 0, 0, 0, 0, 0, 0, 0, - 892, 892, 892, 0, 0, 0, 0, 0, 0, 0, - 0, 735, 0, 0, 0, 0, 1149, 742, 0, 0, - 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 941, 943, 0, 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, 735, 956, 0, 0, 0, 961, 962, 963, 964, - 965, 966, 967, 968, 0, 971, 974, 974, 974, 980, - 974, 974, 980, 974, 988, 989, 990, 991, 992, 993, - 994, 0, 0, 0, 0, 0, 0, 0, 32, 0, - 0, 166, 0, 0, 0, 0, 0, 137, 0, 0, - 0, 1372, 0, 0, 0, 0, 0, 0, 0, 131, - 0, 0, 132, 0, 1035, 0, 108, 0, 130, 0, - 1395, 0, 0, 0, 0, 0, 150, 1399, 0, 1402, - 0, 0, 0, 0, 0, 0, 0, 0, 1421, 0, - 0, 0, 0, 0, 184, 0, 0, 1565, 0, 0, - 0, 0, 0, 0, 0, 0, 184, 140, 0, 0, - 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 147, 0, 148, 0, 0, 0, 0, 117, 118, 139, - 138, 165, 0, 0, 0, 0, 0, 0, 0, 0, + 184, 184, 184, 184, 184, 0, 0, 0, 0, 0, + 184, 184, 0, 0, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1024, 0, 1560, 1561, 184, 0, 0, 0, 593, 0, + 0, 0, 0, 0, 1054, 0, 184, 0, 0, 184, + 0, 0, 0, 1843, 0, 0, 0, 0, 0, 0, + 0, 475, 475, 0, 0, 0, 0, 0, 523, 32, + 0, 0, 0, 0, 475, 0, 0, 475, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1030, 0, 0, 1041, 0, 0, 579, 579, + 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 475, 475, 475, 186, 0, 0, 0, 0, 0, 579, + 0, 0, 0, 0, 475, 0, 475, 0, 1888, 0, + 0, 0, 475, 0, 0, 184, 0, 0, 0, 0, + 0, 0, 0, 1374, 557, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, + 0, 0, 0, 0, 579, 184, 0, 475, 186, 0, + 0, 0, 0, 0, 0, 1151, 184, 184, 184, 184, + 184, 0, 0, 0, 0, 0, 0, 0, 1663, 0, + 0, 0, 184, 0, 0, 184, 184, 0, 0, 184, + 1673, 1249, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 736, 0, 0, 0, 0, 0, 0, 475, + 475, 0, 0, 0, 0, 1150, 0, 0, 0, 1156, + 1156, 0, 1156, 0, 1156, 1156, 0, 1165, 1156, 1156, + 1156, 1156, 1156, 0, 1059, 475, 0, 0, 0, 0, + 1150, 1150, 736, 475, 0, 0, 1117, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1974, + 1975, 1976, 1977, 1978, 0, 1151, 0, 1981, 1982, 0, + 0, 0, 0, 1225, 0, 1249, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, + 0, 0, 0, 0, 0, 1187, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 184, 593, 593, + 0, 593, 593, 0, 593, 593, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1235, 0, 579, 0, 0, 0, 1041, 0, 0, 1246, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1254, 0, 1256, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1270, + 0, 0, 1273, 0, 0, 0, 0, 0, 0, 184, + 0, 0, 0, 0, 0, 0, 0, 0, 1326, 0, + 593, 0, 1151, 0, 0, 0, 0, 0, 0, 0, + 0, 2081, 0, 0, 1150, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, + 0, 0, 1358, 1359, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1390, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1024, 0, 0, 593, 166, + 0, 0, 0, 0, 0, 184, 184, 0, 0, 0, + 0, 0, 0, 1151, 0, 0, 593, 0, 0, 593, + 0, 0, 0, 184, 108, 0, 130, 0, 0, 0, + 736, 0, 0, 0, 150, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 184, 0, 893, 893, 893, + 0, 1397, 0, 0, 0, 0, 0, 0, 1401, 0, + 1404, 0, 0, 0, 0, 140, 0, 32, 0, 1423, + 129, 0, 0, 0, 0, 0, 0, 0, 942, 944, + 0, 0, 0, 0, 0, 743, 0, 0, 147, 0, + 148, 0, 0, 0, 0, 117, 118, 139, 138, 165, + 0, 0, 0, 0, 0, 0, 736, 0, 0, 957, + 1151, 0, 743, 962, 963, 964, 965, 966, 967, 968, + 969, 0, 972, 974, 977, 977, 977, 974, 977, 977, + 974, 977, 990, 991, 992, 993, 994, 995, 996, 0, + 0, 0, 0, 0, 0, 0, 32, 134, 115, 141, + 122, 114, 0, 135, 136, 0, 736, 151, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 156, 123, 0, + 0, 0, 1037, 0, 0, 0, 0, 0, 1081, 0, + 0, 0, 126, 124, 119, 120, 121, 125, 0, 0, + 0, 0, 116, 0, 0, 0, 0, 0, 917, 0, + 920, 127, 0, 0, 0, 1374, 934, 935, 936, 937, + 938, 939, 940, 0, 918, 919, 916, 922, 921, 931, + 932, 924, 925, 926, 927, 928, 929, 930, 923, 0, + 0, 933, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, + 0, 0, 1567, 0, 0, 0, 0, 1041, 0, 0, + 184, 1543, 1544, 1545, 1546, 1547, 0, 0, 143, 0, + 0, 1551, 1552, 0, 0, 1556, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1069, 0, 0, 0, 0, 1562, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1564, 0, 0, + 1566, 0, 0, 0, 0, 0, 0, 137, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, + 0, 0, 132, 1082, 0, 1151, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1150, 0, 1095, + 1098, 1099, 1100, 1101, 1102, 1103, 0, 1104, 1105, 1106, + 1107, 1108, 1083, 1084, 1085, 1086, 1067, 1068, 1096, 0, + 1070, 0, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, + 1079, 1080, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 0, 0, 144, 149, 146, 152, 153, 154, 155, 157, 158, 159, 160, 0, 0, 0, 0, 0, 161, 162, 163, 164, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1149, 0, 0, 0, 0, 0, 0, 0, 134, - 115, 141, 122, 114, 0, 135, 136, 0, 0, 151, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, - 123, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1148, 0, 126, 124, 119, 120, 121, 125, - 0, 0, 0, 0, 116, 0, 0, 0, 0, 0, - 0, 0, 0, 127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1670, 0, 0, + 1713, 0, 0, 0, 0, 893, 893, 0, 893, 893, + 0, 893, 893, 1719, 0, 0, 0, 1150, 0, 1726, + 1097, 0, 1719, 0, 0, 0, 0, 593, 0, 1731, + 33, 34, 35, 68, 37, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 72, 0, 0, 0, 0, 39, 65, 66, 0, 63, + 0, 0, 0, 0, 0, 64, 0, 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1039, 0, 0, 0, - 1541, 1542, 1543, 1544, 1545, 0, 0, 0, 0, 0, - 1549, 1550, 0, 0, 1554, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1711, 0, 0, 0, 0, - 143, 0, 0, 0, 1560, 0, 0, 0, 1717, 0, - 0, 0, 1148, 0, 1724, 0, 1562, 1717, 0, 1564, - 0, 0, 592, 0, 1729, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 892, 892, 137, - 892, 892, 0, 892, 892, 0, 0, 0, 0, 0, - 0, 131, 0, 592, 132, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 52, 593, 0, 0, 0, 0, + 0, 0, 0, 0, 67, 0, 0, 0, 1743, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1757, 0, + 0, 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 592, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 593, 0, 0, 1150, 0, 0, 1817, 1156, 0, + 0, 0, 0, 0, 0, 0, 1422, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 42, 45, 48, 47, + 50, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1802, 0, 0, 0, 0, 0, 0, 51, 71, 70, + 0, 0, 60, 61, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1154, 0, 0, 0, + 0, 0, 736, 0, 0, 1150, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 53, 54, + 0, 55, 56, 57, 58, 0, 0, 0, 0, 0, + 0, 0, 0, 1882, 1883, 1884, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 592, 0, 0, 1148, - 0, 0, 1815, 1154, 144, 149, 146, 152, 153, 154, - 155, 157, 158, 159, 160, 0, 1668, 0, 0, 0, - 161, 162, 163, 164, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 166, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1125, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1420, 0, 108, - 0, 130, 0, 0, 0, 0, 0, 0, 0, 150, - 0, 0, 0, 0, 0, 0, 0, 735, 0, 0, - 1148, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1861, 1862, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 140, 0, 0, 0, 0, 129, 0, 0, 1880, 1881, - 1882, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 147, 0, 148, 0, 1741, 0, 0, - 1129, 1130, 139, 138, 165, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1755, 0, 0, + 0, 0, 0, 0, 1872, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1885, 0, 0, 0, + 0, 0, 1150, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1148, 0, 0, - 0, 0, 134, 1131, 141, 0, 1128, 0, 135, 136, - 0, 0, 151, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 156, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1800, - 1717, 1954, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1717, 0, 0, 592, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1719, 1956, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1719, 0, + 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1717, - 1717, 1717, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1996, 0, 1998, 0, 0, 0, 0, - 0, 1717, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 143, 0, 1859, 1860, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1870, 0, 0, 1717, 0, 0, 0, + 0, 0, 0, 0, 1719, 1719, 1719, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1998, 0, + 2000, 0, 0, 0, 0, 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1883, 0, 0, 0, 0, - 0, 1580, 137, 0, 556, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 131, 0, 0, 132, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 592, 592, + 1582, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1617, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1148, 0, 2076, 0, 0, 0, 0, 0, - 0, 0, 1717, 0, 0, 1035, 0, 0, 0, 0, - 0, 0, 1643, 1644, 0, 0, 1035, 1035, 1035, 1035, - 1035, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1420, 0, 0, 1035, 0, 0, 0, 1035, - 0, 0, 0, 0, 0, 0, 0, 144, 149, 146, - 152, 153, 154, 155, 157, 158, 159, 160, 0, 0, - 0, 0, 0, 161, 162, 163, 164, 0, 0, 0, + 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1619, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1037, 0, 0, 0, 0, 2015, + 0, 1645, 1646, 593, 593, 1037, 1037, 1037, 1037, 1037, + 0, 2024, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1422, 0, 0, 1037, 0, 0, 1150, 1037, 2078, + 0, 0, 0, 0, 0, 0, 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1730, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2013, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2022, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 892, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1732, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 893, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1812, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1814, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1037, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1904, 0, 0, - 0, 0, 0, 0, 1910, 1911, 1912, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1912, 1913, 1914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1812, 0, 32, 0, 1812, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1812, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 713, 700, 32, 2052, 651, 716, 622, 640, 725, - 642, 645, 683, 603, 664, 321, 637, 0, 626, 599, - 633, 600, 624, 653, 237, 657, 621, 702, 667, 715, - 280, 0, 627, 334, 685, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 722, - 284, 674, 0, 379, 306, 0, 0, 0, 655, 705, - 662, 696, 650, 684, 611, 673, 717, 638, 681, 718, - 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, - 175, 176, 0, 2059, 2060, 0, 0, 0, 0, 0, - 213, 0, 219, 678, 712, 635, 680, 233, 268, 239, - 232, 394, 682, 728, 598, 675, 0, 601, 604, 724, - 708, 630, 631, 0, 0, 0, 0, 0, 0, 0, - 654, 663, 693, 648, 0, 0, 0, 0, 0, 0, - 0, 0, 628, 0, 672, 0, 0, 0, 607, 602, - 0, 0, 0, 0, 652, 0, 0, 0, 610, 0, - 629, 694, 0, 596, 256, 605, 307, 698, 707, 649, - 421, 711, 647, 646, 714, 689, 608, 704, 641, 279, - 606, 276, 188, 202, 0, 639, 317, 355, 360, 703, - 625, 634, 224, 632, 358, 330, 409, 209, 247, 352, - 335, 356, 671, 687, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 620, 699, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 691, 727, 329, 359, 215, 411, 378, 615, 619, - 613, 614, 665, 666, 616, 719, 720, 721, 695, 609, - 0, 617, 618, 0, 701, 709, 710, 670, 187, 200, - 282, 723, 349, 250, 432, 416, 414, 597, 612, 230, - 623, 0, 0, 636, 643, 644, 656, 658, 659, 660, - 661, 669, 676, 677, 679, 686, 688, 690, 692, 697, - 706, 726, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, - 425, 0, 290, 668, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 713, 700, 0, - 0, 651, 716, 622, 640, 725, 642, 645, 683, 603, - 664, 321, 637, 0, 626, 599, 633, 600, 624, 653, - 237, 657, 621, 702, 667, 715, 280, 0, 627, 334, - 685, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 722, 284, 674, 0, 379, - 306, 0, 0, 0, 655, 705, 662, 696, 650, 684, - 611, 673, 717, 638, 681, 718, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, - 0, 0, 0, 0, 0, 0, 213, 0, 219, 678, - 712, 635, 680, 233, 268, 239, 232, 394, 682, 728, - 598, 675, 0, 601, 604, 724, 708, 630, 631, 0, - 0, 0, 0, 0, 0, 0, 654, 663, 693, 648, - 0, 0, 0, 0, 0, 0, 1804, 0, 628, 0, - 672, 0, 0, 0, 607, 602, 0, 0, 0, 0, - 652, 0, 0, 0, 610, 0, 629, 694, 0, 596, - 256, 605, 307, 698, 707, 649, 421, 711, 647, 646, - 714, 689, 608, 704, 641, 279, 606, 276, 188, 202, - 0, 639, 317, 355, 360, 703, 625, 634, 224, 632, - 358, 330, 409, 209, 247, 352, 335, 356, 671, 687, - 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, - 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, - 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, - 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, - 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, - 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, - 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, - 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, - 434, 211, 620, 699, 393, 427, 430, 0, 348, 212, - 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, - 259, 312, 206, 264, 377, 277, 286, 691, 727, 329, - 359, 215, 411, 378, 615, 619, 613, 614, 665, 666, - 616, 719, 720, 721, 695, 609, 0, 617, 618, 0, - 701, 709, 710, 670, 187, 200, 282, 723, 349, 250, - 432, 416, 414, 597, 612, 230, 623, 0, 0, 636, - 643, 644, 656, 658, 659, 660, 661, 669, 676, 677, - 679, 686, 688, 690, 692, 697, 706, 726, 189, 190, - 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, - 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, - 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, - 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, - 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, - 400, 410, 420, 424, 258, 407, 425, 0, 290, 668, - 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, - 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 713, 700, 0, 0, 651, 716, 622, - 640, 725, 642, 645, 683, 603, 664, 321, 637, 0, - 626, 599, 633, 600, 624, 653, 237, 657, 621, 702, - 667, 715, 280, 0, 627, 334, 685, 370, 223, 289, - 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, - 326, 722, 284, 674, 0, 379, 306, 0, 0, 0, - 655, 705, 662, 696, 650, 684, 611, 673, 717, 638, - 681, 718, 270, 221, 192, 318, 380, 249, 67, 0, - 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, - 0, 0, 213, 0, 219, 678, 712, 635, 680, 233, - 268, 239, 232, 394, 682, 728, 598, 675, 0, 601, - 604, 724, 708, 630, 631, 0, 0, 0, 0, 0, - 0, 0, 654, 663, 693, 648, 0, 0, 0, 0, - 0, 0, 0, 0, 628, 0, 672, 0, 0, 0, - 607, 602, 0, 0, 0, 0, 652, 0, 0, 0, - 610, 0, 629, 694, 0, 596, 256, 605, 307, 698, - 707, 649, 421, 711, 647, 646, 714, 689, 608, 704, - 641, 279, 606, 276, 188, 202, 0, 639, 317, 355, - 360, 703, 625, 634, 224, 632, 358, 330, 409, 209, - 247, 352, 335, 356, 671, 687, 357, 285, 398, 347, - 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, - 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, - 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, - 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, - 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, - 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, - 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, - 310, 0, 193, 0, 381, 413, 434, 211, 620, 699, - 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, - 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, - 377, 277, 286, 691, 727, 329, 359, 215, 411, 378, - 615, 619, 613, 614, 665, 666, 616, 719, 720, 721, - 695, 609, 0, 617, 618, 0, 701, 709, 710, 670, - 187, 200, 282, 723, 349, 250, 432, 416, 414, 597, - 612, 230, 623, 0, 0, 636, 643, 644, 656, 658, - 659, 660, 661, 669, 676, 677, 679, 686, 688, 690, - 692, 697, 706, 726, 189, 190, 201, 208, 217, 229, - 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, - 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, - 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 668, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 713, - 700, 0, 0, 651, 716, 622, 640, 725, 642, 645, - 683, 603, 664, 321, 637, 0, 626, 599, 633, 600, - 624, 653, 237, 657, 621, 702, 667, 715, 280, 0, - 627, 334, 685, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 722, 284, 674, - 0, 379, 306, 0, 0, 0, 655, 705, 662, 696, - 650, 684, 611, 673, 717, 638, 681, 718, 270, 221, - 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, - 219, 678, 712, 635, 680, 233, 268, 239, 232, 394, - 682, 728, 598, 675, 0, 601, 604, 724, 708, 630, - 631, 0, 0, 0, 0, 0, 0, 0, 654, 663, - 693, 648, 0, 0, 0, 0, 0, 0, 1672, 0, - 628, 0, 672, 0, 0, 0, 607, 602, 0, 0, - 0, 0, 652, 0, 0, 0, 610, 0, 629, 694, - 0, 596, 256, 605, 307, 698, 707, 649, 421, 711, - 647, 646, 714, 689, 608, 704, 641, 279, 606, 276, - 188, 202, 0, 639, 317, 355, 360, 703, 625, 634, - 224, 632, 358, 330, 409, 209, 247, 352, 335, 356, - 671, 687, 357, 285, 398, 347, 408, 422, 423, 231, - 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, - 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, - 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, - 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, - 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, - 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, - 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, - 381, 413, 434, 211, 620, 699, 393, 427, 430, 0, - 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, - 210, 342, 259, 312, 206, 264, 377, 277, 286, 691, - 727, 329, 359, 215, 411, 378, 615, 619, 613, 614, - 665, 666, 616, 719, 720, 721, 695, 609, 0, 617, - 618, 0, 701, 709, 710, 670, 187, 200, 282, 723, - 349, 250, 432, 416, 414, 597, 612, 230, 623, 0, - 0, 636, 643, 644, 656, 658, 659, 660, 661, 669, - 676, 677, 679, 686, 688, 690, 692, 697, 706, 726, - 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, - 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, - 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, - 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, - 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, - 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, - 290, 668, 194, 220, 207, 227, 241, 243, 271, 299, - 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 713, 700, 0, 0, 651, - 716, 622, 640, 725, 642, 645, 683, 603, 664, 321, - 637, 0, 626, 599, 633, 600, 624, 653, 237, 657, - 621, 702, 667, 715, 280, 0, 627, 334, 685, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 722, 284, 674, 0, 379, 306, 0, - 0, 0, 655, 705, 662, 696, 650, 684, 611, 673, - 717, 638, 681, 718, 270, 221, 192, 318, 380, 249, - 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 678, 712, 635, - 680, 233, 268, 239, 232, 394, 682, 728, 598, 675, - 0, 601, 604, 724, 708, 630, 631, 0, 0, 0, - 0, 0, 0, 0, 654, 663, 693, 648, 0, 0, - 0, 0, 0, 0, 1397, 0, 628, 0, 672, 0, - 0, 0, 607, 602, 0, 0, 0, 0, 652, 0, - 0, 0, 610, 0, 629, 694, 0, 596, 256, 605, - 307, 698, 707, 649, 421, 711, 647, 646, 714, 689, - 608, 704, 641, 279, 606, 276, 188, 202, 0, 639, - 317, 355, 360, 703, 625, 634, 224, 632, 358, 330, - 409, 209, 247, 352, 335, 356, 671, 687, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 620, 699, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 691, 727, 329, 359, 215, - 411, 378, 615, 619, 613, 614, 665, 666, 616, 719, - 720, 721, 695, 609, 0, 617, 618, 0, 701, 709, - 710, 670, 187, 200, 282, 723, 349, 250, 432, 416, - 414, 597, 612, 230, 623, 0, 0, 636, 643, 644, - 656, 658, 659, 660, 661, 669, 676, 677, 679, 686, - 688, 690, 692, 697, 706, 726, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 668, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 713, 700, 0, 0, 651, 716, 622, 640, 725, - 642, 645, 683, 603, 664, 321, 637, 0, 626, 599, - 633, 600, 624, 653, 237, 657, 621, 702, 667, 715, - 280, 0, 627, 334, 685, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 722, - 284, 674, 0, 379, 306, 0, 0, 0, 655, 705, - 662, 696, 650, 684, 611, 673, 717, 638, 681, 718, - 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, - 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, - 213, 0, 219, 678, 712, 635, 680, 233, 268, 239, - 232, 394, 682, 728, 598, 675, 0, 601, 604, 724, - 708, 630, 631, 0, 0, 0, 0, 0, 0, 0, - 654, 663, 693, 648, 0, 0, 0, 0, 0, 0, - 0, 0, 628, 0, 672, 0, 0, 0, 607, 602, - 0, 0, 0, 0, 652, 0, 0, 0, 610, 0, - 629, 694, 0, 596, 256, 605, 307, 698, 707, 649, - 421, 711, 647, 646, 714, 689, 608, 704, 641, 279, - 606, 276, 188, 202, 0, 639, 317, 355, 360, 703, - 625, 634, 224, 632, 358, 330, 409, 209, 247, 352, - 335, 356, 671, 687, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 620, 699, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 691, 727, 329, 359, 215, 411, 378, 615, 619, - 613, 614, 665, 666, 616, 719, 720, 721, 695, 609, - 0, 617, 618, 0, 701, 709, 710, 670, 187, 200, - 282, 723, 349, 250, 432, 416, 414, 597, 612, 230, - 623, 0, 0, 636, 643, 644, 656, 658, 659, 660, - 661, 669, 676, 677, 679, 686, 688, 690, 692, 697, - 706, 726, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, - 425, 0, 290, 668, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 713, 700, 0, - 0, 651, 716, 622, 640, 725, 642, 645, 683, 603, - 664, 321, 637, 0, 626, 599, 633, 600, 624, 653, - 237, 657, 621, 702, 667, 715, 280, 0, 627, 334, - 685, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 722, 284, 674, 0, 379, - 306, 0, 0, 0, 655, 705, 662, 696, 650, 684, - 611, 673, 717, 638, 681, 718, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, - 0, 0, 0, 0, 0, 0, 213, 0, 219, 678, - 712, 635, 680, 233, 268, 239, 232, 394, 682, 728, - 598, 675, 0, 601, 604, 724, 708, 630, 631, 0, - 0, 0, 0, 0, 0, 0, 654, 663, 693, 648, - 0, 0, 0, 0, 0, 0, 0, 0, 628, 0, - 672, 0, 0, 0, 607, 602, 0, 0, 0, 0, - 652, 0, 0, 0, 610, 0, 629, 694, 0, 596, - 256, 605, 307, 698, 707, 649, 421, 711, 647, 646, - 714, 689, 608, 704, 641, 279, 606, 276, 188, 202, - 0, 639, 317, 355, 360, 703, 625, 634, 224, 632, - 358, 330, 409, 209, 247, 352, 335, 356, 671, 687, - 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, - 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, - 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, - 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, - 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, - 433, 204, 418, 199, 730, 417, 313, 397, 405, 302, - 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, - 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, - 434, 211, 620, 699, 393, 427, 430, 0, 348, 212, - 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, - 259, 595, 729, 589, 588, 277, 286, 691, 727, 329, - 359, 215, 411, 378, 615, 619, 613, 614, 665, 666, - 616, 719, 720, 721, 695, 609, 0, 617, 618, 0, - 701, 709, 710, 670, 187, 200, 282, 723, 349, 250, - 432, 416, 414, 597, 612, 230, 623, 0, 0, 636, - 643, 644, 656, 658, 659, 660, 661, 669, 676, 677, - 679, 686, 688, 690, 692, 697, 706, 726, 189, 190, - 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, - 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, - 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, - 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, - 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, - 400, 410, 420, 424, 258, 407, 425, 0, 290, 668, - 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, - 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 713, 700, 0, 0, 651, 716, 622, - 640, 725, 642, 645, 683, 603, 664, 321, 637, 0, - 626, 599, 633, 600, 624, 653, 237, 657, 621, 702, - 667, 715, 280, 0, 627, 334, 685, 370, 223, 289, - 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, - 326, 722, 284, 674, 0, 379, 306, 0, 0, 0, - 655, 705, 662, 696, 650, 684, 611, 673, 717, 638, - 681, 718, 270, 221, 192, 318, 380, 249, 0, 0, - 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, - 0, 0, 213, 0, 219, 678, 712, 635, 680, 233, - 268, 239, 232, 394, 682, 728, 598, 675, 0, 601, - 604, 724, 708, 630, 631, 0, 0, 0, 0, 0, - 0, 0, 654, 663, 693, 648, 0, 0, 0, 0, - 0, 0, 0, 0, 628, 0, 672, 0, 0, 0, - 607, 602, 0, 0, 0, 0, 652, 0, 0, 0, - 610, 0, 629, 694, 0, 596, 256, 605, 307, 698, - 707, 649, 421, 711, 647, 646, 714, 689, 608, 704, - 641, 279, 606, 276, 188, 202, 0, 639, 317, 355, - 360, 703, 625, 634, 224, 632, 358, 330, 409, 209, - 247, 352, 335, 356, 671, 687, 357, 285, 398, 347, - 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, - 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, - 191, 283, 195, 386, 1043, 214, 368, 0, 0, 0, - 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, - 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, - 730, 417, 313, 397, 405, 302, 293, 198, 403, 300, - 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, - 310, 0, 193, 0, 381, 413, 434, 211, 620, 699, - 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, - 281, 426, 428, 429, 210, 342, 259, 595, 729, 589, - 588, 277, 286, 691, 727, 329, 359, 215, 411, 378, - 615, 619, 613, 614, 665, 666, 616, 719, 720, 721, - 695, 609, 0, 617, 618, 0, 701, 709, 710, 670, - 187, 200, 282, 723, 349, 250, 432, 416, 414, 597, - 612, 230, 623, 0, 0, 636, 643, 644, 656, 658, - 659, 660, 661, 669, 676, 677, 679, 686, 688, 690, - 692, 697, 706, 726, 189, 190, 201, 208, 217, 229, - 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, - 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, - 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 668, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 713, - 700, 0, 0, 651, 716, 622, 640, 725, 642, 645, - 683, 603, 664, 321, 637, 0, 626, 599, 633, 600, - 624, 653, 237, 657, 621, 702, 667, 715, 280, 0, - 627, 334, 685, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 722, 284, 674, - 0, 379, 306, 0, 0, 0, 655, 705, 662, 696, - 650, 684, 611, 673, 717, 638, 681, 718, 270, 221, - 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, - 219, 678, 712, 635, 680, 233, 268, 239, 232, 394, - 682, 728, 598, 675, 0, 601, 604, 724, 708, 630, - 631, 0, 0, 0, 0, 0, 0, 0, 654, 663, - 693, 648, 0, 0, 0, 0, 0, 0, 0, 0, - 628, 0, 672, 0, 0, 0, 607, 602, 0, 0, - 0, 0, 652, 0, 0, 0, 610, 0, 629, 694, - 0, 596, 256, 605, 307, 698, 707, 649, 421, 711, - 647, 646, 714, 689, 608, 704, 641, 279, 606, 276, - 188, 202, 0, 639, 317, 355, 360, 703, 625, 634, - 224, 632, 358, 330, 409, 209, 247, 352, 335, 356, - 671, 687, 357, 285, 398, 347, 408, 422, 423, 231, - 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, - 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, - 586, 214, 368, 0, 0, 0, 197, 404, 383, 301, - 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, - 402, 225, 433, 204, 418, 199, 730, 417, 313, 397, - 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, - 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, - 381, 413, 434, 211, 620, 699, 393, 427, 430, 0, - 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, - 210, 342, 259, 595, 729, 589, 588, 277, 286, 691, - 727, 329, 359, 215, 411, 378, 615, 619, 613, 614, - 665, 666, 616, 719, 720, 721, 695, 609, 0, 617, - 618, 0, 701, 709, 710, 670, 187, 200, 282, 723, - 349, 250, 432, 416, 414, 597, 612, 230, 623, 0, - 0, 636, 643, 644, 656, 658, 659, 660, 661, 669, - 676, 677, 679, 686, 688, 690, 692, 697, 706, 726, - 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, - 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, - 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, - 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, - 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, - 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, - 290, 668, 194, 220, 207, 227, 241, 243, 271, 299, - 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 321, 0, 0, 1326, 0, - 490, 0, 0, 0, 237, 0, 489, 0, 0, 0, - 280, 0, 1327, 334, 0, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, - 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, - 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 67, 0, 0, 174, - 175, 176, 511, 510, 513, 514, 515, 516, 0, 0, - 213, 512, 219, 517, 518, 519, 0, 233, 268, 239, - 232, 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, - 576, 0, 0, 0, 547, 0, 503, 0, 0, 496, - 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 256, 0, 307, 546, 0, 0, - 421, 0, 0, 544, 0, 0, 0, 0, 0, 279, - 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, - 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, - 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 0, 0, 329, 359, 215, 411, 378, 534, 545, - 540, 541, 538, 539, 0, 537, 536, 535, 548, 526, - 527, 528, 529, 531, 0, 542, 543, 530, 187, 200, - 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, + 0, 0, 1814, 0, 32, 0, 1814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, - 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, - 0, 0, 490, 0, 0, 0, 237, 0, 489, 0, - 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, - 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, - 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, - 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, - 1436, 0, 270, 221, 192, 318, 380, 249, 67, 0, - 0, 174, 175, 176, 511, 510, 513, 514, 515, 516, - 0, 0, 213, 512, 219, 517, 518, 519, 1437, 233, - 268, 239, 232, 394, 0, 0, 0, 487, 504, 0, - 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 501, 502, 0, 0, 0, 0, 547, 0, 503, 0, - 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 256, 0, 307, 546, - 0, 0, 421, 0, 0, 544, 0, 0, 0, 0, - 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, - 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, - 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, - 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, - 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, - 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, - 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, - 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, - 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, - 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, - 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, - 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, - 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, - 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, - 534, 545, 540, 541, 538, 539, 0, 537, 536, 535, - 548, 526, 527, 528, 529, 531, 0, 542, 543, 530, - 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, - 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, - 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, - 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, - 0, 0, 0, 0, 490, 0, 0, 0, 237, 0, - 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, - 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 67, 0, 564, 174, 175, 176, 511, 510, 513, 514, - 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 487, - 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 501, 502, 0, 0, 0, 0, 547, 0, - 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 546, 0, 0, 421, 0, 0, 544, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 534, 545, 540, 541, 538, 539, 0, 537, - 536, 535, 548, 526, 527, 528, 529, 531, 0, 542, - 543, 530, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 0, 490, 0, 0, 0, - 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, - 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, - 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, - 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 67, 0, 0, 174, 175, 176, 511, 510, - 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, - 518, 519, 0, 233, 268, 239, 232, 394, 0, 0, - 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 501, 502, 576, 0, 0, 0, - 547, 0, 503, 0, 0, 496, 497, 499, 498, 500, - 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 256, 0, 307, 546, 0, 0, 421, 0, 0, 544, - 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, - 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, - 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, - 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, - 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, - 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, - 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, - 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, - 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, - 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, - 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, - 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, - 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, - 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, - 359, 215, 411, 378, 534, 545, 540, 541, 538, 539, - 0, 537, 536, 535, 548, 526, 527, 528, 529, 531, - 0, 542, 543, 530, 187, 200, 282, 0, 349, 250, - 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, - 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, - 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, - 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, - 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, - 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, - 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, - 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, - 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 0, 0, 0, 490, 0, - 0, 0, 237, 0, 489, 0, 0, 0, 280, 0, - 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, - 0, 379, 306, 0, 0, 0, 0, 0, 524, 525, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, - 192, 318, 380, 249, 67, 0, 0, 174, 175, 176, - 511, 1344, 513, 514, 515, 516, 0, 0, 213, 512, - 219, 517, 518, 519, 0, 233, 268, 239, 232, 394, - 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 501, 502, 576, 0, - 0, 0, 547, 0, 503, 0, 0, 496, 497, 499, - 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 256, 0, 307, 546, 0, 0, 421, 0, - 0, 544, 0, 0, 0, 0, 0, 279, 0, 276, - 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, - 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, - 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, - 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, - 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, - 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, - 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, - 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, - 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, - 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, - 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, - 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, - 0, 329, 359, 215, 411, 378, 534, 545, 540, 541, - 538, 539, 0, 537, 536, 535, 548, 526, 527, 528, - 529, 531, 0, 542, 543, 530, 187, 200, 282, 0, - 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, - 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, - 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, - 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, - 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, - 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, - 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, - 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, - 490, 0, 0, 0, 237, 0, 489, 0, 0, 0, - 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, - 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, - 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 67, 0, 0, 174, - 175, 176, 511, 1341, 513, 514, 515, 516, 0, 0, - 213, 512, 219, 517, 518, 519, 0, 233, 268, 239, - 232, 394, 0, 0, 0, 487, 504, 0, 532, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, - 576, 0, 0, 0, 547, 0, 503, 0, 0, 496, - 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 256, 0, 307, 546, 0, 0, - 421, 0, 0, 544, 0, 0, 0, 0, 0, 279, - 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, - 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, - 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 0, 0, 329, 359, 215, 411, 378, 534, 545, - 540, 541, 538, 539, 0, 537, 536, 535, 548, 526, - 527, 528, 529, 531, 0, 542, 543, 530, 187, 200, - 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, - 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 557, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 0, 0, 0, 0, 490, 0, 0, 0, 237, - 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, + 714, 701, 32, 2054, 652, 717, 623, 641, 726, 643, + 646, 684, 604, 665, 321, 638, 0, 627, 600, 634, + 601, 625, 654, 237, 658, 622, 703, 668, 716, 280, + 0, 628, 334, 686, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 723, 284, + 675, 0, 379, 306, 0, 0, 0, 656, 706, 663, + 697, 651, 685, 612, 674, 718, 639, 682, 719, 270, + 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, + 176, 0, 2061, 2062, 0, 0, 0, 0, 0, 213, + 0, 219, 679, 713, 636, 681, 233, 268, 239, 232, + 394, 683, 729, 599, 676, 0, 602, 605, 725, 709, + 631, 632, 0, 0, 0, 0, 0, 0, 0, 655, + 664, 694, 649, 0, 0, 0, 0, 0, 0, 0, + 0, 629, 0, 673, 0, 0, 0, 608, 603, 0, + 0, 0, 0, 653, 0, 0, 0, 611, 0, 630, + 695, 0, 597, 256, 606, 307, 699, 708, 650, 421, + 712, 648, 647, 715, 690, 609, 705, 642, 279, 607, + 276, 188, 202, 0, 640, 317, 355, 360, 704, 626, + 635, 224, 633, 358, 330, 409, 209, 247, 352, 335, + 356, 672, 688, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 621, 700, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 692, 728, 329, 359, 215, 411, 378, 616, 620, 614, + 615, 666, 667, 617, 720, 721, 722, 696, 610, 0, + 618, 619, 0, 702, 710, 711, 671, 187, 200, 282, + 724, 349, 250, 432, 416, 414, 598, 613, 230, 624, + 0, 0, 637, 644, 645, 657, 659, 660, 661, 662, + 670, 677, 678, 680, 687, 689, 691, 693, 698, 707, + 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, + 0, 290, 669, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 714, 701, 0, 0, + 652, 717, 623, 641, 726, 643, 646, 684, 604, 665, + 321, 638, 0, 627, 600, 634, 601, 625, 654, 237, + 658, 622, 703, 668, 716, 280, 0, 628, 334, 686, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, - 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, - 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 67, 0, 0, 174, 175, 176, 511, 510, 513, - 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, - 519, 0, 233, 268, 239, 232, 394, 0, 0, 0, - 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 501, 502, 0, 0, 0, 0, 547, - 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 546, 0, 0, 421, 0, 0, 544, 0, - 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, - 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, + 294, 332, 387, 326, 723, 284, 675, 0, 379, 306, + 0, 0, 0, 656, 706, 663, 697, 651, 685, 612, + 674, 718, 639, 682, 719, 270, 221, 192, 318, 380, + 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 213, 0, 219, 679, 713, + 636, 681, 233, 268, 239, 232, 394, 683, 729, 599, + 676, 0, 602, 605, 725, 709, 631, 632, 0, 0, + 0, 0, 0, 0, 0, 655, 664, 694, 649, 0, + 0, 0, 0, 0, 0, 1806, 0, 629, 0, 673, + 0, 0, 0, 608, 603, 0, 0, 0, 0, 653, + 0, 0, 0, 611, 0, 630, 695, 0, 597, 256, + 606, 307, 699, 708, 650, 421, 712, 648, 647, 715, + 690, 609, 705, 642, 279, 607, 276, 188, 202, 0, + 640, 317, 355, 360, 704, 626, 635, 224, 633, 358, + 330, 409, 209, 247, 352, 335, 356, 672, 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, @@ -2337,42 +1717,88 @@ var yyAct = [...]int{ 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, + 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 534, 545, 540, 541, 538, 539, 0, - 537, 536, 535, 548, 526, 527, 528, 529, 531, 0, - 542, 543, 530, 187, 200, 282, 0, 349, 250, 432, - 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, + 312, 206, 264, 377, 277, 286, 692, 728, 329, 359, + 215, 411, 378, 616, 620, 614, 615, 666, 667, 617, + 720, 721, 722, 696, 610, 0, 618, 619, 0, 702, + 710, 711, 671, 187, 200, 282, 724, 349, 250, 432, + 416, 414, 598, 613, 230, 624, 0, 0, 637, 644, + 645, 657, 659, 660, 661, 662, 670, 677, 678, 680, + 687, 689, 691, 693, 698, 707, 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, + 410, 420, 424, 258, 407, 425, 0, 290, 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 321, 0, 0, 0, 0, 490, 0, 0, - 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, - 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, - 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, - 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, - 318, 380, 249, 67, 0, 0, 174, 175, 176, 511, - 510, 513, 514, 515, 516, 0, 0, 213, 512, 219, - 517, 518, 519, 0, 233, 268, 239, 232, 394, 0, - 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 501, 502, 0, 0, 0, - 0, 547, 0, 503, 0, 0, 496, 497, 499, 498, - 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 256, 0, 307, 546, 0, 0, 421, 0, 0, - 544, 0, 0, 0, 0, 0, 279, 0, 276, 188, - 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, - 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, - 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, + 303, 234, 714, 701, 0, 0, 652, 717, 623, 641, + 726, 643, 646, 684, 604, 665, 321, 638, 0, 627, + 600, 634, 601, 625, 654, 237, 658, 622, 703, 668, + 716, 280, 0, 628, 334, 686, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 723, 284, 675, 0, 379, 306, 0, 0, 0, 656, + 706, 663, 697, 651, 685, 612, 674, 718, 639, 682, + 719, 270, 221, 192, 318, 380, 249, 67, 0, 0, + 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 679, 713, 636, 681, 233, 268, + 239, 232, 394, 683, 729, 599, 676, 0, 602, 605, + 725, 709, 631, 632, 0, 0, 0, 0, 0, 0, + 0, 655, 664, 694, 649, 0, 0, 0, 0, 0, + 0, 0, 0, 629, 0, 673, 0, 0, 0, 608, + 603, 0, 0, 0, 0, 653, 0, 0, 0, 611, + 0, 630, 695, 0, 597, 256, 606, 307, 699, 708, + 650, 421, 712, 648, 647, 715, 690, 609, 705, 642, + 279, 607, 276, 188, 202, 0, 640, 317, 355, 360, + 704, 626, 635, 224, 633, 358, 330, 409, 209, 247, + 352, 335, 356, 672, 688, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 621, 700, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 692, 728, 329, 359, 215, 411, 378, 616, + 620, 614, 615, 666, 667, 617, 720, 721, 722, 696, + 610, 0, 618, 619, 0, 702, 710, 711, 671, 187, + 200, 282, 724, 349, 250, 432, 416, 414, 598, 613, + 230, 624, 0, 0, 637, 644, 645, 657, 659, 660, + 661, 662, 670, 677, 678, 680, 687, 689, 691, 693, + 698, 707, 727, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 669, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 714, 701, + 0, 0, 652, 717, 623, 641, 726, 643, 646, 684, + 604, 665, 321, 638, 0, 627, 600, 634, 601, 625, + 654, 237, 658, 622, 703, 668, 716, 280, 0, 628, + 334, 686, 370, 223, 289, 287, 396, 246, 240, 236, + 222, 265, 294, 332, 387, 326, 723, 284, 675, 0, + 379, 306, 0, 0, 0, 656, 706, 663, 697, 651, + 685, 612, 674, 718, 639, 682, 719, 270, 221, 192, + 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, + 679, 713, 636, 681, 233, 268, 239, 232, 394, 683, + 729, 599, 676, 0, 602, 605, 725, 709, 631, 632, + 0, 0, 0, 0, 0, 0, 0, 655, 664, 694, + 649, 0, 0, 0, 0, 0, 0, 1674, 0, 629, + 0, 673, 0, 0, 0, 608, 603, 0, 0, 0, + 0, 653, 0, 0, 0, 611, 0, 630, 695, 0, + 597, 256, 606, 307, 699, 708, 650, 421, 712, 648, + 647, 715, 690, 609, 705, 642, 279, 607, 276, 188, + 202, 0, 640, 317, 355, 360, 704, 626, 635, 224, + 633, 358, 330, 409, 209, 247, 352, 335, 356, 672, + 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, @@ -2380,42 +1806,88 @@ var yyAct = [...]int{ 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, - 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, + 413, 434, 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, - 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, - 329, 359, 215, 411, 378, 534, 545, 540, 541, 538, - 539, 0, 537, 536, 535, 548, 526, 527, 528, 529, - 531, 0, 542, 543, 530, 187, 200, 282, 0, 349, - 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, + 342, 259, 312, 206, 264, 377, 277, 286, 692, 728, + 329, 359, 215, 411, 378, 616, 620, 614, 615, 666, + 667, 617, 720, 721, 722, 696, 610, 0, 618, 619, + 0, 702, 710, 711, 671, 187, 200, 282, 724, 349, + 250, 432, 416, 414, 598, 613, 230, 624, 0, 0, + 637, 644, 645, 657, 659, 660, 661, 662, 670, 677, + 678, 680, 687, 689, 691, 693, 698, 707, 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, - 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, + 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, - 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, - 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, - 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, - 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, - 176, 511, 510, 513, 514, 515, 516, 0, 0, 213, - 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, - 394, 0, 0, 0, 0, 504, 0, 532, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 501, 502, 0, - 0, 0, 0, 547, 0, 503, 0, 0, 496, 497, - 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 546, 0, 0, 421, - 0, 0, 544, 0, 0, 0, 0, 0, 279, 0, - 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, - 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, - 356, 2080, 0, 357, 285, 398, 347, 408, 422, 423, + 390, 392, 303, 234, 714, 701, 0, 0, 652, 717, + 623, 641, 726, 643, 646, 684, 604, 665, 321, 638, + 0, 627, 600, 634, 601, 625, 654, 237, 658, 622, + 703, 668, 716, 280, 0, 628, 334, 686, 370, 223, + 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, + 387, 326, 723, 284, 675, 0, 379, 306, 0, 0, + 0, 656, 706, 663, 697, 651, 685, 612, 674, 718, + 639, 682, 719, 270, 221, 192, 318, 380, 249, 0, + 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, + 0, 0, 0, 213, 0, 219, 679, 713, 636, 681, + 233, 268, 239, 232, 394, 683, 729, 599, 676, 0, + 602, 605, 725, 709, 631, 632, 0, 0, 0, 0, + 0, 0, 0, 655, 664, 694, 649, 0, 0, 0, + 0, 0, 0, 1399, 0, 629, 0, 673, 0, 0, + 0, 608, 603, 0, 0, 0, 0, 653, 0, 0, + 0, 611, 0, 630, 695, 0, 597, 256, 606, 307, + 699, 708, 650, 421, 712, 648, 647, 715, 690, 609, + 705, 642, 279, 607, 276, 188, 202, 0, 640, 317, + 355, 360, 704, 626, 635, 224, 633, 358, 330, 409, + 209, 247, 352, 335, 356, 672, 688, 357, 285, 398, + 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, + 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, + 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, + 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, + 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, + 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, + 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, + 308, 310, 0, 193, 0, 381, 413, 434, 211, 621, + 700, 393, 427, 430, 0, 348, 212, 253, 244, 344, + 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, + 264, 377, 277, 286, 692, 728, 329, 359, 215, 411, + 378, 616, 620, 614, 615, 666, 667, 617, 720, 721, + 722, 696, 610, 0, 618, 619, 0, 702, 710, 711, + 671, 187, 200, 282, 724, 349, 250, 432, 416, 414, + 598, 613, 230, 624, 0, 0, 637, 644, 645, 657, + 659, 660, 661, 662, 670, 677, 678, 680, 687, 689, + 691, 693, 698, 707, 727, 189, 190, 201, 208, 217, + 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, + 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, + 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, + 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, + 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, + 424, 258, 407, 425, 0, 290, 669, 194, 220, 207, + 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, + 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, + 714, 701, 0, 0, 652, 717, 623, 641, 726, 643, + 646, 684, 604, 665, 321, 638, 0, 627, 600, 634, + 601, 625, 654, 237, 658, 622, 703, 668, 716, 280, + 0, 628, 334, 686, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 723, 284, + 675, 0, 379, 306, 0, 0, 0, 656, 706, 663, + 697, 651, 685, 612, 674, 718, 639, 682, 719, 270, + 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, + 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, + 0, 219, 679, 713, 636, 681, 233, 268, 239, 232, + 394, 683, 729, 599, 676, 0, 602, 605, 725, 709, + 631, 632, 0, 0, 0, 0, 0, 0, 0, 655, + 664, 694, 649, 0, 0, 0, 0, 0, 0, 0, + 0, 629, 0, 673, 0, 0, 0, 608, 603, 0, + 0, 0, 0, 653, 0, 0, 0, 611, 0, 630, + 695, 0, 597, 256, 606, 307, 699, 708, 650, 421, + 712, 648, 647, 715, 690, 609, 705, 642, 279, 607, + 276, 188, 202, 0, 640, 317, 355, 360, 704, 626, + 635, 224, 633, 358, 330, 409, 209, 247, 352, 335, + 356, 672, 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, @@ -2423,82 +1895,259 @@ var yyAct = [...]int{ 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 381, 413, 434, 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 0, 0, 329, 359, 215, 411, 378, 534, 545, 540, - 541, 538, 539, 0, 537, 536, 535, 548, 526, 527, - 528, 529, 531, 0, 542, 543, 530, 187, 200, 282, - 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 692, 728, 329, 359, 215, 411, 378, 616, 620, 614, + 615, 666, 667, 617, 720, 721, 722, 696, 610, 0, + 618, 619, 0, 702, 710, 711, 671, 187, 200, 282, + 724, 349, 250, 432, 416, 414, 598, 613, 230, 624, + 0, 0, 637, 644, 645, 657, 659, 660, 661, 662, + 670, 677, 678, 680, 687, 689, 691, 693, 698, 707, + 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 0, 290, 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, - 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 388, 389, 390, 392, 303, 234, 714, 701, 0, 0, + 652, 717, 623, 641, 726, 643, 646, 684, 604, 665, + 321, 638, 0, 627, 600, 634, 601, 625, 654, 237, + 658, 622, 703, 668, 716, 280, 0, 628, 334, 686, + 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, + 294, 332, 387, 326, 723, 284, 675, 0, 379, 306, + 0, 0, 0, 656, 706, 663, 697, 651, 685, 612, + 674, 718, 639, 682, 719, 270, 221, 192, 318, 380, + 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 213, 0, 219, 679, 713, + 636, 681, 233, 268, 239, 232, 394, 683, 729, 599, + 676, 0, 602, 605, 725, 709, 631, 632, 0, 0, + 0, 0, 0, 0, 0, 655, 664, 694, 649, 0, + 0, 0, 0, 0, 0, 0, 0, 629, 0, 673, + 0, 0, 0, 608, 603, 0, 0, 0, 0, 653, + 0, 0, 0, 611, 0, 630, 695, 0, 597, 256, + 606, 307, 699, 708, 650, 421, 712, 648, 647, 715, + 690, 609, 705, 642, 279, 607, 276, 188, 202, 0, + 640, 317, 355, 360, 704, 626, 635, 224, 633, 358, + 330, 409, 209, 247, 352, 335, 356, 672, 688, 357, + 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, + 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, + 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, + 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, + 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, + 204, 418, 199, 731, 417, 313, 397, 405, 302, 293, + 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, + 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, + 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, + 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, + 596, 730, 590, 589, 277, 286, 692, 728, 329, 359, + 215, 411, 378, 616, 620, 614, 615, 666, 667, 617, + 720, 721, 722, 696, 610, 0, 618, 619, 0, 702, + 710, 711, 671, 187, 200, 282, 724, 349, 250, 432, + 416, 414, 598, 613, 230, 624, 0, 0, 637, 644, + 645, 657, 659, 660, 661, 662, 670, 677, 678, 680, + 687, 689, 691, 693, 698, 707, 727, 189, 190, 201, + 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, + 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, + 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, + 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, + 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, + 410, 420, 424, 258, 407, 425, 0, 290, 669, 194, + 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, + 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, + 303, 234, 714, 701, 0, 0, 652, 717, 623, 641, + 726, 643, 646, 684, 604, 665, 321, 638, 0, 627, + 600, 634, 601, 625, 654, 237, 658, 622, 703, 668, + 716, 280, 0, 628, 334, 686, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, - 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, - 0, 270, 221, 192, 318, 380, 249, 67, 0, 564, - 174, 175, 176, 511, 510, 513, 514, 515, 516, 0, - 0, 213, 512, 219, 517, 518, 519, 0, 233, 268, - 239, 232, 394, 0, 0, 0, 0, 504, 0, 532, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, - 502, 0, 0, 0, 0, 547, 0, 503, 0, 0, - 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 256, 0, 307, 546, 0, - 0, 421, 0, 0, 544, 0, 0, 0, 0, 0, - 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, - 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, - 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 723, 284, 675, 0, 379, 306, 0, 0, 0, 656, + 706, 663, 697, 651, 685, 612, 674, 718, 639, 682, + 719, 270, 221, 192, 318, 380, 249, 0, 0, 0, + 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 679, 713, 636, 681, 233, 268, + 239, 232, 394, 683, 729, 599, 676, 0, 602, 605, + 725, 709, 631, 632, 0, 0, 0, 0, 0, 0, + 0, 655, 664, 694, 649, 0, 0, 0, 0, 0, + 0, 0, 0, 629, 0, 673, 0, 0, 0, 608, + 603, 0, 0, 0, 0, 653, 0, 0, 0, 611, + 0, 630, 695, 0, 597, 256, 606, 307, 699, 708, + 650, 421, 712, 648, 647, 715, 690, 609, 705, 642, + 279, 607, 276, 188, 202, 0, 640, 317, 355, 360, + 704, 626, 635, 224, 633, 358, 330, 409, 209, 247, + 352, 335, 356, 672, 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 283, 195, 386, 1045, 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 731, 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 0, 193, 0, 381, 413, 434, 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 0, 0, 329, 359, 215, 411, 378, 534, - 545, 540, 541, 538, 539, 0, 537, 536, 535, 548, - 526, 527, 528, 529, 531, 0, 542, 543, 530, 187, - 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 426, 428, 429, 210, 342, 259, 596, 730, 590, 589, + 277, 286, 692, 728, 329, 359, 215, 411, 378, 616, + 620, 614, 615, 666, 667, 617, 720, 721, 722, 696, + 610, 0, 618, 619, 0, 702, 710, 711, 671, 187, + 200, 282, 724, 349, 250, 432, 416, 414, 598, 613, + 230, 624, 0, 0, 637, 644, 645, 657, 659, 660, + 661, 662, 670, 677, 678, 680, 687, 689, 691, 693, + 698, 707, 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 407, 425, 0, 290, 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, + 216, 369, 388, 389, 390, 392, 303, 234, 714, 701, + 0, 0, 652, 717, 623, 641, 726, 643, 646, 684, + 604, 665, 321, 638, 0, 627, 600, 634, 601, 625, + 654, 237, 658, 622, 703, 668, 716, 280, 0, 628, + 334, 686, 370, 223, 289, 287, 396, 246, 240, 236, + 222, 265, 294, 332, 387, 326, 723, 284, 675, 0, + 379, 306, 0, 0, 0, 656, 706, 663, 697, 651, + 685, 612, 674, 718, 639, 682, 719, 270, 221, 192, + 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, + 679, 713, 636, 681, 233, 268, 239, 232, 394, 683, + 729, 599, 676, 0, 602, 605, 725, 709, 631, 632, + 0, 0, 0, 0, 0, 0, 0, 655, 664, 694, + 649, 0, 0, 0, 0, 0, 0, 0, 0, 629, + 0, 673, 0, 0, 0, 608, 603, 0, 0, 0, + 0, 653, 0, 0, 0, 611, 0, 630, 695, 0, + 597, 256, 606, 307, 699, 708, 650, 421, 712, 648, + 647, 715, 690, 609, 705, 642, 279, 607, 276, 188, + 202, 0, 640, 317, 355, 360, 704, 626, 635, 224, + 633, 358, 330, 409, 209, 247, 352, 335, 356, 672, + 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, + 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, + 304, 395, 275, 375, 254, 191, 283, 195, 386, 587, + 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, + 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, + 225, 433, 204, 418, 199, 731, 417, 313, 397, 405, + 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, + 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, + 413, 434, 211, 621, 700, 393, 427, 430, 0, 348, + 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, + 342, 259, 596, 730, 590, 589, 277, 286, 692, 728, + 329, 359, 215, 411, 378, 616, 620, 614, 615, 666, + 667, 617, 720, 721, 722, 696, 610, 0, 618, 619, + 0, 702, 710, 711, 671, 187, 200, 282, 724, 349, + 250, 432, 416, 414, 598, 613, 230, 624, 0, 0, + 637, 644, 645, 657, 659, 660, 661, 662, 670, 677, + 678, 680, 687, 689, 691, 693, 698, 707, 727, 189, + 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, + 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, + 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, + 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, + 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, + 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, + 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, + 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, + 390, 392, 303, 234, 321, 0, 0, 1328, 0, 490, + 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, + 0, 1329, 334, 0, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, + 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, + 176, 511, 510, 513, 514, 515, 516, 0, 0, 213, + 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 501, 502, 577, + 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, + 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, + 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, + 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, + 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 0, 0, 329, 359, 215, 411, 378, 535, 546, 541, + 542, 539, 540, 534, 538, 537, 536, 549, 526, 527, + 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, + 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, + 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, + 0, 490, 0, 0, 0, 237, 0, 489, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, + 0, 524, 525, 0, 0, 0, 0, 0, 0, 1438, + 0, 270, 221, 192, 318, 380, 249, 67, 0, 0, + 174, 175, 176, 511, 510, 513, 514, 515, 516, 0, + 0, 213, 512, 219, 517, 518, 519, 1439, 233, 268, + 239, 232, 394, 0, 0, 0, 487, 504, 0, 532, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, + 502, 0, 0, 0, 0, 548, 0, 503, 0, 0, + 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 547, 0, + 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 535, + 546, 541, 542, 539, 540, 534, 538, 537, 536, 549, + 526, 527, 528, 529, 531, 0, 543, 544, 530, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, + 0, 0, 0, 490, 0, 0, 0, 237, 0, 489, + 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 67, - 0, 0, 174, 175, 176, 511, 510, 513, 514, 515, + 0, 565, 174, 175, 176, 511, 510, 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 0, 504, + 233, 268, 239, 232, 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 501, 502, 0, 0, 0, 0, 547, 0, 503, + 0, 501, 502, 0, 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 546, 0, 0, 421, 0, 0, 544, 0, 0, 0, + 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, @@ -2513,8 +2162,8 @@ var yyAct = [...]int{ 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 534, 545, 540, 541, 538, 539, 0, 537, 536, - 535, 548, 526, 527, 528, 529, 531, 0, 542, 543, + 378, 535, 546, 541, 542, 539, 540, 534, 538, 537, + 536, 549, 526, 527, 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2527,21 +2176,21 @@ var yyAct = [...]int{ 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, + 321, 0, 0, 0, 0, 490, 0, 0, 0, 237, + 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, + 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, - 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, + 249, 67, 0, 0, 174, 175, 176, 511, 510, 513, + 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, + 519, 0, 233, 268, 239, 232, 394, 0, 0, 0, + 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 921, - 920, 930, 931, 923, 924, 925, 926, 927, 928, 929, - 922, 0, 0, 932, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 501, 502, 577, 0, 0, 0, 548, + 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, + 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, @@ -2556,9 +2205,9 @@ var yyAct = [...]int{ 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, + 215, 411, 378, 535, 546, 541, 542, 539, 540, 534, + 538, 537, 536, 549, 526, 527, 528, 529, 531, 0, + 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, @@ -2570,23 +2219,23 @@ var yyAct = [...]int{ 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 771, 0, 0, 0, 0, 280, 0, 0, + 303, 234, 321, 0, 0, 0, 0, 490, 0, 0, + 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, - 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, + 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, + 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, - 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, - 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 318, 380, 249, 67, 0, 0, 174, 175, 176, 511, + 1346, 513, 514, 515, 516, 0, 0, 213, 512, 219, + 517, 518, 519, 0, 233, 268, 239, 232, 394, 0, + 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 256, 0, 307, 0, 0, 770, 421, 0, 0, - 0, 0, 0, 0, 767, 768, 279, 738, 276, 188, - 202, 761, 765, 317, 355, 360, 0, 0, 0, 224, + 0, 0, 0, 0, 0, 501, 502, 577, 0, 0, + 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, + 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 256, 0, 307, 547, 0, 0, 421, 0, 0, + 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, + 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, @@ -2599,9 +2248,9 @@ var yyAct = [...]int{ 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, - 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 200, 282, 0, 349, + 329, 359, 215, 411, 378, 535, 546, 541, 542, 539, + 540, 534, 538, 537, 536, 549, 526, 527, 528, 529, + 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, @@ -2613,22 +2262,22 @@ var yyAct = [...]int{ 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 0, 1021, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, + 390, 392, 303, 234, 321, 0, 0, 0, 0, 490, + 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, - 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, - 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 1023, 0, 0, 0, 0, 0, 0, 213, - 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, - 394, 910, 911, 909, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 912, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, + 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, + 176, 511, 1343, 513, 514, 515, 516, 0, 0, 213, + 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, - 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, + 0, 0, 0, 0, 0, 0, 0, 501, 502, 577, + 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, + 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, + 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, @@ -2642,9 +2291,9 @@ var yyAct = [...]int{ 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, + 0, 0, 329, 359, 215, 411, 378, 535, 546, 541, + 542, 539, 540, 534, 538, 537, 536, 549, 526, 527, + 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2656,23 +2305,23 @@ var yyAct = [...]int{ 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 33, 0, 0, 0, + 388, 389, 390, 392, 303, 234, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 0, 0, 0, 0, 490, 0, 0, 0, 237, 0, + 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 67, 0, 564, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 67, 0, 0, 174, 175, 176, 511, 510, 513, 514, + 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, + 0, 233, 268, 239, 232, 394, 0, 0, 0, 487, + 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 501, 502, 0, 0, 0, 0, 548, 0, + 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, @@ -2687,9 +2336,9 @@ var yyAct = [...]int{ 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, + 411, 378, 535, 546, 541, 542, 539, 540, 534, 538, + 537, 536, 549, 526, 527, 528, 529, 531, 0, 543, + 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, @@ -2701,24 +2350,24 @@ var yyAct = [...]int{ 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 1371, 0, 0, 0, 0, - 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, + 234, 321, 0, 0, 0, 0, 490, 0, 0, 0, + 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, - 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, + 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 1373, - 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, - 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 380, 249, 67, 0, 0, 174, 175, 176, 511, 510, + 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, + 518, 519, 0, 233, 268, 239, 232, 394, 0, 0, + 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, + 0, 0, 0, 0, 501, 502, 0, 0, 0, 0, + 548, 0, 503, 0, 0, 496, 497, 499, 498, 500, + 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 256, 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, - 358, 330, 409, 209, 247, 352, 335, 356, 0, 1369, + 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, @@ -2730,9 +2379,9 @@ var yyAct = [...]int{ 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, - 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, + 359, 215, 411, 378, 535, 546, 541, 542, 539, 540, + 534, 538, 537, 536, 549, 526, 527, 528, 529, 531, + 0, 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, @@ -2747,22 +2396,22 @@ var yyAct = [...]int{ 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, - 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, + 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, + 0, 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, - 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, - 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 732, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 192, 318, 380, 249, 67, 0, 0, 174, 175, 176, + 511, 510, 513, 514, 515, 516, 0, 0, 213, 512, + 219, 517, 518, 519, 0, 233, 268, 239, 232, 394, + 0, 0, 0, 0, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, - 0, 0, 0, 0, 0, 0, 0, 279, 738, 276, - 188, 202, 736, 0, 317, 355, 360, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 501, 502, 0, 0, + 0, 0, 548, 0, 503, 0, 0, 496, 497, 499, + 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 256, 0, 307, 547, 0, 0, 421, 0, + 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, + 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 2082, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, @@ -2773,9 +2422,9 @@ var yyAct = [...]int{ 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, - 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 187, 200, 282, 0, + 0, 329, 359, 215, 411, 378, 535, 546, 541, 542, + 539, 540, 534, 538, 537, 536, 549, 526, 527, 528, + 529, 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2787,22 +2436,22 @@ var yyAct = [...]int{ 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 321, 0, 0, 0, 1371, + 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, + 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, + 270, 221, 192, 318, 380, 249, 67, 0, 565, 174, + 175, 176, 511, 510, 513, 514, 515, 516, 0, 0, + 213, 512, 219, 517, 518, 519, 0, 233, 268, 239, + 232, 394, 0, 0, 0, 0, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, - 175, 176, 0, 1373, 0, 0, 0, 0, 0, 0, - 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, - 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, - 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, + 0, 0, 0, 0, 548, 0, 503, 0, 0, 496, + 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 256, 0, 307, 547, 0, 0, + 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, @@ -2816,9 +2465,9 @@ var yyAct = [...]int{ 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, + 286, 0, 0, 329, 359, 215, 411, 378, 535, 546, + 541, 542, 539, 540, 534, 538, 537, 536, 549, 526, + 527, 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2830,17 +2479,233 @@ var yyAct = [...]int{ 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 33, 0, 0, + 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, + 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, + 0, 0, 270, 221, 192, 318, 380, 249, 67, 0, + 0, 174, 175, 176, 511, 510, 513, 514, 515, 516, + 0, 0, 213, 512, 219, 517, 518, 519, 0, 233, + 268, 239, 232, 394, 0, 0, 0, 0, 504, 0, + 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, + 501, 502, 0, 0, 0, 0, 548, 0, 503, 0, + 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 0, 307, 547, + 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, + 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, + 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, + 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, + 535, 546, 541, 542, 539, 540, 534, 538, 537, 536, + 549, 526, 527, 528, 529, 531, 0, 543, 544, 530, + 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 67, 0, 0, 174, 175, 176, 0, 0, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, - 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, + 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, + 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, + 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 922, 921, + 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, + 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, + 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, + 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, + 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, + 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, + 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 772, 0, 0, 0, 0, 280, 0, 0, 334, + 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, + 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, + 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, + 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, + 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, + 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 256, 0, 307, 0, 0, 771, 421, 0, 0, 0, + 0, 0, 0, 768, 769, 279, 739, 276, 188, 202, + 762, 766, 317, 355, 360, 0, 0, 0, 224, 0, + 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, + 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, + 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, + 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, + 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, + 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, + 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, + 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, + 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, + 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, + 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, + 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, + 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, + 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, + 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, + 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, + 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, + 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, + 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, + 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, + 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, + 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, + 392, 303, 234, 321, 0, 0, 0, 1023, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, + 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, + 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, + 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, + 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, + 0, 1025, 0, 0, 0, 0, 0, 0, 213, 0, + 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, + 911, 912, 910, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 913, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, + 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, + 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, + 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, + 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, + 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, + 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, + 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, + 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, + 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, + 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, + 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, + 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, + 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 200, 282, 0, + 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, + 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, + 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, + 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, + 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, + 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, + 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, + 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, + 389, 390, 392, 303, 234, 33, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, + 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, + 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 270, 221, 192, 318, 380, 249, 67, + 0, 565, 174, 175, 176, 0, 0, 0, 0, 0, + 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, + 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, + 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, + 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, + 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, + 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, + 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, + 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, + 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, + 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, + 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, + 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, + 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, + 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, + 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, + 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, + 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, + 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, + 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, + 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, + 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, + 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, + 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, + 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, + 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, + 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, + 321, 0, 0, 0, 1373, 0, 0, 0, 0, 237, + 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, + 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, + 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, + 249, 0, 0, 0, 174, 175, 176, 0, 1375, 0, + 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, + 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2849,7 +2714,7 @@ var yyAct = [...]int{ 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, + 330, 409, 209, 247, 352, 335, 356, 0, 1371, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, @@ -2882,16 +2747,16 @@ var yyAct = [...]int{ 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 0, 1389, 0, 0, 1390, 0, 0, 213, 0, 219, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, - 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, + 0, 0, 0, 0, 0, 0, 279, 739, 276, 188, + 202, 737, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, @@ -2918,14 +2783,14 @@ var yyAct = [...]int{ 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 1054, 0, 0, 0, 280, + 390, 392, 303, 234, 321, 0, 0, 0, 1373, 0, + 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 1053, 0, 0, 0, 0, 0, 0, 213, + 176, 0, 1375, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2961,570 +2826,441 @@ var yyAct = [...]int{ 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, - 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, - 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 270, 221, 192, 318, 380, 249, 0, 0, 564, - 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, - 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, - 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 388, 389, 390, 392, 303, 234, 33, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, + 67, 0, 0, 174, 175, 176, 0, 0, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, + 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, - 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, - 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, - 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, - 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, - 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 270, 221, 192, 318, 380, 249, 67, - 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, + 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, + 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, + 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, + 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, + 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, - 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, - 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, - 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, - 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, - 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, - 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, - 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, - 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, - 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, - 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, - 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, - 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, - 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, - 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, - 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, - 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, - 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, - 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, - 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, - 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, - 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, - 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 0, 0, 0, 174, 175, 176, 0, 1373, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, - 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, - 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, - 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, - 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, - 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, - 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, - 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, - 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, - 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, - 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, - 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, - 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, - 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, - 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, - 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, - 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, - 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, - 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, - 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, - 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, - 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, - 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 1023, 0, 0, 0, 0, 0, 0, 213, 0, 219, - 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, + 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, + 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, + 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, + 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, + 1391, 0, 0, 1392, 0, 0, 213, 0, 219, 0, + 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, - 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, - 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, - 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, - 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, - 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, - 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, - 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, - 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, - 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, - 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, - 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, - 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, - 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, - 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 200, 282, 0, 349, - 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, + 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, + 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, + 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, + 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, + 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, + 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, + 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, + 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, + 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, + 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, + 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, + 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, + 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, + 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, + 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, + 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, - 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, - 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, - 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, - 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, - 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, - 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, - 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, - 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 1173, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, - 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, - 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, - 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, - 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, - 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, + 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, + 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, + 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, + 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, + 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, + 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, + 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, + 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, + 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, + 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 1056, 0, 0, 0, 280, 0, + 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, + 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, + 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, + 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, + 0, 1055, 0, 0, 0, 0, 0, 0, 213, 0, + 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, - 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, - 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, - 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, - 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, - 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, - 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, - 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, - 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, - 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, - 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, - 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, - 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, - 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, - 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, + 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, + 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, + 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, + 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, + 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, + 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, + 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, + 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, + 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, + 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, + 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, + 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, + 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, - 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, - 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, - 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, - 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, - 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 321, 0, 1171, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, - 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, - 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 200, 282, 0, + 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, - 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, - 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, - 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, + 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, + 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, + 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, + 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, + 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, + 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, + 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, + 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, + 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 270, 221, 192, 318, 380, 249, 0, 0, 565, 174, + 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, + 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, - 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, - 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, - 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, - 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, - 1169, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, - 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, + 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, + 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, + 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, + 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, + 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, - 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, + 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 270, 221, 192, 318, 380, 249, 67, 0, + 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, + 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, + 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, - 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, - 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, - 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, - 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, - 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, - 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, - 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, - 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, - 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, - 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, - 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, - 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, - 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, - 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, - 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, - 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, - 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, - 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, - 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, - 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, - 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, - 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 1167, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, - 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, + 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, + 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, + 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, + 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, - 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, - 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, - 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, - 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, - 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, - 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, - 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, - 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, - 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, - 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, + 0, 0, 0, 174, 175, 176, 0, 1375, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, + 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, - 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, - 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, - 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, - 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, - 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, - 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, - 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, - 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 321, 0, 1165, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, - 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, - 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, - 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, - 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, + 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, + 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, + 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, + 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, + 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, + 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, + 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, + 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, + 380, 249, 0, 0, 0, 174, 175, 176, 0, 1025, + 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, + 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, - 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, - 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, - 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, - 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, - 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, - 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, - 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, - 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, - 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, - 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, - 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, - 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, - 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, - 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 200, 282, 0, 349, - 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, - 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, - 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, - 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, - 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, - 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, - 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, - 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, - 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 1161, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, - 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, - 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, - 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, - 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, - 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, + 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, + 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, + 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, + 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, + 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, + 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, + 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, + 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, + 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, + 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, + 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, + 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, + 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, + 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, + 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, + 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, - 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, - 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, - 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, - 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, - 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, - 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, - 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, - 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, - 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, - 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, - 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, - 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, - 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, + 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, + 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, + 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, + 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, + 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, + 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, + 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, + 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, + 392, 303, 234, 321, 0, 1175, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, + 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, + 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, + 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, + 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, + 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, + 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, - 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, - 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, - 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, - 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, - 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, - 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 321, 0, 1159, 0, - 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, - 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, - 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, - 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, - 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, - 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, + 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, + 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, + 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, + 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, + 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, + 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, + 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, + 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, + 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, + 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, + 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, + 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, + 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 200, 282, 0, + 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, - 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, - 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, - 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, - 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, + 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, + 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, + 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, + 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, + 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, + 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, + 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, + 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, + 389, 390, 392, 303, 234, 321, 0, 1173, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, + 284, 0, 0, 379, 306, 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, - 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, + 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, + 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, - 1157, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, - 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, - 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, + 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, + 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, + 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, + 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, + 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, - 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, - 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, - 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, - 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, - 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, - 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, - 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, - 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, - 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, - 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, - 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, - 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, - 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, - 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, 321, 0, 1171, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, - 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, - 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, - 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, - 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, - 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, - 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, - 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, - 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, + 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, + 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, + 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, + 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 1132, 0, 0, 174, 175, 176, 0, 0, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, - 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, + 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, + 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, + 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, + 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, - 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, - 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, - 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, - 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, - 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, - 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, - 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, - 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, - 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, - 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, - 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, - 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, + 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, - 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, - 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, - 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, - 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, - 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, - 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, - 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 1036, 0, 0, 0, 0, 0, 0, 321, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, + 0, 1169, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, @@ -3567,7 +3303,7 @@ var yyAct = [...]int{ 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 0, 0, 0, 0, 1027, + 234, 321, 0, 1167, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, @@ -3610,14 +3346,14 @@ var yyAct = [...]int{ 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, + 392, 303, 234, 321, 0, 1163, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 901, 0, 0, 0, 0, 0, 0, 213, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3653,7 +3389,7 @@ var yyAct = [...]int{ 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, + 389, 390, 392, 303, 234, 321, 0, 1161, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, @@ -3667,145 +3403,404 @@ 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, 480, 0, 256, 0, 307, 0, 0, 0, - 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, - 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, - 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, + 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, + 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, + 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, + 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, + 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, + 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, 321, 0, 1159, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, + 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, + 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, + 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, + 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, + 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, + 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, + 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, + 1134, 0, 0, 174, 175, 176, 0, 0, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, + 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, + 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, + 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, + 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, + 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, + 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 1038, 0, 0, 0, 0, 0, 0, 321, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, + 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, + 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, + 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, + 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, + 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, + 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, + 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, + 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, + 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, + 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, + 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, + 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, + 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, + 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, + 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, + 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, + 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, + 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, + 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, + 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, + 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, + 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, + 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, + 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, + 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, + 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, + 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, + 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, + 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, + 321, 0, 0, 0, 0, 0, 0, 0, 1029, 237, + 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, + 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, + 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, + 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, + 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, + 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, + 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, + 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, + 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, + 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, + 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, + 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, + 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, + 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, + 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, + 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, + 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, + 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, + 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, + 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, + 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, + 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, + 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, + 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, + 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, + 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, + 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, + 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, + 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, + 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, + 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, + 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, + 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, + 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, + 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, + 902, 0, 0, 0, 0, 0, 0, 213, 0, 219, + 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, + 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, + 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, + 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, + 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, + 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, + 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, + 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, + 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, + 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, + 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, + 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, + 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, + 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, + 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, + 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 200, 282, 0, 349, + 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, + 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, + 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, + 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, + 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, + 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, + 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, + 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, + 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, + 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, + 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, + 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, + 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 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, 200, - 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, + 0, 480, 0, 256, 0, 307, 0, 0, 0, 421, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, + 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, + 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, + 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 479, 407, - 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, - 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, - 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, - 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, - 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, - 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, - 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, + 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 479, 407, 425, + 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, + 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, + 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, - 182, 0, 421, 0, 0, 0, 0, 0, 0, 0, - 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, - 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, - 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, - 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, - 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, - 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, - 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, - 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, - 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, - 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, - 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, - 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, - 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, - 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 0, 182, + 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, - 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, - 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, - 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, + 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, + 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, + 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, + 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, + 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, + 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, + 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, + 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, + 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, + 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, + 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, + 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, + 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, + 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, + 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, + 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, + 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, + 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, + 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, + 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, + 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, + 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, + 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, + 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, + 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, + 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, + 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, + 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, + 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, + 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, + 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, } var yyPact = [...]int{ - 286, -1000, -331, 1566, -1000, -1000, -1000, -1000, -1000, -1000, + 3884, -1000, -328, 1476, -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, 1521, 1158, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 624, 1202, 102, 1429, 3586, 206, 925, 387, 79, 25498, - 380, 110, 25930, -1000, 90, -1000, 74, 25930, 86, 25066, - -1000, -1000, -1000, 12073, 1380, -4, -5, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1178, 1483, 1490, 1516, 1020, - 1499, -1000, 10332, 10332, 337, 337, 337, 8604, -1000, -1000, - 15974, 25930, 25930, 1215, 325, 376, 325, -126, -1000, -1000, - -1000, -1000, -1000, -1000, 1429, -1000, -1000, 124, -1000, 222, - 1154, -1000, 1142, -1000, 355, 393, 255, 323, 291, 252, - 246, 240, 238, 235, 234, 233, 230, 261, -1000, 509, - 509, -193, -195, 1877, 314, 314, 314, 358, 1392, 1389, - -1000, 512, -1000, 509, 509, 119, 509, 509, 509, 509, - 176, 175, 509, 509, 509, 509, 509, 509, 509, 509, - 509, 509, 509, 509, 509, 509, 509, 25930, -1000, 136, - 496, 559, 1429, 167, -1000, -1000, -1000, 25930, 319, 925, - 319, 319, 25930, -1000, 438, -1000, -1000, -1000, -1000, -1000, + -1000, 1440, 1138, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 526, 1149, 205, 1349, 3394, 131, 925, 364, 101, 25457, + 361, 2020, 25889, -1000, 77, -1000, 63, 25889, 69, 25025, + -1000, -1000, -1000, 12032, 1313, -29, -37, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1167, 1412, 1417, 1438, 1008, + 1474, -1000, 10291, 10291, 306, 306, 306, 8563, -1000, -1000, + 15933, 25889, 25889, 1161, 299, 337, 299, -138, -1000, -1000, + -1000, -1000, -1000, -1000, 1349, -1000, -1000, 129, -1000, 222, + 1105, -1000, 1102, -1000, 438, 359, 215, 288, 287, 214, + 212, 210, 206, 204, 200, 199, 198, 238, -1000, 494, + 494, -191, -192, 2360, 295, 295, 295, 324, 1326, 1325, + -1000, 544, -1000, 494, 494, 113, 494, 494, 494, 494, + 178, 177, 494, 494, 494, 494, 494, 494, 494, 494, + 494, 494, 494, 494, 494, 494, 494, 25889, -1000, 130, + 491, 530, 1349, 155, -1000, -1000, -1000, 25889, 297, 925, + 297, 297, 25889, -1000, 408, -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, @@ -3830,23 +3825,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, -1000, -1000, -1000, 25930, 585, 585, 585, 585, - 585, 585, 63, -1000, 50, 164, 161, 146, 20, 925, - 196, -1000, 431, -1000, 138, 42, -1000, 585, 5928, 5928, - 5928, -1000, 1403, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 357, -1000, -1000, -1000, -1000, 25930, 24634, 180, 555, - -1000, -1000, -1000, -1000, 1082, 695, -1000, 12073, 1203, 1170, - 1170, -1000, -1000, 416, -1000, -1000, 13369, 13369, 13369, 13369, - 13369, 13369, 13369, 13369, 13369, 13369, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 25889, 639, 639, 639, 639, + 639, 639, 49, -1000, 48, 171, 166, 152, 22, 925, + 112, -1000, 423, -1000, 143, 74, -1000, 639, 5887, 5887, + 5887, -1000, 1333, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 323, -1000, -1000, -1000, -1000, 25889, 24593, 180, 529, + -1000, -1000, -1000, -1000, 1030, 468, -1000, 12032, 3489, 1108, + 1108, -1000, -1000, 386, -1000, -1000, 13328, 13328, 13328, 13328, + 13328, 13328, 13328, 13328, 13328, 13328, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1170, 436, -1000, 11641, 1170, 1170, 1170, 1170, 1170, 1170, - 1170, 1170, 12073, 1170, 1170, 1170, 1170, 1170, 1170, 1170, - 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, 1170, -1000, - -1000, -1000, 25930, -1000, 1521, -1000, 1158, -1000, -1000, -1000, - 1407, 12073, 12073, 1521, -1000, 1321, 10332, -1000, -1000, 1471, - -1000, -1000, -1000, -1000, 666, 1545, -1000, 14665, 433, 1536, - 24202, -1000, 18579, 23770, 1138, 8158, -53, -1000, -1000, -1000, - 545, 17715, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1108, 406, -1000, 11600, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 12032, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + -1000, -1000, -1000, 25889, -1000, 1440, -1000, 1138, -1000, -1000, + -1000, 1350, 12032, 12032, 1440, -1000, 1256, 10291, -1000, -1000, + 1339, -1000, -1000, -1000, -1000, 677, 1455, -1000, 14624, 404, + 1454, 24161, -1000, 18538, 23729, 1101, 8117, -70, -1000, -1000, + -1000, 509, 17674, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -3860,179 +3855,179 @@ 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, - 1403, 1070, 25930, -1000, -1000, 2553, 925, -1000, 1201, -1000, - 1068, -1000, 1174, 136, 25930, 579, 925, 925, -1000, -1000, - -1000, 509, 509, 260, 3586, 4039, -1000, -1000, -1000, 23331, - 1200, 925, -1000, 1197, -1000, 1449, 329, 502, 502, 925, - -1000, -1000, 25930, 925, 1447, 1444, 25930, 25930, -1000, 22899, - -1000, 22467, 22035, 849, 25930, 21603, 21171, 20739, 20307, 19875, - -1000, 1274, -1000, 1169, -1000, -1000, -1000, 25930, 25930, 25930, - 4, -1000, -1000, 25930, 925, -1000, -1000, 848, 846, 509, - 509, 830, 930, 928, 927, 509, 509, 829, 924, 919, - 142, 811, 775, 773, 896, 918, 105, 875, 873, 764, - 25930, 1193, -1000, 129, 521, 183, 220, 193, 25930, 135, - 1429, 1379, 1137, 356, 25930, 1464, 1247, 25930, 925, -1000, - 7266, -1000, -1000, 909, 12073, -1000, -1000, -1000, -1000, -1000, - 585, 25930, 585, 25930, 585, 585, 585, 585, 619, 623, - 619, -1000, -1000, -1000, -1000, 5928, 5928, 25930, 5928, 5928, - 25930, 5928, 5928, 623, -1000, -1000, -1000, 479, -1000, 1245, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 81, -1000, -1000, - -1000, -1000, -1000, 1566, -1000, -1000, -1000, -124, 12073, 12073, - 12073, 12073, 713, 500, 13369, 681, 614, 13369, 13369, 13369, - 13369, 13369, 13369, 13369, 13369, 13369, 13369, 13369, 13369, 13369, - 13369, 13369, 608, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 925, -1000, 1564, 1179, 1179, 449, 449, 449, 449, - 449, 449, 449, 449, 449, 13801, 9036, 7266, 1020, 1053, - 1521, 10332, 10332, 12073, 12073, 11196, 10764, 10332, 1414, 548, - 695, 25930, -1000, -1000, 12937, -1000, -1000, -1000, -1000, -1000, - 938, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 25930, 25930, - 10332, 10332, 10332, 10332, 10332, -1000, 1135, -1000, -172, 15542, - 1490, 1020, 1471, 1454, 1557, 470, 736, 1122, -1000, 750, - 1490, 17283, 1089, -1000, 1471, -1000, -1000, -1000, 25930, -1000, - -1000, 19443, -1000, -1000, 6820, 25930, 229, 25930, -1000, 1129, - 1293, -1000, -1000, -1000, 1480, 16851, 25930, 1067, 1057, -1000, - -1000, 430, 7712, -53, -1000, 7712, 1099, -1000, -72, -38, - 9468, 447, -1000, -1000, -1000, 1877, 14233, 1001, 634, 10, - -1000, -1000, -1000, 1174, -1000, 1174, 1174, 1174, 1174, 4, - 4, 4, 4, -1000, -1000, -1000, -1000, -1000, 1192, 1184, - -1000, 1174, 1174, 1174, 1174, -1000, -1000, -1000, -1000, -1000, + -1000, 1333, 1061, 25889, -1000, -1000, 3547, 925, -1000, 1145, + -1000, 1055, -1000, 1114, 130, 25889, 579, 925, 925, -1000, + -1000, -1000, 494, 494, 229, 3394, 267, -1000, -1000, -1000, + 23290, 1144, 925, -1000, 1140, -1000, 1366, 294, 487, 487, + 925, -1000, -1000, 25889, 925, 1365, 1359, 25889, 25889, -1000, + 22858, -1000, 22426, 21994, 800, 25889, 21562, 21130, 20698, 20266, + 19834, -1000, 1218, -1000, 1189, -1000, -1000, -1000, 25889, 25889, + 25889, -12, -1000, -1000, 25889, 925, -1000, -1000, 787, 767, + 494, 494, 765, 896, 895, 891, 494, 494, 763, 890, + 916, 132, 760, 759, 756, 808, 887, 103, 784, 742, + 751, 25889, 1137, -1000, 104, 505, 182, 225, 174, 25889, + 102, 1349, 1310, 1098, 311, 25889, 1397, 1224, 25889, 925, + -1000, 7225, -1000, -1000, 886, 12032, -1000, -1000, -1000, -1000, + -1000, 639, 25889, 639, 25889, 639, 639, 639, 639, 557, + 583, 557, -1000, -1000, -1000, -1000, 5887, 5887, 25889, 5887, + 5887, 25889, 5887, 5887, 583, -1000, -1000, -1000, 453, -1000, + 1222, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 67, -1000, + -1000, -1000, -1000, -1000, 1476, -1000, -1000, -1000, -123, 12032, + 12032, 12032, 12032, 852, 464, 13328, 753, 669, 13328, 13328, + 13328, 13328, 13328, 13328, 13328, 13328, 13328, 13328, 13328, 13328, + 13328, 13328, 13328, 634, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 925, -1000, 1470, 1015, 1015, 407, 407, 407, + 407, 407, 407, 407, 407, 407, 13760, 8995, 7225, 1008, + 1043, 1440, 10291, 10291, 12032, 12032, 11155, 10723, 10291, 1336, + 553, 468, 25889, -1000, 905, -1000, -1000, 12896, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1180, 1180, 1180, 1175, 1175, 298, -1000, 12073, - 94, 25930, 1476, 752, 129, -1000, 1462, 1230, -1000, 914, - 898, -1000, 1116, -1000, -1000, 1509, -1000, -1000, 462, 627, - 621, 458, 25930, 107, 224, -1000, 289, -1000, 25930, 1177, - 1437, 502, 925, -1000, 925, -1000, -1000, -1000, -1000, 428, - -1000, -1000, 925, 1115, -1000, 1114, 711, 617, 690, 604, - 1115, -1000, -1000, -160, 1115, -1000, 1115, -1000, 1115, -1000, - 1115, -1000, 1115, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 519, 25930, 107, 608, -1000, 339, -1000, -1000, 608, - 608, -1000, -1000, -1000, -1000, 906, 905, -1000, -1000, -1000, + 25889, 25889, 10291, 10291, 10291, 10291, 10291, -1000, 1091, -1000, + -168, 15501, 1417, 1008, 1339, 1376, 1464, 444, 899, 1088, + -1000, 809, 1417, 17242, 1077, -1000, 1339, -1000, -1000, -1000, + 25889, -1000, -1000, 19402, -1000, -1000, 6779, 25889, 197, 25889, + -1000, 1099, 1193, -1000, -1000, -1000, 1406, 16810, 25889, 1084, + 1075, -1000, -1000, 403, 7671, -70, -1000, 7671, 1071, -1000, + -96, -76, 9427, 385, -1000, -1000, -1000, 2360, 14192, 947, + 611, -11, -1000, -1000, -1000, 1114, -1000, 1114, 1114, 1114, + 1114, -12, -12, -12, -12, -1000, -1000, -1000, -1000, -1000, + 1131, 1121, -1000, 1114, 1114, 1114, 1114, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1119, 1119, 1119, 1115, 1115, 282, + -1000, 12032, 81, 25889, 1387, 748, 104, -1000, 1381, 1198, + -1000, 884, 875, -1000, 1087, -1000, -1000, 1437, -1000, -1000, + 462, 632, 630, 458, 25889, 94, 194, -1000, 273, -1000, + 25889, 1118, 1358, 487, 925, -1000, 925, -1000, -1000, -1000, + -1000, 402, -1000, -1000, 925, 1085, -1000, 1093, 687, 617, + 664, 601, 1085, -1000, -1000, -172, 1085, -1000, 1085, -1000, + 1085, -1000, 1085, -1000, 1085, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 490, 25889, 94, 634, -1000, 309, -1000, + -1000, 634, 634, -1000, -1000, -1000, -1000, 878, 869, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -316, 25930, 364, 106, 115, 25930, 25930, - 25930, 25930, 25930, 407, -1000, -1000, -1000, 173, 25930, 25930, - 383, -1000, 25930, 377, -1000, -1000, -1000, -1000, -1000, -1000, - 695, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 585, - 25930, 25930, 25930, -1000, -1000, 585, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 25930, -1000, 899, 25930, 25930, -1000, - -1000, -1000, -1000, -1000, 695, 500, 563, 630, -1000, -1000, - 817, -1000, -1000, 2268, -1000, -1000, -1000, -1000, 681, 13369, - 13369, 13369, 481, 2268, 2159, 1543, 2060, 449, 544, 544, - 454, 454, 454, 454, 454, 564, 564, -1000, -1000, -1000, - -1000, 938, -1000, -1000, -1000, 938, 10332, 10332, 1105, 1170, - 427, -1000, 1178, -1000, -1000, 1490, 1000, 1000, 691, 852, - 557, 1534, 1000, 539, 1529, 1000, 1000, 10332, -1000, -1000, - 643, -1000, 12073, 938, -1000, 759, 1101, 1100, 1000, 938, - 938, 1000, 1000, 25930, -1000, -289, -1000, -109, 437, 1170, - -1000, 19011, -1000, -1000, 1407, -1000, -1000, 1365, -1000, 1322, - 12073, 12073, 12073, -1000, -1000, -1000, 1407, 1498, -1000, 1340, - 1339, 1526, 10332, 18579, 1471, -1000, -1000, -1000, 426, 1526, - 1079, 1170, -1000, 25930, 18579, 18579, 18579, 18579, 18579, -1000, - 1291, 1290, -1000, 1318, 1301, 1305, 25930, -1000, 1037, 1020, - 16851, 229, 1063, 18579, 25930, -1000, -1000, 18579, 25930, 6374, - -1000, 1099, -53, -54, -1000, -1000, -1000, -1000, 695, -1000, - 885, -1000, 283, -1000, 311, -1000, -1000, -1000, -1000, 1428, - -1000, 647, 5, -1000, -1000, 4, 4, -1000, -1000, 447, - 651, 447, 447, 447, 892, 892, -1000, -1000, -1000, -1000, - -1000, 737, -1000, -1000, -1000, 735, -1000, -1000, 660, 1268, - 94, -1000, -1000, 509, 886, 1385, 25930, -1000, -1000, 976, - 360, -1000, 1244, -1000, -1000, -1000, -1000, -1000, 3274, 25930, - 1032, -1000, 103, 25930, 973, 25930, -1000, 1027, 25930, -1000, - 925, -1000, -1000, 7266, -1000, 25930, 1170, -1000, -1000, -1000, - -1000, 378, 1415, 1408, 107, 103, 447, 925, -1000, -1000, - -1000, -1000, -1000, -320, 1022, 25930, 130, -1000, 1176, 934, - -1000, 1222, -1000, -1000, -1000, -1000, 87, 182, 169, 330, - -1000, -1000, -1000, -1000, 5928, 25930, -1000, -1000, -1000, -1000, - 619, -1000, 619, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 481, 2268, 815, -1000, 13369, 13369, -1000, -1000, 1000, 1000, - 10332, 7266, 1521, 1407, -1000, -1000, 171, 608, 171, 13369, - 13369, -1000, 13369, 13369, -1000, -153, 1141, 568, -1000, 12073, - 805, -1000, -1000, 13369, 13369, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 375, 369, 367, 25930, -1000, -1000, - 845, 877, 1319, 695, 695, -1000, -1000, 25930, -1000, -1000, - -1000, -1000, 1524, 12073, -1000, 1098, -1000, 5482, 1490, 1243, - 25930, 1170, 1566, 15110, 25930, 1086, -1000, 513, 1293, 1233, - 1241, 1224, -1000, -1000, -1000, -1000, 1289, -1000, 1281, -1000, - -1000, -1000, -1000, -1000, 1020, 1526, 18579, 1034, -1000, 1034, - -1000, 425, -1000, -1000, -1000, -81, -65, -1000, -1000, -1000, - 1877, -1000, -1000, 1238, 13369, -1000, -1000, -1000, 447, 447, - -1000, -1000, -1000, -1000, -1000, -1000, 996, -1000, 994, 1097, - 986, 34, -1000, 1207, 1400, 509, 509, -1000, 725, -1000, - 925, -1000, -1000, 25930, 25930, 1508, 1096, -1000, 25930, -1000, - -1000, 25930, -1000, -1000, 1333, 94, 984, -1000, -1000, -1000, - 224, 25930, -1000, 1179, 103, -1000, -1000, -1000, -1000, -1000, - -1000, 1172, -1000, -1000, -1000, 960, -1000, -161, 925, 25930, - 25930, 25930, -1000, 25930, -1000, -1000, 585, 585, -1000, 13369, - 2268, 2268, -1000, -1000, 938, -1000, 1490, -1000, 938, 1174, - 1174, -1000, 1174, 1175, -1000, 1174, 66, 1174, 54, 938, - 938, 2198, 2144, 2046, 1965, 1170, -146, -1000, 695, 12073, - 1684, 958, 1170, 1170, 1170, 979, 868, 4, -1000, -1000, - -1000, 1500, 1507, 695, -1000, -1000, -1000, 1416, 1050, 1080, - -1000, -1000, 9900, 981, 1330, 424, 979, 1521, 25930, 12073, - -1000, -1000, 12073, 1173, -1000, 12073, -1000, -1000, -1000, 1521, - 1521, 1034, -1000, -1000, 461, -1000, -1000, -1000, -1000, 15, - 1556, 2268, -1000, -1000, 4, 854, 4, 708, -1000, 703, - -1000, -1000, -232, -1000, -1000, 1094, 1272, -1000, -1000, 1172, - -1000, 25930, 25930, -1000, -1000, 184, -1000, 276, 972, -1000, - -190, -1000, -1000, 1475, 25930, -1000, -1000, 7266, -1000, -1000, - 1171, 1225, -1000, -1000, -1000, -1000, 2268, -1000, 1407, -1000, - -1000, 201, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 13369, 13369, 13369, 13369, 13369, 1490, 853, 695, 13369, 13369, - 18147, 25930, 25930, 16406, 4, -12, -1000, 12073, 12073, 1436, - -1000, 1170, -1000, 1148, 25930, 1170, 25930, -1000, 1490, -1000, - 695, 695, 25930, 695, 1490, -1000, 483, -1000, -165, 447, - -1000, 447, 953, 947, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 1472, 1096, -1000, 213, 25930, -1000, 224, -1000, - -197, -198, 1158, 970, 1087, -1000, 488, 25930, 25930, -1000, - -1000, -1000, 759, 759, 759, 759, 202, 938, -1000, 759, - 759, 963, -1000, 963, 963, 437, -284, -1000, 1376, 1373, - 695, 1082, 1555, -1000, 1170, 1566, 406, 1080, -1000, -1000, - 952, -1000, 658, 1433, -1000, 1431, -1000, -1000, -1000, -1000, - -1000, 1158, 1170, 1095, -1000, -1000, -1000, 165, -1000, 7266, - 5036, 950, -1000, -1000, -1000, -1000, -1000, 938, 112, -164, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -12, 262, -1000, - 1345, 1343, 1506, 25930, 1080, 25930, -1000, -1000, 760, -1000, - -1000, 165, 12505, 25930, -1000, -75, -1000, -1000, -1000, -1000, - -1000, 1222, -1000, 1315, -157, -175, 1349, 1351, 1351, 1373, - 1505, 1360, 1357, -1000, 751, 1077, -1000, -1000, -1000, 759, - 938, 942, 293, -1000, -1000, -161, -1000, 1302, -1000, 1347, - 838, -1000, -1000, -1000, -1000, 734, -1000, 1502, 1496, -1000, - -1000, -1000, 1237, 132, -1000, -162, -1000, 765, -1000, -1000, - -1000, 692, 682, 1236, -1000, 1540, -1000, -170, -1000, -1000, - -1000, -1000, -1000, 1554, 465, 465, -180, -1000, -1000, -1000, - 290, 733, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -317, 25889, 328, 85, 115, + 25889, 25889, 25889, 25889, 25889, 378, -1000, -1000, -1000, 159, + 25889, 25889, 357, -1000, 25889, 338, -1000, -1000, -1000, -1000, + -1000, -1000, 468, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 639, 25889, 25889, 25889, -1000, -1000, 639, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 25889, -1000, 868, 25889, + 25889, -1000, -1000, -1000, -1000, -1000, 468, 464, 531, 495, + -1000, -1000, 725, -1000, -1000, 2766, -1000, -1000, -1000, -1000, + 753, 13328, 13328, 13328, 375, 2766, 2445, 620, 793, 407, + 605, 605, 422, 422, 422, 422, 422, 594, 594, -1000, + -1000, -1000, -1000, 905, -1000, -1000, -1000, 905, 10291, 10291, + 1083, 1108, 401, -1000, 1167, -1000, -1000, 1417, 1010, 1010, + 692, 846, 565, 1453, 1010, 536, 1452, 1010, 1010, 10291, + -1000, -1000, 556, -1000, 12032, 905, -1000, 1206, 1082, 1072, + 1010, 905, 905, 1010, 1010, 25889, -1000, -291, -1000, -121, + 400, 1108, -1000, 18970, -1000, -1000, 1350, -1000, -1000, 1308, + -1000, 1253, 12032, 12032, 12032, -1000, -1000, -1000, 1350, 1426, + -1000, 1269, 1266, 1447, 10291, 18538, 1339, -1000, -1000, -1000, + 398, 1447, 1123, 1108, -1000, 25889, 18538, 18538, 18538, 18538, + 18538, -1000, 1239, 1236, -1000, 1237, 1235, 1243, 25889, -1000, + 1037, 1008, 16810, 197, 960, 18538, 25889, -1000, -1000, 18538, + 25889, 6333, -1000, 1071, -70, -38, -1000, -1000, -1000, -1000, + 468, -1000, 773, -1000, 2337, -1000, 275, -1000, -1000, -1000, + -1000, 1348, -1000, 670, 6, -1000, -1000, -12, -12, -1000, + -1000, 385, 475, 385, 385, 385, 859, 859, -1000, -1000, + -1000, -1000, -1000, 743, -1000, -1000, -1000, 737, -1000, -1000, + 735, 1207, 81, -1000, -1000, 494, 850, 1320, 25889, -1000, + -1000, 940, 326, -1000, 1219, -1000, -1000, -1000, -1000, -1000, + 245, 25889, 1034, -1000, 84, 25889, 933, 25889, -1000, 1016, + 25889, -1000, 925, -1000, -1000, 7225, -1000, 25889, 1108, -1000, + -1000, -1000, -1000, 339, 1341, 1335, 94, 84, 385, 925, + -1000, -1000, -1000, -1000, -1000, -320, 1012, 25889, 139, -1000, + 1116, 902, -1000, 1176, -1000, -1000, -1000, -1000, 83, 181, + 153, 308, -1000, -1000, -1000, -1000, 5887, 25889, -1000, -1000, + -1000, -1000, 557, -1000, 557, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 375, 2766, 2198, -1000, 13328, 13328, -1000, -1000, + 1010, 1010, 10291, 7225, 1440, 1350, -1000, -1000, 192, 634, + 192, 13328, 13328, -1000, 13328, 13328, -1000, -155, 1097, 537, + -1000, 12032, 705, -1000, -1000, 13328, 13328, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 335, 332, 331, 25889, + -1000, -1000, 789, 833, 1248, 468, 468, -1000, -1000, 25889, + -1000, -1000, -1000, -1000, 1445, 12032, -1000, 1068, -1000, 5441, + 1417, 1217, 25889, 1108, 1476, 15069, 25889, 1057, -1000, 503, + 1193, 1197, 1215, 1614, -1000, -1000, -1000, -1000, 1228, -1000, + 1216, -1000, -1000, -1000, -1000, -1000, 1008, 1447, 18538, 1018, + -1000, 1018, -1000, 391, -1000, -1000, -1000, -106, -117, -1000, + -1000, -1000, 2360, -1000, -1000, 1212, 13328, -1000, -1000, -1000, + 385, 385, -1000, -1000, -1000, -1000, -1000, -1000, 999, -1000, + 996, 1059, 994, 34, -1000, 1160, 1331, 494, 494, -1000, + 732, -1000, 925, -1000, -1000, 25889, 25889, 1436, 1053, -1000, + 25889, -1000, -1000, 25889, -1000, -1000, 1265, 81, 985, -1000, + -1000, -1000, 194, 25889, -1000, 1015, 84, -1000, -1000, -1000, + -1000, -1000, -1000, 1110, -1000, -1000, -1000, 922, -1000, -173, + 925, 25889, 25889, 25889, -1000, 25889, -1000, -1000, 639, 639, + -1000, 13328, 2766, 2766, -1000, -1000, 905, -1000, 1417, -1000, + 905, 1114, 1114, -1000, 1114, 1115, -1000, 1114, 54, 1114, + 53, 905, 905, 2680, 2427, 2273, 2147, 1108, -149, -1000, + 468, 12032, 2055, 1685, 1108, 1108, 1108, 981, 832, -12, + -1000, -1000, -1000, 1442, 1435, 468, -1000, -1000, -1000, 1369, + 979, 987, -1000, -1000, 9859, 983, 1260, 384, 981, 1440, + 25889, 12032, -1000, -1000, 12032, 1111, -1000, 12032, -1000, -1000, + -1000, 1440, 1440, 1018, -1000, -1000, 431, -1000, -1000, -1000, + -1000, 13, 1463, 2766, -1000, -1000, -12, 827, -12, 715, + -1000, 697, -1000, -1000, -230, -1000, -1000, 1174, 1200, -1000, + -1000, 1110, -1000, 25889, 25889, -1000, -1000, 190, -1000, 253, + 975, -1000, -189, -1000, -1000, 1402, 25889, -1000, -1000, 7225, + -1000, -1000, 1109, 1181, -1000, -1000, -1000, -1000, 2766, -1000, + 1350, -1000, -1000, 196, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 13328, 13328, 13328, 13328, 13328, 1417, 826, 468, + 13328, 13328, 18106, 25889, 25889, 16365, -12, -19, -1000, 12032, + 12032, 1356, -1000, 1108, -1000, 1079, 25889, 1108, 25889, -1000, + 1417, -1000, 468, 468, 25889, 468, 1417, -1000, 446, -1000, + -78, 385, -1000, 385, 915, 908, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1399, 1053, -1000, 186, 25889, -1000, + 194, -1000, -194, -195, 1138, 965, 1047, -1000, 482, 25889, + 25889, -1000, -1000, -1000, 1206, 1206, 1206, 1206, 195, 905, + -1000, 1206, 1206, 954, -1000, 954, 954, 400, -281, -1000, + 1309, 1306, 468, 1030, 1462, -1000, 1108, 1476, 382, 987, + -1000, -1000, 938, -1000, 672, 1354, -1000, 1340, -1000, -1000, + -1000, -1000, -1000, 1138, 1108, 1080, -1000, -1000, -1000, 151, + -1000, 7225, 4995, 930, -1000, -1000, -1000, -1000, -1000, 905, + 98, -177, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -19, + 242, -1000, 1273, 1271, 1431, 25889, 987, 25889, -1000, -1000, + 819, -1000, -1000, 151, 12464, 25889, -1000, -72, -1000, -1000, + -1000, -1000, -1000, 1176, -1000, 1221, -170, -186, 1277, 1280, + 1280, 1306, 1430, 1303, 1284, -1000, 817, 963, -1000, -1000, + -1000, 1206, 905, 912, 269, -1000, -1000, -173, -1000, 1214, + -1000, 1275, 704, -1000, -1000, -1000, -1000, 810, -1000, 1428, + 1423, -1000, -1000, -1000, 1210, 127, -1000, -175, -1000, 702, + -1000, -1000, -1000, 806, 774, 1204, -1000, 1451, -1000, -184, + -1000, -1000, -1000, -1000, -1000, 1460, 414, 414, -187, -1000, + -1000, -1000, 278, 730, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1854, 1853, 14, 77, 81, 1852, 1850, 1848, 1847, - 128, 123, 121, 1844, 1843, 1840, 1839, 1837, 1836, 1835, - 1834, 1833, 1831, 1830, 1829, 62, 115, 114, 1828, 1825, - 1811, 1810, 1807, 126, 124, 473, 1806, 125, 1805, 1803, - 1802, 1801, 1800, 1796, 1794, 1792, 1781, 1780, 1778, 1777, - 199, 1776, 1775, 7, 1774, 83, 1772, 1769, 1768, 1767, - 1760, 1759, 1757, 105, 1756, 44, 226, 48, 75, 1753, - 69, 765, 1746, 96, 111, 1745, 161, 1744, 39, 89, - 68, 1743, 40, 1742, 1738, 86, 1736, 1735, 1734, 73, - 1733, 1731, 2601, 1729, 67, 76, 21, 37, 1728, 1727, - 1726, 1725, 32, 1285, 1724, 1722, 24, 1721, 1720, 127, - 1718, 82, 31, 16, 19, 18, 1717, 79, 1716, 8, - 61, 23, 1713, 80, 1712, 1704, 1701, 1698, 33, 1696, - 74, 100, 116, 1695, 6, 10, 1690, 1689, 1688, 1686, - 1684, 1671, 4, 1670, 1668, 1666, 1665, 26, 1663, 11, - 25, 70, 46, 29, 9, 1662, 119, 1660, 27, 104, - 66, 102, 1659, 1658, 1657, 962, 1656, 59, 1655, 131, - 1654, 1653, 41, 1652, 462, 753, 1648, 1647, 1646, 49, - 1116, 2368, 13, 106, 1643, 1642, 1687, 55, 71, 22, - 1641, 1640, 1637, 122, 45, 51, 939, 43, 1636, 1635, - 1634, 1633, 1631, 1627, 1626, 387, 1625, 1624, 1623, 34, - 20, 110, 30, 1621, 1619, 1617, 1614, 1613, 63, 54, - 1612, 99, 98, 72, 117, 1611, 107, 84, 57, 1609, - 56, 1606, 1605, 1604, 1603, 42, 1602, 1601, 1599, 1598, - 94, 85, 64, 36, 35, 87, 1597, 38, 1596, 1592, - 97, 90, 1591, 17, 113, 12, 1590, 2, 0, 1589, - 5, 109, 1400, 112, 1587, 1585, 1, 1584, 3, 1583, - 1581, 78, 1580, 1579, 1578, 1573, 3031, 28, 103, 1572, - 118, + 0, 1748, 1746, 14, 89, 85, 1745, 1744, 1743, 1740, + 128, 125, 118, 1738, 1737, 1736, 1735, 1733, 1730, 1729, + 1728, 1727, 1726, 1724, 1723, 61, 110, 115, 1722, 1720, + 1719, 1718, 1715, 124, 121, 458, 1708, 122, 1706, 1703, + 1700, 1698, 1694, 1693, 1692, 1691, 1690, 1688, 1684, 1681, + 134, 1675, 1673, 7, 1672, 81, 1670, 1668, 1667, 1666, + 1664, 1662, 1661, 109, 1660, 46, 86, 48, 74, 1659, + 71, 793, 1658, 98, 117, 1657, 161, 1656, 45, 90, + 69, 1655, 43, 1654, 1650, 94, 1649, 1648, 1645, 72, + 1644, 1643, 2430, 1642, 68, 76, 21, 37, 1639, 1638, + 1637, 1636, 38, 1286, 1634, 1633, 26, 1629, 1628, 127, + 1627, 80, 31, 16, 19, 18, 1626, 79, 1625, 8, + 54, 32, 1624, 75, 1623, 1622, 1617, 1616, 33, 1613, + 73, 97, 24, 1611, 6, 10, 1608, 1607, 1606, 1605, + 1604, 1603, 4, 1602, 1601, 1600, 1599, 29, 1598, 11, + 23, 70, 111, 27, 9, 1596, 136, 1593, 25, 106, + 66, 104, 1592, 1591, 1589, 939, 1588, 49, 1587, 132, + 1586, 1585, 41, 1583, 442, 815, 1582, 1580, 1579, 59, + 1117, 2371, 13, 107, 1574, 1572, 1689, 57, 77, 22, + 1571, 1570, 1569, 119, 64, 51, 891, 44, 1567, 1566, + 1565, 1564, 1563, 1561, 1559, 246, 1556, 1555, 1554, 34, + 20, 100, 30, 1552, 1551, 1548, 1547, 1543, 63, 36, + 1541, 103, 102, 62, 116, 1540, 113, 84, 55, 1539, + 56, 1536, 1532, 1528, 1527, 42, 1526, 1525, 1524, 1523, + 99, 82, 67, 40, 35, 96, 1521, 39, 1520, 1519, + 83, 87, 1517, 17, 114, 12, 1515, 3, 0, 1512, + 5, 126, 1355, 112, 1507, 1506, 1, 1505, 2, 1504, + 1503, 78, 1498, 1495, 1488, 1483, 2988, 28, 105, 1479, + 120, } var yyR1 = [...]int{ @@ -4107,28 +4102,28 @@ var yyR1 = [...]int{ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 107, 107, 107, 107, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 280, 280, 109, - 108, 108, 108, 108, 108, 108, 108, 61, 61, 61, - 61, 61, 195, 195, 195, 197, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 124, 124, - 60, 60, 122, 122, 123, 125, 125, 119, 119, 119, - 102, 102, 102, 102, 102, 102, 102, 102, 104, 104, - 104, 126, 126, 127, 127, 128, 128, 129, 129, 130, - 131, 131, 131, 132, 132, 132, 132, 248, 248, 248, - 248, 248, 243, 243, 243, 243, 244, 244, 244, 71, - 71, 71, 71, 73, 73, 72, 72, 53, 53, 54, - 54, 54, 74, 74, 75, 75, 75, 75, 147, 147, - 147, 133, 133, 133, 133, 138, 138, 138, 134, 134, - 136, 136, 136, 137, 137, 137, 135, 141, 141, 143, - 143, 142, 142, 140, 140, 145, 145, 144, 144, 139, - 139, 101, 101, 101, 101, 101, 148, 148, 148, 148, - 153, 153, 113, 113, 115, 115, 114, 116, 154, 154, - 158, 155, 155, 159, 159, 159, 159, 159, 156, 156, - 157, 157, 185, 185, 185, 163, 163, 174, 174, 175, - 175, 165, 165, 178, 178, 178, 146, 146, 146, 146, - 249, 249, 245, 181, 181, 182, 182, 186, 186, 187, - 187, 179, 179, 179, 179, 179, 179, 179, 179, 179, + 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 280, 280, + 109, 108, 108, 108, 108, 108, 108, 108, 61, 61, + 61, 61, 61, 195, 195, 195, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, 197, 124, + 124, 60, 60, 122, 122, 123, 125, 125, 119, 119, + 119, 102, 102, 102, 102, 102, 102, 102, 102, 104, + 104, 104, 126, 126, 127, 127, 128, 128, 129, 129, + 130, 131, 131, 131, 132, 132, 132, 132, 248, 248, + 248, 248, 248, 243, 243, 243, 243, 244, 244, 244, + 71, 71, 71, 71, 73, 73, 72, 72, 53, 53, + 54, 54, 54, 74, 74, 75, 75, 75, 75, 147, + 147, 147, 133, 133, 133, 133, 138, 138, 138, 134, + 134, 136, 136, 136, 137, 137, 137, 135, 141, 141, + 143, 143, 142, 142, 140, 140, 145, 145, 144, 144, + 139, 139, 101, 101, 101, 101, 101, 148, 148, 148, + 148, 153, 153, 113, 113, 115, 115, 114, 116, 154, + 154, 158, 155, 155, 159, 159, 159, 159, 159, 156, + 156, 157, 157, 185, 185, 185, 163, 163, 174, 174, + 175, 175, 165, 165, 178, 178, 178, 146, 146, 146, + 146, 249, 249, 245, 181, 181, 182, 182, 186, 186, + 187, 187, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, @@ -4141,7 +4136,7 @@ var yyR1 = [...]int{ 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 180, 180, 180, 180, 180, 180, + 179, 179, 179, 179, 179, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, @@ -4166,7 +4161,7 @@ var yyR1 = [...]int{ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 276, 277, 193, 194, 194, 194, + 180, 180, 180, 276, 277, 193, 194, 194, 194, } var yyR2 = [...]int{ @@ -4242,26 +4237,26 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 4, 5, 5, 6, 4, 4, 6, 6, 6, 8, 8, 8, 8, 9, 8, 5, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 8, 8, 0, 2, 3, - 4, 4, 4, 4, 4, 4, 4, 0, 3, 4, - 7, 3, 1, 1, 1, 2, 3, 3, 1, 2, - 2, 1, 2, 1, 2, 2, 1, 2, 0, 1, - 0, 2, 1, 2, 4, 0, 2, 1, 3, 5, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 2, 0, 3, 0, 2, 0, 3, 1, 3, 2, - 0, 1, 1, 0, 2, 4, 4, 0, 2, 2, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 0, - 3, 3, 3, 0, 3, 1, 1, 0, 4, 0, - 1, 1, 0, 3, 1, 3, 2, 1, 0, 2, - 4, 0, 9, 3, 5, 0, 3, 3, 0, 1, - 0, 2, 2, 0, 2, 2, 2, 0, 3, 0, - 3, 0, 3, 0, 4, 0, 3, 0, 4, 0, - 1, 2, 1, 5, 4, 4, 1, 3, 3, 5, - 0, 5, 1, 3, 1, 2, 3, 1, 1, 3, - 3, 1, 3, 3, 3, 3, 3, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 0, 2, 0, - 3, 0, 1, 0, 1, 1, 0, 1, 1, 1, - 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 8, 8, 0, 2, + 3, 4, 4, 4, 4, 4, 4, 4, 0, 3, + 4, 7, 3, 1, 1, 1, 2, 3, 3, 1, + 2, 2, 1, 2, 1, 2, 2, 1, 2, 0, + 1, 0, 2, 1, 2, 4, 0, 2, 1, 3, + 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 0, 3, 0, 2, 0, 3, 1, 3, + 2, 0, 1, 1, 0, 2, 4, 4, 0, 2, + 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 0, 3, 3, 3, 0, 3, 1, 1, 0, 4, + 0, 1, 1, 0, 3, 1, 3, 2, 1, 0, + 2, 4, 0, 9, 3, 5, 0, 3, 3, 0, + 1, 0, 2, 2, 0, 2, 2, 2, 0, 3, + 0, 3, 0, 3, 0, 4, 0, 3, 0, 4, + 0, 1, 2, 1, 5, 4, 4, 1, 3, 3, + 5, 0, 5, 1, 3, 1, 2, 3, 1, 1, + 3, 3, 1, 3, 3, 3, 3, 3, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 0, 3, 0, 1, 0, 1, 1, 0, 1, 1, + 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -4300,7 +4295,7 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 1, 1, } var yyChk = [...]int{ @@ -4357,230 +4352,230 @@ var yyChk = [...]int{ 147, 132, 133, 140, 110, 148, -107, -105, -106, -108, 87, 86, 95, 88, 89, 90, 91, 97, 98, 99, -181, -186, -114, -276, 64, 65, 323, 324, 325, 326, - 331, 327, 112, 53, 312, 321, 320, 319, 316, 317, - 314, 315, 329, 330, 167, 313, 161, 138, 322, -258, - -180, 40, 282, 282, -5, -4, -276, 6, 21, 22, - -132, 18, 17, -277, 82, -59, -69, 59, 60, -70, - 22, 36, 63, 61, -51, -68, 134, -76, -186, -68, - -165, 166, -165, -165, -155, -196, 226, -159, 302, 301, - -182, -157, -181, -179, -156, 299, 157, 341, 108, 23, - 25, 111, 143, 17, 112, 159, 174, 142, 170, 323, - 152, 68, 342, 314, 315, 312, 318, 325, 326, 313, - 280, 30, 11, 344, 26, 184, 22, 36, 136, 154, - 115, 116, 187, 24, 185, 99, 347, 20, 71, 179, - 12, 172, 14, 348, 349, 15, 167, 166, 127, 163, - 66, 9, 148, 27, 124, 62, 350, 29, 351, 352, - 353, 354, 64, 125, 18, 316, 317, 32, 427, 355, - 331, 196, 138, 69, 55, 109, 356, 357, 97, 358, - 100, 72, 106, 16, 67, 38, 359, 197, 360, 169, - 361, 305, 362, 126, 155, 322, 65, 363, 161, 281, - 6, 328, 31, 183, 171, 63, 364, 162, 114, 329, - 330, 165, 98, 5, 168, 33, 10, 70, 73, 319, - 320, 321, 53, 335, 113, 13, 365, 306, 107, 300, - 252, -232, 125, -219, -223, -181, 178, -251, 174, -92, - -241, -240, -181, -71, -175, 167, 163, -175, 322, -33, - -34, -156, 142, 195, 81, 81, -223, -222, -221, -263, - 197, 178, -250, -239, 170, 179, -229, 171, 172, -224, - 163, 29, -263, -224, 169, 179, 197, 197, 105, 197, - 105, 197, 197, 197, 197, 197, 197, 197, 197, 197, - 194, -230, 117, -230, 339, 339, -235, -263, -263, -263, - 165, 34, 34, -178, -224, 165, 23, -230, -230, -156, - 142, -230, -230, -230, -230, 205, 205, -230, -230, -230, + 331, 327, 112, 53, 318, 312, 321, 320, 319, 316, + 317, 314, 315, 329, 330, 167, 313, 161, 138, 322, + -258, -180, 40, 282, 282, -5, -4, -276, 6, 21, + 22, -132, 18, 17, -277, 82, -59, -69, 59, 60, + -70, 22, 36, 63, 61, -51, -68, 134, -76, -186, + -68, -165, 166, -165, -165, -155, -196, 226, -159, 302, + 301, -182, -157, -181, -179, -156, 299, 157, 341, 108, + 23, 25, 111, 143, 17, 112, 159, 174, 142, 170, + 323, 152, 68, 342, 314, 315, 312, 318, 325, 326, + 313, 280, 30, 11, 344, 26, 184, 22, 36, 136, + 154, 115, 116, 187, 24, 185, 99, 347, 20, 71, + 179, 12, 172, 14, 348, 349, 15, 167, 166, 127, + 163, 66, 9, 148, 27, 124, 62, 350, 29, 351, + 352, 353, 354, 64, 125, 18, 316, 317, 32, 427, + 355, 331, 196, 138, 69, 55, 109, 356, 357, 97, + 358, 100, 72, 106, 16, 67, 38, 359, 197, 360, + 169, 361, 305, 362, 126, 155, 322, 65, 363, 161, + 281, 6, 328, 31, 183, 171, 63, 364, 162, 114, + 329, 330, 165, 98, 5, 168, 33, 10, 70, 73, + 319, 320, 321, 53, 335, 113, 13, 365, 306, 107, + 300, 252, -232, 125, -219, -223, -181, 178, -251, 174, + -92, -241, -240, -181, -71, -175, 167, 163, -175, 322, + -33, -34, -156, 142, 195, 81, 81, -223, -222, -221, + -263, 197, 178, -250, -239, 170, 179, -229, 171, 172, + -224, 163, 29, -263, -224, 169, 179, 197, 197, 105, + 197, 105, 197, 197, 197, 197, 197, 197, 197, 197, + 197, 194, -230, 117, -230, 339, 339, -235, -263, -263, + -263, 165, 34, 34, -178, -224, 165, 23, -230, -230, + -156, 142, -230, -230, -230, -230, 205, 205, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, - -230, -230, -92, -74, 212, 152, 154, 157, 72, 117, - -35, 207, -22, -92, -174, 167, -258, -174, -174, -92, - 149, -92, -172, 125, 13, -172, -172, -172, -172, -172, - 208, 296, 208, 296, 208, 209, 208, 209, 208, -169, - -168, 287, 288, 282, 286, -258, 313, 298, -258, 201, - 162, 202, 164, -225, 163, 34, 175, 209, 282, 204, - -172, -194, -276, -182, -194, -194, 31, 165, -181, -52, - -181, 87, -7, -3, -11, -10, -12, 117, 81, 108, - 106, 107, 124, -76, -100, 127, 109, 125, 126, 111, - 129, 128, 139, 132, 133, 134, 135, 136, 137, 138, - 130, 131, 142, 117, 118, 119, 120, 121, 122, 123, - -164, -276, -117, -276, 150, 151, -103, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -276, 149, -2, -112, - -4, -276, -276, -276, -276, -276, -276, -276, -276, -124, - -76, -276, -280, -109, -276, -280, -109, -280, -109, -280, - -276, -280, -109, -280, -109, -280, -280, -109, -276, -276, - -276, -276, -276, -276, -276, -193, -270, -271, -95, -92, - -128, -3, -50, -147, 20, 32, -76, -129, -130, -76, - -128, 55, -66, -68, -70, 59, 60, 93, 12, -184, - -183, 23, -181, 87, 149, 12, -93, 27, -92, -78, - -79, -80, -81, -95, -118, -276, 12, -85, -86, -92, - -94, -186, 81, 226, -159, -196, -161, -160, 303, 305, - 117, -185, -181, 87, 30, 82, 81, -92, -198, -201, - -203, -202, -204, -199, -200, 249, 250, 143, 253, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 31, - 186, 245, 246, 247, 248, 265, 266, 267, 268, 269, - 270, 271, 272, 232, 251, 333, 233, 234, 235, 236, - 237, 238, 240, 241, 242, 243, 244, -261, -258, 80, - 82, 81, -205, 80, -74, -92, 109, -258, -258, -230, - -230, 194, -27, -26, -254, 16, -25, -26, 157, 101, - 102, 154, 80, -219, 80, -228, -261, -258, 80, 29, - 169, 168, -227, -224, -227, -228, -258, -119, -181, -186, - -258, 29, 29, -152, -181, -152, -152, 21, -152, 21, - -152, 21, 88, -181, -152, 21, -152, 21, -152, 21, - -152, 21, -152, 21, 30, 74, 75, 30, 77, 78, - 79, -119, -119, -219, -156, -92, -258, 88, 88, -230, - -230, 88, 87, 87, 87, -230, -230, 88, 87, -258, - 87, -264, 180, 221, 223, 88, 88, 88, 88, 30, - 87, -265, 30, 440, 439, 441, 442, 443, 88, 30, - 88, 30, 88, -181, 80, -73, 214, 117, 203, 203, - 162, 162, 216, -92, 215, 217, 218, 40, 81, 165, - -85, 24, 72, -87, -92, -258, -187, -186, -179, 87, - -76, -172, -92, -172, -92, -172, -172, -172, -172, -167, - 12, 127, -226, 12, 127, -167, -194, -194, -92, -194, - -194, -92, -194, -194, -226, -173, 125, 72, -192, 229, - 263, 423, 424, 425, -76, -76, -76, -76, -110, 97, - 109, 98, 99, -103, -111, -114, -117, 92, 127, 125, - 126, 111, -103, -103, -103, -103, -103, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -103, -195, -258, 87, - 143, -258, -102, -102, -181, -67, 22, 36, -66, -182, - -187, -179, -63, -277, -277, -128, -66, -66, -76, -76, - -119, 87, -66, -119, 87, -66, -66, -62, 22, 36, - -122, -123, 113, -119, -277, -103, -181, -181, -66, -67, - -67, -66, -66, 81, -272, 305, 306, 427, -189, 197, - -188, 23, -186, 87, -132, -277, -133, 27, 10, 127, - 81, 19, 81, -131, 25, 26, -132, -104, -181, 88, - 91, -77, 81, 12, -70, -92, -183, 134, -187, -92, - -151, 197, -92, 31, 81, -88, -90, -89, -91, 62, - 66, 68, 63, 64, 65, 69, -190, 23, -78, -3, - -276, -92, -85, -278, 81, 12, 73, -278, 81, 149, - -159, -161, 81, 304, 306, 307, 72, 100, -76, -210, - 142, -237, -236, -235, -219, -221, -222, -223, 82, -176, - 97, 109, -214, 277, -205, -205, -205, -205, -205, -209, - -156, -209, -209, -209, 80, 80, -205, -205, -205, -205, - -211, 80, -211, -211, -212, 80, -212, -251, -76, -247, - -246, -242, -245, 173, 94, 335, 73, -240, -131, 88, - -73, 24, -249, -245, -258, 87, -258, 87, 81, 17, - -220, -219, -120, 221, -253, 197, -250, -241, 80, 29, - -227, -228, -228, 149, -258, 81, 27, 105, 105, 105, - 105, 335, 154, 31, -219, -120, -195, 165, -195, -195, - 87, 87, -171, 448, -85, 164, 220, -75, 318, 87, - 83, -92, -92, -92, -92, -92, 157, 154, 205, -92, - -92, -55, 182, 177, -92, 81, -55, -172, -186, -186, - -92, -172, -92, 87, -92, -181, 97, 98, 99, -111, - -103, -103, -103, -65, 187, 108, -277, -277, -66, -66, - -276, 149, -5, -132, -277, -277, 81, 73, 23, 12, - 12, -277, 12, 12, -277, -277, -66, -125, -123, 115, - -76, -277, -277, 81, 81, -277, -277, -277, -277, -277, - -271, 426, 306, -96, 70, 166, 71, -276, -188, -147, - 38, 46, 57, -76, -76, -130, -147, -163, 20, 12, - 53, 53, -97, 13, -68, -78, -70, 149, -97, -101, - 31, 53, -3, -276, -276, -154, -158, -119, -79, -80, - -80, -79, -80, 62, 62, 62, 67, 62, 67, 62, - -89, -186, -277, -277, -3, -151, 73, -78, -92, -78, - -94, -186, 134, -160, -162, 308, 305, 311, -258, 87, - 81, -235, -223, -207, 30, 97, -215, 278, -209, -209, - -210, -258, 143, -210, -210, -210, -218, 87, -218, 88, - 88, 82, -248, -243, -244, 32, 76, -242, -230, 87, - 37, -181, 82, 164, 72, 16, -149, -181, 81, 82, - -121, 222, -119, 82, -181, 82, -149, -228, -182, -181, - -276, 162, 30, 30, -120, -121, -210, -258, 450, 449, - 82, -92, -72, 212, 219, 80, 84, -260, 73, 203, - 274, 203, 206, 165, -194, -92, -167, -167, -65, 108, - -103, -103, -277, -277, -67, -182, -128, -147, -197, 143, - 249, 186, 247, 243, 263, 254, 276, 245, 277, -195, - -197, -103, -103, -103, -103, 332, -128, 116, -76, 114, - -103, -103, 163, 163, 163, -152, 39, 87, 87, 58, - -92, -126, 14, -76, 134, -132, -153, 72, -154, -113, - -115, -114, -276, -148, -277, -181, -152, -97, 81, 117, - -83, -82, 72, 73, -84, 72, -82, 62, 62, -277, - -97, -78, -97, -97, 149, 305, 309, 310, -235, -208, - 72, -103, -210, -210, 82, 81, 82, 81, 82, 81, - -177, 372, 109, -244, -243, -230, -230, 88, -258, -92, - -92, 17, 81, -219, -119, 53, -247, 82, -252, -253, - -92, -102, -121, -150, 80, 82, -257, 335, -259, -258, - -181, -181, -181, -92, -172, -172, -103, -277, -132, -277, - -205, -205, -205, -212, -205, 237, -205, 237, -277, -277, - 20, 20, 20, 20, -276, -60, 328, -76, 81, 81, - -276, -276, -276, -277, 87, -209, -127, 15, 17, 28, - -153, 81, -277, -277, 81, 53, 149, -277, -128, -158, - -76, -76, 80, -76, -128, -97, -213, 274, 10, -209, - 87, -209, 88, 88, 372, 30, 77, 78, 79, 30, - 74, 75, -150, -149, -181, 199, 181, -277, 81, -216, - 335, 338, 23, -149, -256, -255, -182, 80, 73, -147, - -209, -258, -103, -103, -103, -103, -103, -132, 87, -103, - -103, -149, -277, -149, -149, -189, -209, -135, -140, -169, - -76, -112, 29, -115, 53, -3, -181, -113, -181, -132, - -149, -132, -217, 169, 29, 168, -106, -210, -210, 82, - 82, 23, 200, -92, -253, 339, 339, -3, 82, 81, - 117, -149, -92, -277, -277, -277, -277, -61, 127, 335, - -277, -277, -277, -277, -277, -277, -96, -138, 422, -141, - 42, -142, 43, 10, -113, 149, 82, -206, 94, 29, - 29, -3, -276, 80, -53, 335, -255, -234, -182, 87, - 88, 82, -277, 333, 69, 336, -135, 47, 255, -143, - 51, -144, -139, 52, 17, -154, -181, 87, -53, -103, - 196, -149, -54, 211, 426, -260, 58, 334, 337, -136, - 49, -134, 48, -134, -142, 17, -145, 44, 45, 87, - -277, -277, 82, 174, -257, 58, -137, 50, 72, 100, - 87, 17, 17, -267, -268, 72, 213, 335, 72, 100, - 87, 87, -268, 72, 11, 10, 336, -266, 182, 177, - 180, 31, -266, 337, 176, 30, 97, + -230, -230, -230, -92, -74, 212, 152, 154, 157, 72, + 117, -35, 207, -22, -92, -174, 167, -258, -174, -174, + -92, 149, -92, -172, 125, 13, -172, -172, -172, -172, + -172, 208, 296, 208, 296, 208, 209, 208, 209, 208, + -169, -168, 287, 288, 282, 286, -258, 313, 298, -258, + 201, 162, 202, 164, -225, 163, 34, 175, 209, 282, + 204, -172, -194, -276, -182, -194, -194, 31, 165, -181, + -52, -181, 87, -7, -3, -11, -10, -12, 117, 81, + 108, 106, 107, 124, -76, -100, 127, 109, 125, 126, + 111, 129, 128, 139, 132, 133, 134, 135, 136, 137, + 138, 130, 131, 142, 117, 118, 119, 120, 121, 122, + 123, -164, -276, -117, -276, 150, 151, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -276, 149, -2, + -112, -4, -276, -276, -276, -276, -276, -276, -276, -276, + -124, -76, -276, -280, -276, -280, -109, -276, -280, -109, + -280, -109, -280, -280, -109, -280, -109, -280, -280, -109, + -276, -276, -276, -276, -276, -276, -276, -193, -270, -271, + -95, -92, -128, -3, -50, -147, 20, 32, -76, -129, + -130, -76, -128, 55, -66, -68, -70, 59, 60, 93, + 12, -184, -183, 23, -181, 87, 149, 12, -93, 27, + -92, -78, -79, -80, -81, -95, -118, -276, 12, -85, + -86, -92, -94, -186, 81, 226, -159, -196, -161, -160, + 303, 305, 117, -185, -181, 87, 30, 82, 81, -92, + -198, -201, -203, -202, -204, -199, -200, 249, 250, 143, + 253, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 31, 186, 245, 246, 247, 248, 265, 266, 267, + 268, 269, 270, 271, 272, 232, 251, 333, 233, 234, + 235, 236, 237, 238, 240, 241, 242, 243, 244, -261, + -258, 80, 82, 81, -205, 80, -74, -92, 109, -258, + -258, -230, -230, 194, -27, -26, -254, 16, -25, -26, + 157, 101, 102, 154, 80, -219, 80, -228, -261, -258, + 80, 29, 169, 168, -227, -224, -227, -228, -258, -119, + -181, -186, -258, 29, 29, -152, -181, -152, -152, 21, + -152, 21, -152, 21, 88, -181, -152, 21, -152, 21, + -152, 21, -152, 21, -152, 21, 30, 74, 75, 30, + 77, 78, 79, -119, -119, -219, -156, -92, -258, 88, + 88, -230, -230, 88, 87, 87, 87, -230, -230, 88, + 87, -258, 87, -264, 180, 221, 223, 88, 88, 88, + 88, 30, 87, -265, 30, 440, 439, 441, 442, 443, + 88, 30, 88, 30, 88, -181, 80, -73, 214, 117, + 203, 203, 162, 162, 216, -92, 215, 217, 218, 40, + 81, 165, -85, 24, 72, -87, -92, -258, -187, -186, + -179, 87, -76, -172, -92, -172, -92, -172, -172, -172, + -172, -167, 12, 127, -226, 12, 127, -167, -194, -194, + -92, -194, -194, -92, -194, -194, -226, -173, 125, 72, + -192, 229, 263, 423, 424, 425, -76, -76, -76, -76, + -110, 97, 109, 98, 99, -103, -111, -114, -117, 92, + 127, 125, 126, 111, -103, -103, -103, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -195, + -258, 87, 143, -258, -102, -102, -181, -67, 22, 36, + -66, -182, -187, -179, -63, -277, -277, -128, -66, -66, + -76, -76, -119, 87, -66, -119, 87, -66, -66, -62, + 22, 36, -122, -123, 113, -119, -277, -103, -181, -181, + -66, -67, -67, -66, -66, 81, -272, 305, 306, 427, + -189, 197, -188, 23, -186, 87, -132, -277, -133, 27, + 10, 127, 81, 19, 81, -131, 25, 26, -132, -104, + -181, 88, 91, -77, 81, 12, -70, -92, -183, 134, + -187, -92, -151, 197, -92, 31, 81, -88, -90, -89, + -91, 62, 66, 68, 63, 64, 65, 69, -190, 23, + -78, -3, -276, -92, -85, -278, 81, 12, 73, -278, + 81, 149, -159, -161, 81, 304, 306, 307, 72, 100, + -76, -210, 142, -237, -236, -235, -219, -221, -222, -223, + 82, -176, 97, 109, -214, 277, -205, -205, -205, -205, + -205, -209, -156, -209, -209, -209, 80, 80, -205, -205, + -205, -205, -211, 80, -211, -211, -212, 80, -212, -251, + -76, -247, -246, -242, -245, 173, 94, 335, 73, -240, + -131, 88, -73, 24, -249, -245, -258, 87, -258, 87, + 81, 17, -220, -219, -120, 221, -253, 197, -250, -241, + 80, 29, -227, -228, -228, 149, -258, 81, 27, 105, + 105, 105, 105, 335, 154, 31, -219, -120, -195, 165, + -195, -195, 87, 87, -171, 448, -85, 164, 220, -75, + 318, 87, 83, -92, -92, -92, -92, -92, 157, 154, + 205, -92, -92, -55, 182, 177, -92, 81, -55, -172, + -186, -186, -92, -172, -92, 87, -92, -181, 97, 98, + 99, -111, -103, -103, -103, -65, 187, 108, -277, -277, + -66, -66, -276, 149, -5, -132, -277, -277, 81, 73, + 23, 12, 12, -277, 12, 12, -277, -277, -66, -125, + -123, 115, -76, -277, -277, 81, 81, -277, -277, -277, + -277, -277, -271, 426, 306, -96, 70, 166, 71, -276, + -188, -147, 38, 46, 57, -76, -76, -130, -147, -163, + 20, 12, 53, 53, -97, 13, -68, -78, -70, 149, + -97, -101, 31, 53, -3, -276, -276, -154, -158, -119, + -79, -80, -80, -79, -80, 62, 62, 62, 67, 62, + 67, 62, -89, -186, -277, -277, -3, -151, 73, -78, + -92, -78, -94, -186, 134, -160, -162, 308, 305, 311, + -258, 87, 81, -235, -223, -207, 30, 97, -215, 278, + -209, -209, -210, -258, 143, -210, -210, -210, -218, 87, + -218, 88, 88, 82, -248, -243, -244, 32, 76, -242, + -230, 87, 37, -181, 82, 164, 72, 16, -149, -181, + 81, 82, -121, 222, -119, 82, -181, 82, -149, -228, + -182, -181, -276, 162, 30, 30, -120, -121, -210, -258, + 450, 449, 82, -92, -72, 212, 219, 80, 84, -260, + 73, 203, 274, 203, 206, 165, -194, -92, -167, -167, + -65, 108, -103, -103, -277, -277, -67, -182, -128, -147, + -197, 143, 249, 186, 247, 243, 263, 254, 276, 245, + 277, -195, -197, -103, -103, -103, -103, 332, -128, 116, + -76, 114, -103, -103, 163, 163, 163, -152, 39, 87, + 87, 58, -92, -126, 14, -76, 134, -132, -153, 72, + -154, -113, -115, -114, -276, -148, -277, -181, -152, -97, + 81, 117, -83, -82, 72, 73, -84, 72, -82, 62, + 62, -277, -97, -78, -97, -97, 149, 305, 309, 310, + -235, -208, 72, -103, -210, -210, 82, 81, 82, 81, + 82, 81, -177, 372, 109, -244, -243, -230, -230, 88, + -258, -92, -92, 17, 81, -219, -119, 53, -247, 82, + -252, -253, -92, -102, -121, -150, 80, 82, -257, 335, + -259, -258, -181, -181, -181, -92, -172, -172, -103, -277, + -132, -277, -205, -205, -205, -212, -205, 237, -205, 237, + -277, -277, 20, 20, 20, 20, -276, -60, 328, -76, + 81, 81, -276, -276, -276, -277, 87, -209, -127, 15, + 17, 28, -153, 81, -277, -277, 81, 53, 149, -277, + -128, -158, -76, -76, 80, -76, -128, -97, -213, 274, + 10, -209, 87, -209, 88, 88, 372, 30, 77, 78, + 79, 30, 74, 75, -150, -149, -181, 199, 181, -277, + 81, -216, 335, 338, 23, -149, -256, -255, -182, 80, + 73, -147, -209, -258, -103, -103, -103, -103, -103, -132, + 87, -103, -103, -149, -277, -149, -149, -189, -209, -135, + -140, -169, -76, -112, 29, -115, 53, -3, -181, -113, + -181, -132, -149, -132, -217, 169, 29, 168, -106, -210, + -210, 82, 82, 23, 200, -92, -253, 339, 339, -3, + 82, 81, 117, -149, -92, -277, -277, -277, -277, -61, + 127, 335, -277, -277, -277, -277, -277, -277, -96, -138, + 422, -141, 42, -142, 43, 10, -113, 149, 82, -206, + 94, 29, 29, -3, -276, 80, -53, 335, -255, -234, + -182, 87, 88, 82, -277, 333, 69, 336, -135, 47, + 255, -143, 51, -144, -139, 52, 17, -154, -181, 87, + -53, -103, 196, -149, -54, 211, 426, -260, 58, 334, + 337, -136, 49, -134, 48, -134, -142, 17, -145, 44, + 45, 87, -277, -277, 82, 174, -257, 58, -137, 50, + 72, 100, 87, 17, 17, -267, -268, 72, 213, 335, + 72, 100, 87, 87, -268, 72, 11, 10, 336, -266, + 182, 177, 180, 31, -266, 337, 176, 30, 97, } var yyDef = [...]int{ 32, -2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 785, 0, 523, 523, 523, 523, 523, 523, 523, - 0, 0, -2, -2, -2, 809, 36, 0, 0, 0, + 31, 786, 0, 523, 523, 523, 523, 523, 523, 523, + 0, 0, -2, -2, -2, 810, 36, 0, 0, 0, 0, -2, 481, 482, 0, 484, -2, 0, 0, 493, - 1304, 1304, 1304, 0, 0, 0, 0, 1302, 53, 54, - 499, 500, 501, 1, 3, 0, 527, 793, 0, 0, - -2, 525, 0, 0, 901, 901, 901, 0, 84, 85, - 0, 0, 0, 809, 899, 0, 899, 0, 907, 908, - 909, 104, 105, 88, -2, 109, 110, 0, 114, 367, + 1305, 1305, 1305, 0, 0, 0, 0, 1303, 53, 54, + 499, 500, 501, 1, 3, 0, 527, 794, 0, 0, + -2, 525, 0, 0, 902, 902, 902, 0, 84, 85, + 0, 0, 0, 810, 900, 0, 900, 0, 908, 909, + 910, 104, 105, 88, -2, 109, 110, 0, 114, 367, 328, 370, 326, 356, -2, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 223, 223, 0, 0, -2, 319, 319, 319, 0, 0, 0, - 353, 903, 273, 223, 223, 0, 223, 223, 223, 223, + 353, 904, 273, 223, 223, 0, 223, 223, 223, 223, 0, 0, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 0, 103, 822, - 0, 0, 113, 37, 33, 34, 35, 0, 897, 0, - 897, 897, 0, 419, 607, 917, 918, 1054, 1055, 1056, - 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, - 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, - 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 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, 1115, 1116, - 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, - 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, - 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, - 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, - 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, - 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, - 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, - 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, - 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, - 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, - 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, - 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, - 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, - 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, - 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, - 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, - 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, - 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, - 1297, 1298, 1299, 1300, 1301, 0, 472, 472, 472, 472, + 223, 223, 223, 223, 223, 223, 223, 0, 103, 823, + 0, 0, 113, 37, 33, 34, 35, 0, 898, 0, + 898, 898, 0, 419, 607, 918, 919, 1055, 1056, 1057, + 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, + 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, + 1078, 1079, 1080, 1081, 1082, 1083, 1084, 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, 1115, 1116, 1117, + 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, + 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, + 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, + 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, + 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, + 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, + 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, + 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, + 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, + 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, + 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, + 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, + 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, + 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, + 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, + 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, + 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, + 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, + 1298, 1299, 1300, 1301, 1302, 0, 472, 472, 472, 472, 472, 472, 0, 428, 0, 0, 0, 0, 0, 0, - 0, 444, 0, 447, 0, 0, 454, 472, 1305, 1305, - 1305, 888, 0, 478, 479, 466, 464, 461, 462, 480, - 483, 0, 488, 491, 913, 914, 0, 506, 0, 1125, + 0, 444, 0, 447, 0, 0, 454, 472, 1306, 1306, + 1306, 889, 0, 478, 479, 466, 464, 461, 462, 480, + 483, 0, 488, 491, 914, 915, 0, 506, 0, 1126, 498, 511, 512, 522, 38, 658, 617, 0, 623, 625, 0, 660, 661, 662, 663, 664, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 690, 691, 692, 693, - 770, 771, 772, 773, 774, 775, 776, 777, 627, 628, - 767, 0, 877, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 758, 0, 727, 727, 727, 727, 727, 727, - 727, 727, 0, 0, 0, 0, 0, 0, 0, -2, - -2, 1304, 0, 521, 785, 49, 0, 523, 528, 529, - 828, 0, 0, 785, 1303, 0, 0, -2, -2, 539, - 545, 546, 547, 548, 524, 0, 551, 555, 0, 0, - 0, 902, 0, 0, 70, 0, 1273, 881, -2, -2, - 0, 0, 915, 916, 890, -2, 921, 922, 923, 924, + 771, 772, 773, 774, 775, 776, 777, 778, 627, 628, + 768, 0, 878, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 759, 0, 728, 728, 728, 728, 728, 728, + 728, 728, 728, 0, 0, 0, 0, 0, 0, 0, + -2, -2, 1305, 0, 521, 786, 49, 0, 523, 528, + 529, 829, 0, 0, 786, 1304, 0, 0, -2, -2, + 539, 545, 546, 547, 548, 524, 0, 551, 555, 0, + 0, 0, 903, 0, 0, 70, 0, 1274, 882, -2, + -2, 0, 0, 916, 917, 891, -2, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, @@ -4593,148 +4588,148 @@ var yyDef = [...]int{ 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, -2, - 1072, 0, 0, 123, 124, 0, 36, 249, 0, 119, - 0, 243, 181, 822, 0, 0, 0, 0, 90, 111, - 112, 223, 223, 0, 113, 113, 335, 336, 337, 0, - 0, -2, 247, 0, 320, 0, 0, 237, 237, 241, - 239, 240, 0, 0, 0, 0, 0, 0, 347, 0, - 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 403, 0, 224, 0, 365, 366, 274, 0, 0, 0, - 0, 345, 346, 0, 0, 904, 905, 0, 0, 223, - 223, 0, 0, 0, 0, 223, 223, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 100, 813, 0, 0, 0, 0, 0, 0, - -2, 0, 411, 0, 0, 0, 0, 0, 0, 418, - 0, 420, 421, 0, 0, 422, 423, 424, 425, 426, - 472, 0, 472, 0, 472, 472, 472, 472, 469, 0, - 469, 467, 468, 459, 460, 1305, 1305, 0, 1305, 1305, - 0, 1305, 1305, 0, 232, 233, 234, 475, 451, 452, - 455, 456, 1306, 1307, 457, 458, 889, 489, 492, 509, - 507, 508, 510, 502, 503, 504, 505, 0, 0, 0, - 0, 0, 0, 621, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 645, 646, 647, 648, 649, 650, 651, - 624, 0, 638, 0, 0, 0, 680, 681, 682, 683, - 684, 685, 686, 687, 688, 0, 536, 0, 0, 0, - 785, 0, 0, 0, 0, 0, 0, 0, 533, 0, - 759, 0, 711, 719, 0, 712, 720, 713, 721, 714, - 0, 715, 722, 716, 723, 717, 718, 724, 0, 0, - 0, 536, 536, 0, 0, 39, 513, 514, 0, 590, - 793, 0, 538, 831, 0, 0, 794, 786, 787, 790, - 793, 0, 560, 549, 540, 543, 544, 526, 0, 552, - 556, 0, 558, 559, 0, 0, 68, 0, 606, 0, - 562, 564, 565, 566, 588, 0, 0, 0, 0, 64, - 66, 607, 0, 1273, 887, 0, 72, 73, 0, 0, - 0, 204, 892, 893, 894, -2, 230, 0, 192, 188, - 132, 133, 134, 181, 136, 181, 181, 181, 181, 201, - 201, 201, 201, 164, 165, 166, 167, 168, 0, 0, - 151, 181, 181, 181, 181, 171, 172, 173, 174, 175, - 176, 177, 178, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 183, 183, 183, 185, 185, 0, 37, 0, - 215, 0, 790, 0, 813, 99, 0, 910, 102, 0, - 0, 368, 329, 357, 369, 0, 332, 333, -2, 0, - 0, 319, 0, 321, 0, 231, 0, -2, 0, 0, - 0, 237, 241, 238, 241, 229, 242, 349, 767, 0, - 350, 351, 0, 383, 576, 0, 0, 0, 0, 0, - 389, 390, 391, 0, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, 358, 359, 360, 361, 362, 363, - 364, 0, 0, 321, 0, 354, 0, 275, 276, 0, - 0, 279, 280, 281, 282, 0, 0, 285, 286, 287, - 288, 289, 313, 314, 315, 290, 291, 292, 293, 294, - 295, 296, 307, 308, 309, 310, 311, 312, 297, 298, - 299, 300, 301, 304, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 810, 811, 812, 0, 0, 0, - 262, 898, 0, 262, 62, 417, 608, 919, 920, 473, - 474, 427, 445, 429, 448, 430, 432, 431, 433, 472, - 0, 0, 0, 235, 236, 472, 436, 437, 438, 439, - 440, 441, 442, 443, 0, 450, 0, 0, 0, 490, - 494, 495, 496, 497, 659, 618, 619, 620, 622, 639, - 0, 641, 643, 629, 630, 654, 655, 656, 0, 0, - 0, 0, 652, 634, 0, 665, 666, 667, 668, 669, - 670, 671, 672, 673, 674, 675, 676, 679, 742, 743, - 744, 0, 677, 678, 689, 0, 0, 0, 537, 768, - 0, -2, 0, 657, 876, 793, 0, 0, 0, 0, - 662, 770, 0, 662, 770, 0, 0, 0, 534, 535, - 765, 762, 0, 0, 728, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 516, 517, 519, 0, 610, 0, - 591, 0, 593, 594, 828, 50, 40, 0, 829, 0, - 0, 0, 0, 789, 791, 792, 828, 0, 778, 0, - 0, 615, 0, 0, 541, 46, 557, 553, 0, 615, - 0, 0, 605, 0, 0, 0, 0, 0, 0, 595, - 0, 0, 598, 0, 0, 0, 0, 589, 0, 0, - 0, -2, 0, 0, 0, 60, 61, 0, 0, 0, - 882, 71, 0, 0, 76, 77, 883, 884, 885, 886, - 0, 106, -2, 270, 125, 127, 128, 129, 120, 195, - 193, 0, 190, 189, 135, 201, 201, 158, 159, 204, - 0, 204, 204, 204, 0, 0, 152, 153, 154, 155, - 146, 0, 147, 148, 149, 0, 150, 248, 0, 797, - 216, 217, 219, 223, 0, 0, 0, 244, 245, 0, - 0, 900, 0, 911, 115, 116, 117, 118, 113, 0, - 0, 121, 323, 0, 0, 0, 246, 0, 0, 225, - 241, 226, 227, 0, 352, 0, 0, 385, 386, 387, - 388, 0, 0, 0, 321, 323, 204, 0, 277, 278, - 283, 284, 302, 0, 0, 0, 0, 823, 824, 0, - 827, 91, 375, 377, 376, 380, 0, 0, 0, 0, - 412, 414, 263, 264, 1305, 0, 416, 434, 470, 471, - 469, 449, 469, 476, 453, 486, 640, 642, 644, 631, - 652, 635, 0, 632, 0, 0, 626, 694, 0, 0, - 536, 0, 785, 828, 698, 699, 0, 0, 0, 0, - 0, 735, 0, 0, 736, 0, 785, 0, 763, 0, - 0, 710, 729, 0, 0, 730, 731, 732, 733, 734, - 515, 518, 520, 570, 0, 0, 0, 0, 592, 42, - 0, 0, 0, 795, 796, 788, 41, 0, 895, 896, - 779, 780, 781, 0, 550, 561, 542, 0, 793, 870, - 0, 0, 862, 0, 0, 615, 878, 0, 563, 584, - 586, 0, 581, 596, 597, 599, 0, 601, 0, 603, - 604, 567, 568, 569, 0, 615, 0, 615, 65, 615, - 67, 0, 609, 74, 75, 0, 0, 81, 205, 206, - 113, 272, 126, 197, 0, 194, 131, 191, 204, 204, - 160, 202, 203, 161, 162, 163, 0, 179, 0, 0, - 0, 265, 86, 801, 800, 223, 223, 218, 0, 221, - 0, 912, 182, 0, 0, 0, 327, 574, 0, 338, - 339, 0, 322, 382, 0, 215, 0, 228, 768, 577, - 0, 0, 340, 0, 323, 343, 344, 355, 305, 306, - 303, 572, 814, 815, 816, 0, 826, 94, 0, 0, - 0, 0, 373, 0, 415, 63, 472, 472, 633, 0, - 653, 636, 695, 696, 0, 769, 793, 44, 0, 181, - 181, 748, 181, 185, 751, 181, 753, 181, 756, 0, - 0, 0, 0, 0, 0, 0, 760, 709, 766, 0, - 0, 0, 0, 0, 0, 0, 0, 201, 833, 830, - 43, 783, 0, 616, 554, 47, 51, 0, 870, 861, - 872, 874, 0, 0, 0, 866, 0, 785, 0, 0, - 578, 585, 0, 0, 579, 0, 580, 600, 602, -2, - 785, 615, 58, 59, 0, 78, 79, 80, 271, 199, - 0, 196, 156, 157, 201, 0, 201, 0, 186, 0, - 254, 266, 0, 798, 799, 0, 0, 220, 222, 572, - 101, 0, 0, 122, 324, 0, 214, 0, 0, 407, - 404, 341, 342, 0, 0, 825, 374, 0, 92, 93, - 0, 0, 379, 413, 435, 446, 637, 697, 828, 700, - 745, 201, 749, 750, 752, 754, 755, 757, 702, 701, - 0, 0, 0, 0, 0, 793, 0, 764, 0, 0, - 0, 0, 0, 590, 201, 853, 48, 0, 0, 0, - 52, 0, 875, 0, 0, 0, 0, 69, 793, 879, - 880, 582, 0, 587, 793, 57, 207, 200, 0, 204, - 180, 204, 0, 0, 267, 802, 803, 804, 805, 806, - 807, 808, 0, 330, 575, 0, 0, 384, 0, 392, - 0, 0, 0, 0, 95, 96, 0, 0, 0, 45, - 746, 747, 0, 0, 0, 0, 737, 0, 761, 0, - 0, 0, 612, 0, 0, 610, 835, 834, 847, 851, - 784, 782, 0, 873, 0, 865, 868, 864, 867, 55, - 0, 56, 212, 0, 209, 211, 198, 169, 170, 184, - 187, 0, 0, 0, 408, 405, 406, 817, 573, 0, - 0, 0, 381, 703, 705, 704, 706, 0, 0, 0, - 708, 725, 726, 611, 613, 614, 571, 853, 0, 846, - 849, -2, 0, 0, 863, 0, 583, 130, 0, 208, - 210, 817, 0, 0, 371, 819, 97, 98, 316, 317, - 318, 91, 707, 0, 0, 0, 840, 838, 838, 851, - 0, 855, 0, 860, 0, 871, 869, 213, 87, 0, - 0, 0, 0, 820, 821, 94, 738, 0, 741, 843, - 0, 836, 839, 837, 848, 0, 854, 0, 0, 852, - 409, 410, 250, 0, 378, 739, 832, 0, 841, 842, - 850, 0, 0, 251, 252, 0, 818, 0, 844, 845, - 856, 858, 253, 0, 0, 0, 0, 255, 257, 258, - 0, 0, 256, 740, 259, 260, 261, + 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, + -2, 1073, 0, 0, 123, 124, 0, 36, 249, 0, + 119, 0, 243, 181, 823, 0, 0, 0, 0, 90, + 111, 112, 223, 223, 0, 113, 113, 335, 336, 337, + 0, 0, -2, 247, 0, 320, 0, 0, 237, 237, + 241, 239, 240, 0, 0, 0, 0, 0, 0, 347, + 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 403, 0, 224, 0, 365, 366, 274, 0, 0, + 0, 0, 345, 346, 0, 0, 905, 906, 0, 0, + 223, 223, 0, 0, 0, 0, 223, 223, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 100, 814, 0, 0, 0, 0, 0, + 0, -2, 0, 411, 0, 0, 0, 0, 0, 0, + 418, 0, 420, 421, 0, 0, 422, 423, 424, 425, + 426, 472, 0, 472, 0, 472, 472, 472, 472, 469, + 0, 469, 467, 468, 459, 460, 1306, 1306, 0, 1306, + 1306, 0, 1306, 1306, 0, 232, 233, 234, 475, 451, + 452, 455, 456, 1307, 1308, 457, 458, 890, 489, 492, + 509, 507, 508, 510, 502, 503, 504, 505, 0, 0, + 0, 0, 0, 0, 621, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 645, 646, 647, 648, 649, 650, + 651, 624, 0, 638, 0, 0, 0, 680, 681, 682, + 683, 684, 685, 686, 687, 688, 0, 536, 0, 0, + 0, 786, 0, 0, 0, 0, 0, 0, 0, 533, + 0, 760, 0, 711, 0, 712, 720, 0, 713, 721, + 714, 722, 715, 716, 723, 717, 724, 718, 719, 725, + 0, 0, 0, 536, 536, 0, 0, 39, 513, 514, + 0, 590, 794, 0, 538, 832, 0, 0, 795, 787, + 788, 791, 794, 0, 560, 549, 540, 543, 544, 526, + 0, 552, 556, 0, 558, 559, 0, 0, 68, 0, + 606, 0, 562, 564, 565, 566, 588, 0, 0, 0, + 0, 64, 66, 607, 0, 1274, 888, 0, 72, 73, + 0, 0, 0, 204, 893, 894, 895, -2, 230, 0, + 192, 188, 132, 133, 134, 181, 136, 181, 181, 181, + 181, 201, 201, 201, 201, 164, 165, 166, 167, 168, + 0, 0, 151, 181, 181, 181, 181, 171, 172, 173, + 174, 175, 176, 177, 178, 137, 138, 139, 140, 141, + 142, 143, 144, 145, 183, 183, 183, 185, 185, 0, + 37, 0, 215, 0, 791, 0, 814, 99, 0, 911, + 102, 0, 0, 368, 329, 357, 369, 0, 332, 333, + -2, 0, 0, 319, 0, 321, 0, 231, 0, -2, + 0, 0, 0, 237, 241, 238, 241, 229, 242, 349, + 768, 0, 350, 351, 0, 383, 576, 0, 0, 0, + 0, 0, 389, 390, 391, 0, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 358, 359, 360, 361, + 362, 363, 364, 0, 0, 321, 0, 354, 0, 275, + 276, 0, 0, 279, 280, 281, 282, 0, 0, 285, + 286, 287, 288, 289, 313, 314, 315, 290, 291, 292, + 293, 294, 295, 296, 307, 308, 309, 310, 311, 312, + 297, 298, 299, 300, 301, 304, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 811, 812, 813, 0, + 0, 0, 262, 899, 0, 262, 62, 417, 608, 920, + 921, 473, 474, 427, 445, 429, 448, 430, 432, 431, + 433, 472, 0, 0, 0, 235, 236, 472, 436, 437, + 438, 439, 440, 441, 442, 443, 0, 450, 0, 0, + 0, 490, 494, 495, 496, 497, 659, 618, 619, 620, + 622, 639, 0, 641, 643, 629, 630, 654, 655, 656, + 0, 0, 0, 0, 652, 634, 0, 665, 666, 667, + 668, 669, 670, 671, 672, 673, 674, 675, 676, 679, + 743, 744, 745, 0, 677, 678, 689, 0, 0, 0, + 537, 769, 0, -2, 0, 657, 877, 794, 0, 0, + 0, 0, 662, 771, 0, 662, 771, 0, 0, 0, + 534, 535, 766, 763, 0, 0, 729, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 516, 517, 519, 0, + 610, 0, 591, 0, 593, 594, 829, 50, 40, 0, + 830, 0, 0, 0, 0, 790, 792, 793, 829, 0, + 779, 0, 0, 615, 0, 0, 541, 46, 557, 553, + 0, 615, 0, 0, 605, 0, 0, 0, 0, 0, + 0, 595, 0, 0, 598, 0, 0, 0, 0, 589, + 0, 0, 0, -2, 0, 0, 0, 60, 61, 0, + 0, 0, 883, 71, 0, 0, 76, 77, 884, 885, + 886, 887, 0, 106, -2, 270, 125, 127, 128, 129, + 120, 195, 193, 0, 190, 189, 135, 201, 201, 158, + 159, 204, 0, 204, 204, 204, 0, 0, 152, 153, + 154, 155, 146, 0, 147, 148, 149, 0, 150, 248, + 0, 798, 216, 217, 219, 223, 0, 0, 0, 244, + 245, 0, 0, 901, 0, 912, 115, 116, 117, 118, + 113, 0, 0, 121, 323, 0, 0, 0, 246, 0, + 0, 225, 241, 226, 227, 0, 352, 0, 0, 385, + 386, 387, 388, 0, 0, 0, 321, 323, 204, 0, + 277, 278, 283, 284, 302, 0, 0, 0, 0, 824, + 825, 0, 828, 91, 375, 377, 376, 380, 0, 0, + 0, 0, 412, 414, 263, 264, 1306, 0, 416, 434, + 470, 471, 469, 449, 469, 476, 453, 486, 640, 642, + 644, 631, 652, 635, 0, 632, 0, 0, 626, 694, + 0, 0, 536, 0, 786, 829, 698, 699, 0, 0, + 0, 0, 0, 736, 0, 0, 737, 0, 786, 0, + 764, 0, 0, 710, 730, 0, 0, 731, 732, 733, + 734, 735, 515, 518, 520, 570, 0, 0, 0, 0, + 592, 42, 0, 0, 0, 796, 797, 789, 41, 0, + 896, 897, 780, 781, 782, 0, 550, 561, 542, 0, + 794, 871, 0, 0, 863, 0, 0, 615, 879, 0, + 563, 584, 586, 0, 581, 596, 597, 599, 0, 601, + 0, 603, 604, 567, 568, 569, 0, 615, 0, 615, + 65, 615, 67, 0, 609, 74, 75, 0, 0, 81, + 205, 206, 113, 272, 126, 197, 0, 194, 131, 191, + 204, 204, 160, 202, 203, 161, 162, 163, 0, 179, + 0, 0, 0, 265, 86, 802, 801, 223, 223, 218, + 0, 221, 0, 913, 182, 0, 0, 0, 327, 574, + 0, 338, 339, 0, 322, 382, 0, 215, 0, 228, + 769, 577, 0, 0, 340, 0, 323, 343, 344, 355, + 305, 306, 303, 572, 815, 816, 817, 0, 827, 94, + 0, 0, 0, 0, 373, 0, 415, 63, 472, 472, + 633, 0, 653, 636, 695, 696, 0, 770, 794, 44, + 0, 181, 181, 749, 181, 185, 752, 181, 754, 181, + 757, 0, 0, 0, 0, 0, 0, 0, 761, 709, + 767, 0, 0, 0, 0, 0, 0, 0, 0, 201, + 834, 831, 43, 784, 0, 616, 554, 47, 51, 0, + 871, 862, 873, 875, 0, 0, 0, 867, 0, 786, + 0, 0, 578, 585, 0, 0, 579, 0, 580, 600, + 602, -2, 786, 615, 58, 59, 0, 78, 79, 80, + 271, 199, 0, 196, 156, 157, 201, 0, 201, 0, + 186, 0, 254, 266, 0, 799, 800, 0, 0, 220, + 222, 572, 101, 0, 0, 122, 324, 0, 214, 0, + 0, 407, 404, 341, 342, 0, 0, 826, 374, 0, + 92, 93, 0, 0, 379, 413, 435, 446, 637, 697, + 829, 700, 746, 201, 750, 751, 753, 755, 756, 758, + 702, 701, 0, 0, 0, 0, 0, 794, 0, 765, + 0, 0, 0, 0, 0, 590, 201, 854, 48, 0, + 0, 0, 52, 0, 876, 0, 0, 0, 0, 69, + 794, 880, 881, 582, 0, 587, 794, 57, 207, 200, + 0, 204, 180, 204, 0, 0, 267, 803, 804, 805, + 806, 807, 808, 809, 0, 330, 575, 0, 0, 384, + 0, 392, 0, 0, 0, 0, 95, 96, 0, 0, + 0, 45, 747, 748, 0, 0, 0, 0, 738, 0, + 762, 0, 0, 0, 612, 0, 0, 610, 836, 835, + 848, 852, 785, 783, 0, 874, 0, 866, 869, 865, + 868, 55, 0, 56, 212, 0, 209, 211, 198, 169, + 170, 184, 187, 0, 0, 0, 408, 405, 406, 818, + 573, 0, 0, 0, 381, 703, 705, 704, 706, 0, + 0, 0, 708, 726, 727, 611, 613, 614, 571, 854, + 0, 847, 850, -2, 0, 0, 864, 0, 583, 130, + 0, 208, 210, 818, 0, 0, 371, 820, 97, 98, + 316, 317, 318, 91, 707, 0, 0, 0, 841, 839, + 839, 852, 0, 856, 0, 861, 0, 872, 870, 213, + 87, 0, 0, 0, 0, 821, 822, 94, 739, 0, + 742, 844, 0, 837, 840, 838, 849, 0, 855, 0, + 0, 853, 409, 410, 250, 0, 378, 740, 833, 0, + 842, 843, 851, 0, 0, 251, 252, 0, 819, 0, + 845, 846, 857, 859, 253, 0, 0, 0, 0, 255, + 257, 258, 0, 0, 256, 741, 259, 260, 261, } var yyTok1 = [...]int{ @@ -9279,141 +9274,141 @@ yydefault: } case 711: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3626 +//line sql.y:3620 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} + yyVAL.expr = &FuncExpr{Name: NewColIdent(string(yyDollar[1].bytes))} } case 712: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3630 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } case 713: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3634 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } case 714: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3639 +//line sql.y:3638 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } case 715: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3644 +//line sql.y:3643 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } case 716: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3649 +//line sql.y:3648 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } case 717: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3655 +//line sql.y:3653 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } case 718: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3660 +//line sql.y:3659 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } case 719: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3665 +//line sql.y:3664 { - yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].expr} + yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } case 720: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3669 { - yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].expr} + yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].expr} } case 721: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3673 { - yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].expr} + yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].expr} } case 722: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3678 +//line sql.y:3677 { - yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].expr} + yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].expr} } case 723: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3683 +//line sql.y:3682 { - yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].expr} + yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].expr} } case 724: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3688 +//line sql.y:3687 { - yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].expr} + yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].expr} } case 725: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3692 { - yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} + yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].expr} } case 726: yyDollar = yyS[yypt-8 : yypt+1] //line sql.y:3696 { - yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} + yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 729: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3706 + case 727: + yyDollar = yyS[yypt-8 : yypt+1] +//line sql.y:3700 { - yyVAL.expr = yyDollar[2].expr + yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } case 730: - yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3716 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3710 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = yyDollar[2].expr } case 731: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:3720 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } case 732: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:3724 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("schema"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } case 733: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:3728 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("schema"), Exprs: yyDollar[3].selectExprs} } case 734: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:3732 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } case 735: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:3736 { - yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} + yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } case 736: yyDollar = yyS[yypt-4 : yypt+1] @@ -9422,46 +9417,46 @@ yydefault: yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } case 737: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3746 + yyDollar = yyS[yypt-4 : yypt+1] +//line sql.y:3744 { - yyVAL.matchExprOption = NoOption + yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } case 738: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:3750 { - yyVAL.matchExprOption = BooleanModeOpt + yyVAL.matchExprOption = NoOption } case 739: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:3754 { - yyVAL.matchExprOption = NaturalLanguageModeOpt + yyVAL.matchExprOption = BooleanModeOpt } case 740: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:3758 { - yyVAL.matchExprOption = NaturalLanguageModeWithQueryExpansionOpt + yyVAL.matchExprOption = NaturalLanguageModeOpt } case 741: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] //line sql.y:3762 { - yyVAL.matchExprOption = QueryExpansionOpt + yyVAL.matchExprOption = NaturalLanguageModeWithQueryExpansionOpt } case 742: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3768 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3766 { - yyVAL.str = string(yyDollar[1].colIdent.String()) + yyVAL.matchExprOption = QueryExpansionOpt } case 743: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3772 { - yyVAL.str = string(yyDollar[1].bytes) + yyVAL.str = string(yyDollar[1].colIdent.String()) } case 744: yyDollar = yyS[yypt-1 : yypt+1] @@ -9470,63 +9465,63 @@ yydefault: yyVAL.str = string(yyDollar[1].bytes) } case 745: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3782 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3780 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} + yyVAL.str = string(yyDollar[1].bytes) } case 746: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3786 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal, Charset: yyDollar[3].str, Operator: CharacterSetOp} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } case 747: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:3790 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal, Charset: string(yyDollar[3].colIdent.String())} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal, Charset: yyDollar[3].str, Operator: CharacterSetOp} } case 748: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:3794 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal, Charset: string(yyDollar[3].colIdent.String())} } case 749: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3798 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 750: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3802 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} - yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length - yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } case 751: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3808 + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:3806 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length + yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale } case 752: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3812 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 753: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3816 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } case 754: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3820 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} @@ -9535,143 +9530,149 @@ yydefault: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3824 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 756: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3828 { - yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } case 757: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3832 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } case 758: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:3836 + { + yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} + } + case 759: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3837 +//line sql.y:3841 { yyVAL.expr = nil } - case 759: + case 760: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3841 +//line sql.y:3845 { yyVAL.expr = yyDollar[1].expr } - case 760: + case 761: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3846 +//line sql.y:3850 { yyVAL.str = string("") } - case 761: + case 762: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3850 +//line sql.y:3854 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } - case 762: + case 763: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3856 +//line sql.y:3860 { yyVAL.whens = []*When{yyDollar[1].when} } - case 763: + case 764: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3860 +//line sql.y:3864 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } - case 764: + case 765: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3866 +//line sql.y:3870 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } - case 765: + case 766: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3871 +//line sql.y:3875 { yyVAL.expr = nil } - case 766: + case 767: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3875 +//line sql.y:3879 { yyVAL.expr = yyDollar[2].expr } - case 767: + case 768: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3881 +//line sql.y:3885 { yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } - case 768: + case 769: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3885 +//line sql.y:3889 { yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } - case 769: + case 770: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3889 +//line sql.y:3893 { yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } - case 770: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3895 - { - yyVAL.expr = NewStrLiteral(yyDollar[1].bytes) - } case 771: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3899 { - yyVAL.expr = NewHexLiteral(yyDollar[1].bytes) + yyVAL.expr = NewStrLiteral(yyDollar[1].bytes) } case 772: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3903 { - yyVAL.expr = NewBitLiteral(yyDollar[1].bytes) + yyVAL.expr = NewHexLiteral(yyDollar[1].bytes) } case 773: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3907 { - yyVAL.expr = NewIntLiteral(yyDollar[1].bytes) + yyVAL.expr = NewBitLiteral(yyDollar[1].bytes) } case 774: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3911 { - yyVAL.expr = NewFloatLiteral(yyDollar[1].bytes) + yyVAL.expr = NewIntLiteral(yyDollar[1].bytes) } case 775: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3915 { - yyVAL.expr = NewHexNumLiteral(yyDollar[1].bytes) + yyVAL.expr = NewFloatLiteral(yyDollar[1].bytes) } case 776: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3919 { - yyVAL.expr = NewArgument(yyDollar[1].bytes) + yyVAL.expr = NewHexNumLiteral(yyDollar[1].bytes) } case 777: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3923 { - yyVAL.expr = &NullVal{} + yyVAL.expr = NewArgument(yyDollar[1].bytes) } case 778: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3929 +//line sql.y:3927 + { + yyVAL.expr = &NullVal{} + } + case 779: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3933 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -9680,80 +9681,74 @@ yydefault: } yyVAL.expr = NewIntLiteral([]byte("1")) } - case 779: + case 780: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3938 +//line sql.y:3942 { yyVAL.expr = NewIntLiteral(yyDollar[1].bytes) } - case 780: + case 781: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3942 +//line sql.y:3946 { yyVAL.expr = NewArgument(yyDollar[1].bytes) } - case 781: + case 782: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3947 +//line sql.y:3951 { yyVAL.exprs = nil } - case 782: + case 783: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3951 +//line sql.y:3955 { yyVAL.exprs = yyDollar[3].exprs } - case 783: + case 784: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3956 +//line sql.y:3960 { yyVAL.expr = nil } - case 784: + case 785: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3960 +//line sql.y:3964 { yyVAL.expr = yyDollar[2].expr } - case 785: + case 786: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3965 +//line sql.y:3969 { yyVAL.orderBy = nil } - case 786: + case 787: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3969 +//line sql.y:3973 { yyVAL.orderBy = yyDollar[3].orderBy } - case 787: + case 788: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3975 +//line sql.y:3979 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } - case 788: + case 789: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3979 +//line sql.y:3983 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } - case 789: + case 790: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3985 +//line sql.y:3989 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].orderDirection} } - case 790: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3990 - { - yyVAL.orderDirection = AscOrder - } case 791: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:3994 { yyVAL.orderDirection = AscOrder @@ -9762,43 +9757,43 @@ yydefault: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3998 { - yyVAL.orderDirection = DescOrder + yyVAL.orderDirection = AscOrder } case 793: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4003 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4002 { - yyVAL.limit = nil + yyVAL.orderDirection = DescOrder } case 794: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4007 { - yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} + yyVAL.limit = nil } case 795: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:4011 { - yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} + yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } case 796: yyDollar = yyS[yypt-4 : yypt+1] //line sql.y:4015 { - yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} + yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } case 797: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4020 + yyDollar = yyS[yypt-4 : yypt+1] +//line sql.y:4019 { - yyVAL.indexOptions = nil + yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } case 798: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4024 { - yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption, yyDollar[2].indexOption} + yyVAL.indexOptions = nil } case 799: yyDollar = yyS[yypt-2 : yypt+1] @@ -9807,10 +9802,10 @@ yydefault: yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption, yyDollar[2].indexOption} } case 800: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:4032 { - yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} + yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption, yyDollar[2].indexOption} } case 801: yyDollar = yyS[yypt-1 : yypt+1] @@ -9819,10 +9814,10 @@ yydefault: yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } case 802: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4043 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4040 { - yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} + yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } case 803: yyDollar = yyS[yypt-3 : yypt+1] @@ -9844,7 +9839,7 @@ yydefault: } case 806: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4061 +//line sql.y:4059 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } @@ -9861,16 +9856,16 @@ yydefault: yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } case 809: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4074 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:4073 { - yyVAL.str = "" + yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } case 810: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4078 { - yyVAL.str = string(yyDollar[3].bytes) + yyVAL.str = "" } case 811: yyDollar = yyS[yypt-3 : yypt+1] @@ -9885,22 +9880,22 @@ yydefault: yyVAL.str = string(yyDollar[3].bytes) } case 813: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4091 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:4090 { - yyVAL.str = "" + yyVAL.str = string(yyDollar[3].bytes) } case 814: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4095 { - yyVAL.str = yyDollar[3].str + yyVAL.str = "" } case 815: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4101 + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:4099 { - yyVAL.str = string(yyDollar[1].bytes) + yyVAL.str = yyDollar[3].str } case 816: yyDollar = yyS[yypt-1 : yypt+1] @@ -9909,28 +9904,28 @@ yydefault: yyVAL.str = string(yyDollar[1].bytes) } case 817: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4110 + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4109 { - yyVAL.str = "" + yyVAL.str = string(yyDollar[1].bytes) } case 818: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4114 { - yyVAL.str = yyDollar[2].str + yyVAL.str = "" } case 819: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4119 + yyDollar = yyS[yypt-4 : yypt+1] +//line sql.y:4118 { - yyVAL.str = "cascaded" + yyVAL.str = yyDollar[2].str } case 820: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4123 { - yyVAL.str = string(yyDollar[1].bytes) + yyVAL.str = "cascaded" } case 821: yyDollar = yyS[yypt-1 : yypt+1] @@ -9939,338 +9934,344 @@ yydefault: yyVAL.str = string(yyDollar[1].bytes) } case 822: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4131 + { + yyVAL.str = string(yyDollar[1].bytes) + } + case 823: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4132 +//line sql.y:4136 { yyVAL.str = "" } - case 823: + case 824: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4136 +//line sql.y:4140 { yyVAL.str = yyDollar[3].str } - case 824: + case 825: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4142 +//line sql.y:4146 { yyVAL.str = string(yyDollar[1].bytes) } - case 825: + case 826: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4146 +//line sql.y:4150 { yyVAL.str = string(yyDollar[1].bytes) } - case 826: + case 827: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4150 +//line sql.y:4154 { yyVAL.str = "'" + string(yyDollar[1].bytes) + "'@" + string(yyDollar[2].bytes) } - case 827: + case 828: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4154 +//line sql.y:4158 { yyVAL.str = string(yyDollar[1].bytes) } - case 828: + case 829: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4159 +//line sql.y:4163 { yyVAL.lock = NoLock } - case 829: + case 830: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4163 +//line sql.y:4167 { yyVAL.lock = ForUpdateLock } - case 830: + case 831: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4167 +//line sql.y:4171 { yyVAL.lock = ShareModeLock } - case 831: + case 832: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4172 +//line sql.y:4176 { yyVAL.selectInto = nil } - case 832: + case 833: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:4176 +//line sql.y:4180 { yyVAL.selectInto = &SelectInto{Type: IntoOutfileS3, FileName: string(yyDollar[4].bytes), Charset: yyDollar[5].str, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } - case 833: + case 834: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4180 +//line sql.y:4184 { yyVAL.selectInto = &SelectInto{Type: IntoDumpfile, FileName: string(yyDollar[3].bytes), Charset: "", FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } - case 834: + case 835: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4184 +//line sql.y:4188 { yyVAL.selectInto = &SelectInto{Type: IntoOutfile, FileName: string(yyDollar[3].bytes), Charset: yyDollar[4].str, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } - case 835: + case 836: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4189 +//line sql.y:4193 { yyVAL.str = "" } - case 836: + case 837: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4193 +//line sql.y:4197 { yyVAL.str = " format csv" + yyDollar[3].str } - case 837: + case 838: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4197 +//line sql.y:4201 { yyVAL.str = " format text" + yyDollar[3].str } - case 838: + case 839: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4202 +//line sql.y:4206 { yyVAL.str = "" } - case 839: + case 840: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4206 +//line sql.y:4210 { yyVAL.str = " header" } - case 840: + case 841: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4211 +//line sql.y:4215 { yyVAL.str = "" } - case 841: + case 842: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4215 +//line sql.y:4219 { yyVAL.str = " manifest on" } - case 842: + case 843: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4219 +//line sql.y:4223 { yyVAL.str = " manifest off" } - case 843: + case 844: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4224 +//line sql.y:4228 { yyVAL.str = "" } - case 844: + case 845: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4228 +//line sql.y:4232 { yyVAL.str = " overwrite on" } - case 845: + case 846: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4232 +//line sql.y:4236 { yyVAL.str = " overwrite off" } - case 846: + case 847: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4238 +//line sql.y:4242 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 847: + case 848: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4243 +//line sql.y:4247 { yyVAL.str = "" } - case 848: + case 849: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4247 +//line sql.y:4251 { yyVAL.str = " lines" + yyDollar[2].str + yyDollar[3].str } - case 849: + case 850: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4252 +//line sql.y:4256 { yyVAL.str = "" } - case 850: + case 851: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4256 +//line sql.y:4260 { yyVAL.str = " starting by '" + string(yyDollar[3].bytes) + "'" } - case 851: + case 852: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4261 +//line sql.y:4265 { yyVAL.str = "" } - case 852: + case 853: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4265 +//line sql.y:4269 { yyVAL.str = " terminated by '" + string(yyDollar[3].bytes) + "'" } - case 853: + case 854: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4270 +//line sql.y:4274 { yyVAL.str = "" } - case 854: + case 855: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4274 +//line sql.y:4278 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str + yyDollar[3].str + yyDollar[4].str } - case 855: + case 856: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4279 +//line sql.y:4283 { yyVAL.str = "" } - case 856: + case 857: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4283 +//line sql.y:4287 { yyVAL.str = " escaped by '" + string(yyDollar[3].bytes) + "'" } - case 857: + case 858: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4288 +//line sql.y:4292 { yyVAL.str = "" } - case 858: + case 859: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4292 +//line sql.y:4296 { yyVAL.str = yyDollar[1].str + " enclosed by '" + string(yyDollar[4].bytes) + "'" } - case 859: + case 860: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4297 +//line sql.y:4301 { yyVAL.str = "" } - case 860: + case 861: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4301 +//line sql.y:4305 { yyVAL.str = " optionally" } - case 861: + case 862: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4314 +//line sql.y:4318 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } - case 862: + case 863: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4318 +//line sql.y:4322 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } - case 863: + case 864: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4322 +//line sql.y:4326 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } - case 864: + case 865: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4326 +//line sql.y:4330 { yyVAL.ins = &Insert{Rows: yyDollar[4].values} } - case 865: + case 866: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4330 +//line sql.y:4334 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } - case 866: + case 867: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4336 +//line sql.y:4340 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 867: + case 868: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4340 +//line sql.y:4344 { yyVAL.columns = Columns{yyDollar[3].colIdent} } - case 868: + case 869: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4344 +//line sql.y:4348 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 869: + case 870: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4348 +//line sql.y:4352 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } - case 870: + case 871: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4353 +//line sql.y:4357 { yyVAL.updateExprs = nil } - case 871: + case 872: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4357 +//line sql.y:4361 { yyVAL.updateExprs = yyDollar[5].updateExprs } - case 872: + case 873: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4363 +//line sql.y:4367 { yyVAL.values = Values{yyDollar[1].valTuple} } - case 873: + case 874: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4367 +//line sql.y:4371 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } - case 874: + case 875: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4373 +//line sql.y:4377 { yyVAL.valTuple = yyDollar[1].valTuple } - case 875: + case 876: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4377 +//line sql.y:4381 { yyVAL.valTuple = ValTuple{} } - case 876: + case 877: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4383 +//line sql.y:4387 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } - case 877: + case 878: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4389 +//line sql.y:4393 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = yyDollar[1].valTuple[0] @@ -10278,252 +10279,246 @@ yydefault: yyVAL.expr = yyDollar[1].valTuple } } - case 878: + case 879: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4399 +//line sql.y:4403 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } - case 879: + case 880: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4403 +//line sql.y:4407 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } - case 880: + case 881: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4409 +//line sql.y:4413 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } - case 881: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4415 - { - yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} - } case 882: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:4419 { - yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) + yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } case 883: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4425 +//line sql.y:4423 { - yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral([]byte("on"))} + yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } case 884: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:4429 { - yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral([]byte("off"))} + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral([]byte("on"))} } case 885: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:4433 { - yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: yyDollar[3].expr} + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral([]byte("off"))} } case 886: yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:4437 { - yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Scope: ImplicitScope, Expr: yyDollar[2].expr} + yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: yyDollar[3].expr} } case 887: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:4441 + { + yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Scope: ImplicitScope, Expr: yyDollar[2].expr} + } + case 888: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:4445 { yyDollar[2].setExpr.Scope = yyDollar[1].scope yyVAL.setExpr = yyDollar[2].setExpr } - case 889: + case 890: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4449 +//line sql.y:4453 { yyVAL.bytes = []byte("charset") } - case 892: + case 893: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4459 +//line sql.y:4463 { yyVAL.expr = NewStrLiteral([]byte(yyDollar[1].colIdent.String())) } - case 893: + case 894: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4463 +//line sql.y:4467 { yyVAL.expr = NewStrLiteral(yyDollar[1].bytes) } - case 894: + case 895: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4467 +//line sql.y:4471 { yyVAL.expr = &Default{} } - case 897: + case 898: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4476 +//line sql.y:4480 { yyVAL.boolean = false } - case 898: + case 899: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4478 +//line sql.y:4482 { yyVAL.boolean = true } - case 899: + case 900: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4481 +//line sql.y:4485 { yyVAL.boolean = false } - case 900: + case 901: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4483 +//line sql.y:4487 { yyVAL.boolean = true } - case 901: + case 902: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4486 +//line sql.y:4490 { yyVAL.ignore = false } - case 902: + case 903: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4488 +//line sql.y:4492 { yyVAL.ignore = true } - case 903: + case 904: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4491 +//line sql.y:4495 { yyVAL.empty = struct{}{} } - case 904: + case 905: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4493 +//line sql.y:4497 { yyVAL.empty = struct{}{} } - case 905: + case 906: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4495 +//line sql.y:4499 { yyVAL.empty = struct{}{} } - case 906: + case 907: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4498 +//line sql.y:4502 { yyVAL.str = "" } - case 907: + case 908: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4500 +//line sql.y:4504 { yyVAL.str = string(yyDollar[1].bytes) } - case 908: + case 909: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4502 +//line sql.y:4506 { yyVAL.str = string(yyDollar[1].bytes) } - case 909: + case 910: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4504 +//line sql.y:4508 { yyVAL.str = string(yyDollar[1].bytes) } - case 910: + case 911: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4507 +//line sql.y:4511 { yyVAL.indexOptions = nil } - case 911: + case 912: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4509 +//line sql.y:4513 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } - case 912: + case 913: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4513 +//line sql.y:4517 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[2].colIdent.String())} } - case 913: + case 914: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4519 +//line sql.y:4523 { yyVAL.colIdent = yyDollar[1].colIdent } - case 914: + case 915: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4523 +//line sql.y:4527 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 916: + case 917: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4530 +//line sql.y:4534 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 917: + case 918: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4536 +//line sql.y:4540 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].colIdent.String())) } - case 918: + case 919: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4540 +//line sql.y:4544 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 920: + case 921: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4547 +//line sql.y:4551 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 1302: + case 1303: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4953 +//line sql.y:4957 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 1303: + case 1304: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4962 +//line sql.y:4966 { decNesting(yylex) } - case 1304: - yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4967 - { - skipToEnd(yylex) - } case 1305: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4972 +//line sql.y:4971 { skipToEnd(yylex) } case 1306: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-0 : yypt+1] //line sql.y:4976 { skipToEnd(yylex) @@ -10534,6 +10529,12 @@ yydefault: { skipToEnd(yylex) } + case 1308: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:4984 + { + skipToEnd(yylex) + } } goto yystack /* stack new state and value */ } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 9d085188cd4..1ceec18a43e 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -3616,47 +3616,51 @@ function_call_keyword: { $$ = &ValuesFuncExpr{Name: $3} } +| CURRENT_USER func_paren_opt + { + $$ = &FuncExpr{Name: NewColIdent(string($1))} + } /* Function calls using non reserved keywords but with special syntax forms. Dedicated grammar rules are needed because of the special syntax */ function_call_nonkeyword: - CURRENT_TIMESTAMP func_datetime_opt + CURRENT_TIMESTAMP func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("current_timestamp")} } -| UTC_TIMESTAMP func_datetime_opt +| UTC_TIMESTAMP func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("utc_timestamp")} } -| UTC_TIME func_datetime_opt +| UTC_TIME func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("utc_time")} } /* doesn't support fsp */ -| UTC_DATE func_datetime_opt +| UTC_DATE func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("utc_date")} } // now -| LOCALTIME func_datetime_opt +| LOCALTIME func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("localtime")} } // now -| LOCALTIMESTAMP func_datetime_opt +| LOCALTIMESTAMP func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("localtimestamp")} } // curdate /* doesn't support fsp */ -| CURRENT_DATE func_datetime_opt +| CURRENT_DATE func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("current_date")} } // curtime -| CURRENT_TIME func_datetime_opt +| CURRENT_TIME func_paren_opt { $$ = &FuncExpr{Name:NewColIdent("current_time")} } @@ -3697,7 +3701,7 @@ function_call_nonkeyword: $$ = &TimestampFuncExpr{Name:string("timestampdiff"), Unit:$3.String(), Expr1:$5, Expr2:$7} } -func_datetime_opt: +func_paren_opt: /* empty */ | openb closeb From e2e4450ade258e3c7a4e8850944eddf16a4eaabe Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 9 Mar 2021 17:37:53 -0800 Subject: [PATCH 092/310] healthcheck: update healthy tablets correctly when a stream returns an error or times out Signed-off-by: deepthi --- go/vt/discovery/healthcheck.go | 29 +++++++++++++------------- go/vt/discovery/healthcheck_test.go | 11 ++++++++++ go/vt/discovery/tablet_health_check.go | 15 +++++++++---- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 02eb035ea21..c672e88ac05 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -404,17 +404,17 @@ func (hc *HealthCheckImpl) deleteTablet(tablet *topodata.Tablet) { } } -func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, shr *query.StreamHealthResponse, currentTarget *query.Target, trivialNonMasterUpdate bool, isMasterUpdate bool, isMasterChange bool) { +func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.Target, trivialNonMasterUpdate bool, isMasterUpdate bool, isMasterChange bool) { // hc.healthByAlias is authoritative, it should be updated hc.mu.Lock() defer hc.mu.Unlock() - tabletAlias := tabletAliasString(topoproto.TabletAliasString(shr.TabletAlias)) - - hcErrorCounters.Add([]string{shr.Target.Keyspace, shr.Target.Shard, topoproto.TabletTypeLString(shr.Target.TabletType)}, 0) - targetKey := hc.keyFromTarget(shr.Target) - targetChanged := currentTarget.TabletType != shr.Target.TabletType || currentTarget.Keyspace != shr.Target.Keyspace || currentTarget.Shard != shr.Target.Shard + tabletAlias := tabletAliasString(topoproto.TabletAliasString(th.Tablet.Alias)) + targetKey := hc.keyFromTarget(th.Target) + targetChanged := currentTarget.TabletType != th.Target.TabletType || currentTarget.Keyspace != th.Target.Keyspace || currentTarget.Shard != th.Target.Shard if targetChanged { + // Error counter has to be set here in case we get a new tablet type for the first time in a stream response + hcErrorCounters.Add([]string{th.Target.Keyspace, th.Target.Shard, topoproto.TabletTypeLString(th.Target.TabletType)}, 0) // keyspace and shard are not expected to change, but just in case ... // move this tabletHealthCheck to the correct map oldTargetKey := hc.keyFromTarget(currentTarget) @@ -433,12 +433,12 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, shr *query.StreamHealt } else { // We already have one up server, see if we // need to replace it. - if shr.TabletExternallyReparentedTimestamp < hc.healthy[targetKey][0].MasterTermStartTime { + if th.MasterTermStartTime < hc.healthy[targetKey][0].MasterTermStartTime { log.Warningf("not marking healthy master %s as Up for %s because its MasterTermStartTime is smaller than the highest known timestamp from previous MASTERs %s: %d < %d ", - topoproto.TabletAliasString(shr.TabletAlias), - topoproto.KeyspaceShardString(shr.Target.Keyspace, shr.Target.Shard), + topoproto.TabletAliasString(th.Tablet.Alias), + topoproto.KeyspaceShardString(th.Target.Keyspace, th.Target.Shard), topoproto.TabletAliasString(hc.healthy[targetKey][0].Tablet.Alias), - shr.TabletExternallyReparentedTimestamp, + th.MasterTermStartTime, hc.healthy[targetKey][0].MasterTermStartTime) } else { // Just replace it. @@ -450,21 +450,20 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, shr *query.StreamHealt // We re-sort the healthy tablet list whenever we get a health update for tablets we can route to. // Tablets from other cells for non-master targets should not trigger a re-sort; // they should also be excluded from healthy list. - if shr.Target.TabletType != topodata.TabletType_MASTER && hc.isIncluded(shr.Target.TabletType, shr.TabletAlias) { + if th.Target.TabletType != topodata.TabletType_MASTER && hc.isIncluded(th.Target.TabletType, th.Tablet.Alias) { hc.recomputeHealthy(targetKey) } - if targetChanged && currentTarget.TabletType != topodata.TabletType_MASTER && hc.isIncluded(shr.Target.TabletType, shr.TabletAlias) { // also recompute old target's healthy list + if targetChanged && currentTarget.TabletType != topodata.TabletType_MASTER && hc.isIncluded(th.Target.TabletType, th.Tablet.Alias) { // also recompute old target's healthy list oldTargetKey := hc.keyFromTarget(currentTarget) hc.recomputeHealthy(oldTargetKey) } } if isMasterChange { - log.Errorf("Adding 1 to MasterPromoted counter for tablet: %v, shr.Tablet: %v, shr.TabletType: %v", currentTarget, topoproto.TabletAliasString(shr.TabletAlias), shr.Target.TabletType) - hcMasterPromotedCounters.Add([]string{shr.Target.Keyspace, shr.Target.Shard}, 1) + log.Errorf("Adding 1 to MasterPromoted counter for target: %v, tablet: %v, tabletType: %v", currentTarget, topoproto.TabletAliasString(th.Tablet.Alias), th.Target.TabletType) + hcMasterPromotedCounters.Add([]string{th.Target.Keyspace, th.Target.Shard}, 1) } // broadcast to subscribers hc.broadcast(th) - } func (hc *HealthCheckImpl) recomputeHealthy(key keyspaceShardTabletType) { diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index e2b4d125f29..3b4046b58b5 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -65,6 +65,8 @@ func init() { } func TestHealthCheck(t *testing.T) { + // reset error counters + hcErrorCounters.ResetAll() ts := memorytopo.NewServer("cell") hc := createTestHc(ts) // close healthcheck @@ -257,6 +259,9 @@ func TestHealthCheckStreamError(t *testing.T) { result = <-resultChan //TODO: figure out how to compare objects that contain errors using utils.MustMatch assert.True(t, want.DeepEqual(result), "Wrong TabletHealth data\n Expected: %v\n Actual: %v", want, result) + // tablet should be removed from healthy list + a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}) + assert.Empty(t, a, "wrong result, expected empty list") } func TestHealthCheckVerifiesTabletAlias(t *testing.T) { @@ -363,6 +368,8 @@ func TestHealthCheckCloseWaitsForGoRoutines(t *testing.T) { } func TestHealthCheckTimeout(t *testing.T) { + // reset counters + hcErrorCounters.ResetAll() ts := memorytopo.NewServer("cell") hc := createTestHc(ts) hc.healthCheckTimeout = 500 * time.Millisecond @@ -410,6 +417,10 @@ func TestHealthCheckTimeout(t *testing.T) { assert.Nil(t, checkErrorCounter("k", "s", topodatapb.TabletType_REPLICA, 1)) assert.True(t, fc.isCanceled(), "StreamHealth should be canceled after timeout, but is not") + // tablet should be removed from healthy list + a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}) + assert.Empty(t, a, "wrong result, expected empty list") + // repeat the wait. It will timeout one more time trying to get the connection. fc.resetCanceledFlag() time.Sleep(hc.healthCheckTimeout) diff --git a/go/vt/discovery/tablet_health_check.go b/go/vt/discovery/tablet_health_check.go index 4882ac39341..2f36f78e765 100644 --- a/go/vt/discovery/tablet_health_check.go +++ b/go/vt/discovery/tablet_health_check.go @@ -202,7 +202,7 @@ func (thc *tabletHealthCheck) processResponse(hc *HealthCheckImpl, shr *query.St thc.setServingState(serving, reason) // notify downstream for master change - hc.updateHealth(thc.SimpleCopy(), shr, currentTarget, trivialNonMasterUpdate, isMasterUpdate, isMasterChange) + hc.updateHealth(thc.SimpleCopy(), currentTarget, trivialNonMasterUpdate, isMasterUpdate, isMasterChange) return nil } @@ -241,6 +241,9 @@ func (thc *tabletHealthCheck) checkConn(hc *HealthCheckImpl) { hc.connsWG.Done() }() + // Initialize error counter + hcErrorCounters.Add([]string{thc.Target.Keyspace, thc.Target.Shard, topoproto.TabletTypeLString(thc.Target.TabletType)}, 0) + retryDelay := hc.retryDelay for { streamCtx, streamCancel := context.WithCancel(thc.ctx) @@ -287,12 +290,14 @@ func (thc *tabletHealthCheck) checkConn(hc *HealthCheckImpl) { streamCancel() if err != nil { + hcErrorCounters.Add([]string{thc.Target.Keyspace, thc.Target.Shard, topoproto.TabletTypeLString(thc.Target.TabletType)}, 1) if strings.Contains(err.Error(), "health stats mismatch") { hc.deleteTablet(thc.Tablet) return } - res := thc.SimpleCopy() - hc.broadcast(res) + // trivialNonMasterUpdate = false because this is an error + // It is safe to pass isMasterChange = false because in case of an error there is no information that can be used to update the master + hc.updateHealth(thc.SimpleCopy(), thc.Target, false, thc.Target.TabletType == topodata.TabletType_MASTER, false) } // If there was a timeout send an error. We do this after stream has returned. // This will ensure that this update prevails over any previous message that @@ -301,7 +306,9 @@ func (thc *tabletHealthCheck) checkConn(hc *HealthCheckImpl) { thc.LastError = fmt.Errorf("healthcheck timed out (latest %v)", thc.lastResponseTimestamp) thc.setServingState(false, thc.LastError.Error()) hcErrorCounters.Add([]string{thc.Target.Keyspace, thc.Target.Shard, topoproto.TabletTypeLString(thc.Target.TabletType)}, 1) - hc.broadcast(thc.SimpleCopy()) + // trivialNonMasterUpdate = false because this is an error + // It is safe to pass isMasterChange = false because in case of timeout there is no information that can be used to update the master + hc.updateHealth(thc.SimpleCopy(), thc.Target, false, thc.Target.TabletType == topodata.TabletType_MASTER, false) } // Streaming RPC failed e.g. because vttablet was restarted or took too long. From a83d30e481e2ac7d004cbeac2fa89b2c63b4cf4d Mon Sep 17 00:00:00 2001 From: deepthi Date: Wed, 10 Mar 2021 17:34:38 -0800 Subject: [PATCH 093/310] healthcheck: remove PRIMARY from healthy list when there's an error or timeout from healthcheck stream Signed-off-by: deepthi --- go/vt/discovery/healthcheck.go | 41 ++++++++++-------- go/vt/discovery/healthcheck_test.go | 60 ++++++++++++++++++++++++++ go/vt/discovery/tablet_health_check.go | 18 ++++---- 3 files changed, 91 insertions(+), 28 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index c672e88ac05..f091a13a441 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -404,7 +404,7 @@ func (hc *HealthCheckImpl) deleteTablet(tablet *topodata.Tablet) { } } -func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.Target, trivialNonMasterUpdate bool, isMasterUpdate bool, isMasterChange bool) { +func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.Target, trivialUpdate bool, isPrimaryUp bool) { // hc.healthByAlias is authoritative, it should be updated hc.mu.Lock() defer hc.mu.Unlock() @@ -427,26 +427,31 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.T // add it to the map by target hc.healthData[targetKey][tabletAlias] = th - if isMasterUpdate { - if len(hc.healthy[targetKey]) == 0 { - hc.healthy[targetKey] = append(hc.healthy[targetKey], th) - } else { - // We already have one up server, see if we - // need to replace it. - if th.MasterTermStartTime < hc.healthy[targetKey][0].MasterTermStartTime { - log.Warningf("not marking healthy master %s as Up for %s because its MasterTermStartTime is smaller than the highest known timestamp from previous MASTERs %s: %d < %d ", - topoproto.TabletAliasString(th.Tablet.Alias), - topoproto.KeyspaceShardString(th.Target.Keyspace, th.Target.Shard), - topoproto.TabletAliasString(hc.healthy[targetKey][0].Tablet.Alias), - th.MasterTermStartTime, - hc.healthy[targetKey][0].MasterTermStartTime) + if th.Target.TabletType == topodata.TabletType_MASTER { + if isPrimaryUp { + if len(hc.healthy[targetKey]) == 0 { + hc.healthy[targetKey] = append(hc.healthy[targetKey], th) } else { - // Just replace it. - hc.healthy[targetKey][0] = th + // We already have one up server, see if we + // need to replace it. + if th.MasterTermStartTime < hc.healthy[targetKey][0].MasterTermStartTime { + log.Warningf("not marking healthy master %s as Up for %s because its MasterTermStartTime is smaller than the highest known timestamp from previous MASTERs %s: %d < %d ", + topoproto.TabletAliasString(th.Tablet.Alias), + topoproto.KeyspaceShardString(th.Target.Keyspace, th.Target.Shard), + topoproto.TabletAliasString(hc.healthy[targetKey][0].Tablet.Alias), + th.MasterTermStartTime, + hc.healthy[targetKey][0].MasterTermStartTime) + } else { + // Just replace it. + hc.healthy[targetKey][0] = th + } } + } else { + // No healthy master tablet + hc.healthy[targetKey] = []*TabletHealth{} } } - if !trivialNonMasterUpdate { + if !trivialUpdate { // We re-sort the healthy tablet list whenever we get a health update for tablets we can route to. // Tablets from other cells for non-master targets should not trigger a re-sort; // they should also be excluded from healthy list. @@ -458,7 +463,7 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.T hc.recomputeHealthy(oldTargetKey) } } - if isMasterChange { + if currentTarget.TabletType != topodata.TabletType_MASTER && th.Target.TabletType == topodata.TabletType_MASTER { log.Errorf("Adding 1 to MasterPromoted counter for target: %v, tablet: %v, tabletType: %v", currentTarget, topoproto.TabletAliasString(th.Tablet.Alias), th.Target.TabletType) hcMasterPromotedCounters.Add([]string{th.Target.Keyspace, th.Target.Shard}, 1) } diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index 3b4046b58b5..2d554ab2cf2 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -264,6 +264,66 @@ func TestHealthCheckStreamError(t *testing.T) { assert.Empty(t, a, "wrong result, expected empty list") } +// TestHealthCheckErrorOnPrimary is the same as TestHealthCheckStreamError except for tablet type +func TestHealthCheckErrorOnPrimary(t *testing.T) { + ts := memorytopo.NewServer("cell") + hc := createTestHc(ts) + defer hc.Close() + + tablet := createTestTablet(0, "cell", "a") + input := make(chan *querypb.StreamHealthResponse) + resultChan := hc.Subscribe() + fc := createFakeConn(tablet, input) + fc.errCh = make(chan error) + hc.AddTablet(tablet) + + // Immediately after AddTablet() there will be the first notification. + want := &TabletHealth{ + Tablet: tablet, + Target: &querypb.Target{Keyspace: "k", Shard: "s"}, + Serving: false, + MasterTermStartTime: 0, + } + result := <-resultChan + mustMatch(t, want, result, "Wrong TabletHealth data") + + // one tablet after receiving a StreamHealthResponse + shr := &querypb.StreamHealthResponse{ + TabletAlias: tablet.Alias, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + TabletExternallyReparentedTimestamp: 10, + RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 1, CpuUsage: 0.2}, + } + want = &TabletHealth{ + Tablet: tablet, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 1, CpuUsage: 0.2}, + MasterTermStartTime: 10, + } + input <- shr + result = <-resultChan + mustMatch(t, want, result, "Wrong TabletHealth data") + + // Stream error + fc.errCh <- fmt.Errorf("some stream error") + want = &TabletHealth{ + Tablet: tablet, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: false, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 1, CpuUsage: 0.2}, + MasterTermStartTime: 10, + LastError: fmt.Errorf("some stream error"), + } + result = <-resultChan + //TODO: figure out how to compare objects that contain errors using utils.MustMatch + assert.True(t, want.DeepEqual(result), "Wrong TabletHealth data\n Expected: %v\n Actual: %v", want, result) + // tablet should be removed from healthy list + a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}) + assert.Empty(t, a, "wrong result, expected empty list") +} + func TestHealthCheckVerifiesTabletAlias(t *testing.T) { ts := memorytopo.NewServer("cell") hc := createTestHc(ts) diff --git a/go/vt/discovery/tablet_health_check.go b/go/vt/discovery/tablet_health_check.go index 2f36f78e765..c008d2f162f 100644 --- a/go/vt/discovery/tablet_health_check.go +++ b/go/vt/discovery/tablet_health_check.go @@ -186,10 +186,8 @@ func (thc *tabletHealthCheck) processResponse(hc *HealthCheckImpl, shr *query.St currentTarget := thc.Target // check whether this is a trivial update so as to update healthy map - trivialNonMasterUpdate := thc.LastError == nil && thc.Serving && shr.RealtimeStats.HealthError == "" && shr.Serving && + trivialUpdate := thc.LastError == nil && thc.Serving && shr.RealtimeStats.HealthError == "" && shr.Serving && currentTarget.TabletType != topodata.TabletType_MASTER && currentTarget.TabletType == shr.Target.TabletType && thc.isTrivialReplagChange(shr.RealtimeStats) - isMasterUpdate := shr.Target.TabletType == topodata.TabletType_MASTER - isMasterChange := thc.Target.TabletType != topodata.TabletType_MASTER && shr.Target.TabletType == topodata.TabletType_MASTER thc.lastResponseTimestamp = time.Now() thc.Target = shr.Target thc.MasterTermStartTime = shr.TabletExternallyReparentedTimestamp @@ -202,7 +200,7 @@ func (thc *tabletHealthCheck) processResponse(hc *HealthCheckImpl, shr *query.St thc.setServingState(serving, reason) // notify downstream for master change - hc.updateHealth(thc.SimpleCopy(), currentTarget, trivialNonMasterUpdate, isMasterUpdate, isMasterChange) + hc.updateHealth(thc.SimpleCopy(), currentTarget, trivialUpdate, true) return nil } @@ -295,9 +293,9 @@ func (thc *tabletHealthCheck) checkConn(hc *HealthCheckImpl) { hc.deleteTablet(thc.Tablet) return } - // trivialNonMasterUpdate = false because this is an error - // It is safe to pass isMasterChange = false because in case of an error there is no information that can be used to update the master - hc.updateHealth(thc.SimpleCopy(), thc.Target, false, thc.Target.TabletType == topodata.TabletType_MASTER, false) + // trivialUpdate = false because this is an error + // isPrimaryUp = false because we did not get a healthy response + hc.updateHealth(thc.SimpleCopy(), thc.Target, false, false) } // If there was a timeout send an error. We do this after stream has returned. // This will ensure that this update prevails over any previous message that @@ -306,9 +304,9 @@ func (thc *tabletHealthCheck) checkConn(hc *HealthCheckImpl) { thc.LastError = fmt.Errorf("healthcheck timed out (latest %v)", thc.lastResponseTimestamp) thc.setServingState(false, thc.LastError.Error()) hcErrorCounters.Add([]string{thc.Target.Keyspace, thc.Target.Shard, topoproto.TabletTypeLString(thc.Target.TabletType)}, 1) - // trivialNonMasterUpdate = false because this is an error - // It is safe to pass isMasterChange = false because in case of timeout there is no information that can be used to update the master - hc.updateHealth(thc.SimpleCopy(), thc.Target, false, thc.Target.TabletType == topodata.TabletType_MASTER, false) + // trivialUpdate = false because this is an error + // isPrimaryUp = false because we did not get a healthy response within the timeout + hc.updateHealth(thc.SimpleCopy(), thc.Target, false, false) } // Streaming RPC failed e.g. because vttablet was restarted or took too long. From c3693f85c7aa1f9e70981a00e7d14d71b4cb3aa1 Mon Sep 17 00:00:00 2001 From: deepthi Date: Thu, 11 Mar 2021 17:35:43 -0800 Subject: [PATCH 094/310] healthcheck: reorganize code to be more readable Signed-off-by: deepthi --- go/vt/discovery/healthcheck.go | 58 ++++++++++++++------------ go/vt/discovery/healthcheck_test.go | 2 +- go/vt/discovery/tablet_health_check.go | 6 +-- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index f091a13a441..4af9dfd7202 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -404,20 +404,20 @@ func (hc *HealthCheckImpl) deleteTablet(tablet *topodata.Tablet) { } } -func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.Target, trivialUpdate bool, isPrimaryUp bool) { +func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, prevTarget *query.Target, trivialUpdate bool, isPrimaryUp bool) { // hc.healthByAlias is authoritative, it should be updated hc.mu.Lock() defer hc.mu.Unlock() tabletAlias := tabletAliasString(topoproto.TabletAliasString(th.Tablet.Alias)) targetKey := hc.keyFromTarget(th.Target) - targetChanged := currentTarget.TabletType != th.Target.TabletType || currentTarget.Keyspace != th.Target.Keyspace || currentTarget.Shard != th.Target.Shard + targetChanged := prevTarget.TabletType != th.Target.TabletType || prevTarget.Keyspace != th.Target.Keyspace || prevTarget.Shard != th.Target.Shard if targetChanged { // Error counter has to be set here in case we get a new tablet type for the first time in a stream response hcErrorCounters.Add([]string{th.Target.Keyspace, th.Target.Shard, topoproto.TabletTypeLString(th.Target.TabletType)}, 0) // keyspace and shard are not expected to change, but just in case ... // move this tabletHealthCheck to the correct map - oldTargetKey := hc.keyFromTarget(currentTarget) + oldTargetKey := hc.keyFromTarget(prevTarget) delete(hc.healthData[oldTargetKey], tabletAlias) _, ok := hc.healthData[targetKey] if !ok { @@ -427,30 +427,31 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.T // add it to the map by target hc.healthData[targetKey][tabletAlias] = th - if th.Target.TabletType == topodata.TabletType_MASTER { - if isPrimaryUp { - if len(hc.healthy[targetKey]) == 0 { - hc.healthy[targetKey] = append(hc.healthy[targetKey], th) + isPrimary := th.Target.TabletType == topodata.TabletType_MASTER + switch { + case isPrimary && isPrimaryUp: + if len(hc.healthy[targetKey]) == 0 { + hc.healthy[targetKey] = append(hc.healthy[targetKey], th) + } else { + // We already have one up server, see if we + // need to replace it. + if th.MasterTermStartTime < hc.healthy[targetKey][0].MasterTermStartTime { + log.Warningf("not marking healthy master %s as Up for %s because its MasterTermStartTime is smaller than the highest known timestamp from previous MASTERs %s: %d < %d ", + topoproto.TabletAliasString(th.Tablet.Alias), + topoproto.KeyspaceShardString(th.Target.Keyspace, th.Target.Shard), + topoproto.TabletAliasString(hc.healthy[targetKey][0].Tablet.Alias), + th.MasterTermStartTime, + hc.healthy[targetKey][0].MasterTermStartTime) } else { - // We already have one up server, see if we - // need to replace it. - if th.MasterTermStartTime < hc.healthy[targetKey][0].MasterTermStartTime { - log.Warningf("not marking healthy master %s as Up for %s because its MasterTermStartTime is smaller than the highest known timestamp from previous MASTERs %s: %d < %d ", - topoproto.TabletAliasString(th.Tablet.Alias), - topoproto.KeyspaceShardString(th.Target.Keyspace, th.Target.Shard), - topoproto.TabletAliasString(hc.healthy[targetKey][0].Tablet.Alias), - th.MasterTermStartTime, - hc.healthy[targetKey][0].MasterTermStartTime) - } else { - // Just replace it. - hc.healthy[targetKey][0] = th - } + // Just replace it. + hc.healthy[targetKey][0] = th } - } else { - // No healthy master tablet - hc.healthy[targetKey] = []*TabletHealth{} } + case isPrimary && !isPrimaryUp: + // No healthy master tablet + hc.healthy[targetKey] = []*TabletHealth{} } + if !trivialUpdate { // We re-sort the healthy tablet list whenever we get a health update for tablets we can route to. // Tablets from other cells for non-master targets should not trigger a re-sort; @@ -458,15 +459,18 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, currentTarget *query.T if th.Target.TabletType != topodata.TabletType_MASTER && hc.isIncluded(th.Target.TabletType, th.Tablet.Alias) { hc.recomputeHealthy(targetKey) } - if targetChanged && currentTarget.TabletType != topodata.TabletType_MASTER && hc.isIncluded(th.Target.TabletType, th.Tablet.Alias) { // also recompute old target's healthy list - oldTargetKey := hc.keyFromTarget(currentTarget) + if targetChanged && prevTarget.TabletType != topodata.TabletType_MASTER && hc.isIncluded(th.Target.TabletType, th.Tablet.Alias) { // also recompute old target's healthy list + oldTargetKey := hc.keyFromTarget(prevTarget) hc.recomputeHealthy(oldTargetKey) } } - if currentTarget.TabletType != topodata.TabletType_MASTER && th.Target.TabletType == topodata.TabletType_MASTER { - log.Errorf("Adding 1 to MasterPromoted counter for target: %v, tablet: %v, tabletType: %v", currentTarget, topoproto.TabletAliasString(th.Tablet.Alias), th.Target.TabletType) + + isNewPrimary := isPrimary && prevTarget.TabletType != topodata.TabletType_MASTER + if isNewPrimary { + log.Errorf("Adding 1 to MasterPromoted counter for target: %v, tablet: %v, tabletType: %v", prevTarget, topoproto.TabletAliasString(th.Tablet.Alias), th.Target.TabletType) hcMasterPromotedCounters.Add([]string{th.Target.Keyspace, th.Target.Shard}, 1) } + // broadcast to subscribers hc.broadcast(th) } diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index 2d554ab2cf2..73ba30a665f 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -869,7 +869,7 @@ func TestMasterInOtherCell(t *testing.T) { // check that MASTER tablet from other cell IS in healthy tablet list a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}) - assert.Len(t, a, 1, "") + require.Len(t, a, 1, "") mustMatch(t, want, a[0], "Expecting healthy master") } diff --git a/go/vt/discovery/tablet_health_check.go b/go/vt/discovery/tablet_health_check.go index c008d2f162f..664e1924870 100644 --- a/go/vt/discovery/tablet_health_check.go +++ b/go/vt/discovery/tablet_health_check.go @@ -184,10 +184,10 @@ func (thc *tabletHealthCheck) processResponse(hc *HealthCheckImpl, shr *query.St return vterrors.New(vtrpc.Code_FAILED_PRECONDITION, fmt.Sprintf("health stats mismatch, tablet %+v alias does not match response alias %v", thc.Tablet, shr.TabletAlias)) } - currentTarget := thc.Target + prevTarget := thc.Target // check whether this is a trivial update so as to update healthy map trivialUpdate := thc.LastError == nil && thc.Serving && shr.RealtimeStats.HealthError == "" && shr.Serving && - currentTarget.TabletType != topodata.TabletType_MASTER && currentTarget.TabletType == shr.Target.TabletType && thc.isTrivialReplagChange(shr.RealtimeStats) + prevTarget.TabletType != topodata.TabletType_MASTER && prevTarget.TabletType == shr.Target.TabletType && thc.isTrivialReplagChange(shr.RealtimeStats) thc.lastResponseTimestamp = time.Now() thc.Target = shr.Target thc.MasterTermStartTime = shr.TabletExternallyReparentedTimestamp @@ -200,7 +200,7 @@ func (thc *tabletHealthCheck) processResponse(hc *HealthCheckImpl, shr *query.St thc.setServingState(serving, reason) // notify downstream for master change - hc.updateHealth(thc.SimpleCopy(), currentTarget, trivialUpdate, true) + hc.updateHealth(thc.SimpleCopy(), prevTarget, trivialUpdate, true) return nil } From c343360f4dbf159f06d81cd0618e64adc6d7281b Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 23 Mar 2021 15:02:11 +0100 Subject: [PATCH 095/310] make sure to handle subqueries on top of subqueries Signed-off-by: Andres Taylor Signed-off-by: Harshit Gangal --- go/test/endtoend/vtgate/misc_test.go | 14 ++++++ .../multi-output/selectsharded-output.txt | 6 +++ .../testdata/selectsharded-queries.sql | 2 + go/vt/vtgate/planbuilder/filtering.go | 4 +- .../planbuilder/testdata/filter_cases.txt | 47 ++++++++++++++----- 5 files changed, 59 insertions(+), 14 deletions(-) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 415d67a2840..09a075556ae 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -496,6 +496,20 @@ func TestCreateView(t *testing.T) { assertMatches(t, conn, "select * from v1", `[[INT64(1) INT64(1)] [INT64(2) INT64(2)] [INT64(3) INT64(3)] [INT64(4) INT64(4)] [INT64(5) INT64(5)]]`) } +func TestSubQueryOnTopOfSubQuery(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + defer exec(t, conn, `delete from t1`) + + exec(t, conn, `insert into t1(id1, id2) values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5)`) + exec(t, conn, `insert into t2(id3, id4) values (1, 3), (2, 4)`) + + assertMatches(t, conn, "select id1 from t1 where id1 not in (select id3 from t2) and id2 in (select id4 from t2)", `[[INT64(3)] [INT64(4)]]`) +} + func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index ccad1126651..f17fa13e4cc 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -166,3 +166,9 @@ select id, 'abc' as test from user where id = 1 union all select id, 'def' as te 1 ks_sharded/-40: select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 limit 10001 /* union all */ ---------------------------------------------------------------------- +select id from user where not id in (select col from music where music.user_id = 42) and id in (select col from music where music.user_id = 411) + +1 ks_sharded/40-80: select col from music where music.user_id = 42 limit 10001 +2 ks_sharded/40-80: select col from music where music.user_id = 411 limit 10001 + +---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index e2fdfc3171e..a32e1a6cd21 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -32,3 +32,5 @@ select id, case when name = 'alice' then 'ALICE' when name = 'bob' then 'BOB' el select id, case when substr(name, 1, 5) = 'alice' then 'ALICE' when name = 'bob' then 'BOB' else 'OTHER' end as name from user where id = 1 /* select case */; select id, 'abc' as test from user where id = 1 union all select id, 'def' as test from user where id = 1 union all select id, 'ghi' as test from user where id = 1 /* union all */; + +select id from user where not id in (select col from music where music.user_id = 42) and id in (select col from music where music.user_id = 411); diff --git a/go/vt/vtgate/planbuilder/filtering.go b/go/vt/vtgate/planbuilder/filtering.go index 4e22a3cdbc6..1e085f09ca6 100644 --- a/go/vt/vtgate/planbuilder/filtering.go +++ b/go/vt/vtgate/planbuilder/filtering.go @@ -64,7 +64,9 @@ func planFilter(pb *primitiveBuilder, input logicalPlan, filter sqlparser.Expr, node.UpdatePlan(pb, filter) return node, nil case *pulloutSubquery: - return planFilter(pb, node.underlying, filter, whereType, origin) + plan, err := planFilter(pb, node.underlying, filter, whereType, origin) + node.underlying = plan + return node, err case *vindexFunc: return filterVindexFunc(node, filter) case *subquery: diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt index 038e498bc60..a2ba4862a31 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt @@ -1799,19 +1799,40 @@ "Vindex": "user_index" }, { - "OperatorType": "Route", - "Variant": "SelectIN", - "Keyspace": { - "Name": "user", - "Sharded": true - }, - "FieldQuery": "select id from user where 1 != 1", - "Query": "select id from user where :__sq_has_values1 = 1 and id in ::__vals and not (:__sq_has_values2 = 1 and id in ::__sq2)", - "Table": "user", - "Values": [ - "::__sq1" - ], - "Vindex": "user_index" + "OperatorType": "Subquery", + "Variant": "PulloutIn", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "SelectEqualUnique", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select user_extra.col from user_extra where 1 != 1", + "Query": "select user_extra.col from user_extra where user_extra.user_id = 411", + "Table": "user_extra", + "Values": [ + 411 + ], + "Vindex": "user_index" + }, + { + "OperatorType": "Route", + "Variant": "SelectIN", + "Keyspace": { + "Name": "user", + "Sharded": true + }, + "FieldQuery": "select id from user where 1 != 1", + "Query": "select id from user where :__sq_has_values1 = 1 and id in ::__vals and not (:__sq_has_values2 = 1 and id in ::__sq2)", + "Table": "user", + "Values": [ + "::__sq1" + ], + "Vindex": "user_index" + } + ] } ] } From 61e13d2728b6959496b9bec521957e79e136ce38 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 25 Mar 2021 14:31:16 +0100 Subject: [PATCH 096/310] check error before returning Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/filtering.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/planbuilder/filtering.go b/go/vt/vtgate/planbuilder/filtering.go index 1e085f09ca6..6b442a2f169 100644 --- a/go/vt/vtgate/planbuilder/filtering.go +++ b/go/vt/vtgate/planbuilder/filtering.go @@ -65,8 +65,11 @@ func planFilter(pb *primitiveBuilder, input logicalPlan, filter sqlparser.Expr, return node, nil case *pulloutSubquery: plan, err := planFilter(pb, node.underlying, filter, whereType, origin) + if err != nil { + return nil, err + } node.underlying = plan - return node, err + return node, nil case *vindexFunc: return filterVindexFunc(node, filter) case *subquery: From ca705e6f454beca42ef2376ad792d37b93fee7a9 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 1 Apr 2021 08:23:20 +0200 Subject: [PATCH 097/310] make sure to not log sensitive information Signed-off-by: Andres Taylor --- go/vt/vtgate/executor.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index dec82d79380..994e28386c4 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -157,7 +157,11 @@ func (e *Executor) Execute(ctx context.Context, method string, safeSession *Safe saveSessionStats(safeSession, stmtType, result, err) if result != nil && len(result.Rows) > *warnMemoryRows { warnings.Add("ResultsExceeded", 1) - log.Warningf("%q exceeds warning threshold of max memory rows: %v", sql, *warnMemoryRows) + piiSafeSQL, err := sqlparser.RedactSQLQuery(sql) + if err != nil { + piiSafeSQL = sqlparser.Preview(sql).String() + } + log.Warningf("%q exceeds warning threshold of max memory rows: %v", piiSafeSQL, *warnMemoryRows) } logStats.Send() From b720ad09200eba5430caab8a0e9bcb75296575ca Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 1 Apr 2021 15:27:00 +0530 Subject: [PATCH 098/310] addressed review comments Signed-off-by: Harshit Gangal --- go/vt/vtgate/executor.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/executor.go b/go/vt/vtgate/executor.go index 994e28386c4..6a23241d200 100644 --- a/go/vt/vtgate/executor.go +++ b/go/vt/vtgate/executor.go @@ -159,7 +159,7 @@ func (e *Executor) Execute(ctx context.Context, method string, safeSession *Safe warnings.Add("ResultsExceeded", 1) piiSafeSQL, err := sqlparser.RedactSQLQuery(sql) if err != nil { - piiSafeSQL = sqlparser.Preview(sql).String() + piiSafeSQL = logStats.StmtType } log.Warningf("%q exceeds warning threshold of max memory rows: %v", piiSafeSQL, *warnMemoryRows) } From 34d9f9502edea039ac149df06fdf678841df95bf Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Tue, 6 Apr 2021 13:21:55 +0200 Subject: [PATCH 099/310] make: build vitess as static binaries by default Signed-off-by: Vicent Marti --- Makefile | 18 ++++++++++++++++-- go.sum | 6 ++++++ go/cmd/vtorc/main.go | 3 +++ go/vt/orchestrator/db/db.go | 6 ++++-- .../external/golib/sqlutils/sqlutils.go | 3 --- go/vt/orchestrator/inst/cluster_test.go | 2 ++ 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 1014fed006e..f84918bb2e1 100644 --- a/Makefile +++ b/Makefile @@ -53,13 +53,27 @@ embed_config: go run github.com/GeertJohan/go.rice/rice embed-go go build . +# build the vitess binaries with dynamic dependency on libc +build-dyn: +ifndef NOBANNER + echo $$(date): Building source tree +endif + bash ./build.env + go install $(EXTRA_BUILD_FLAGS) $(VT_GO_PARALLEL) -ldflags "$(shell tools/build_version_flags.sh)" ./go/... + (cd go/cmd/vttablet && go run github.com/GeertJohan/go.rice/rice append --exec=../../../bin/vttablet) + +# build the vitess binaries statically build: ifndef NOBANNER echo $$(date): Building source tree endif bash ./build.env - go install $(EXTRA_BUILD_FLAGS) $(VT_GO_PARALLEL) -ldflags "$(shell tools/build_version_flags.sh)" ./go/... && \ - (cd go/cmd/vttablet && go run github.com/GeertJohan/go.rice/rice append --exec=../../../bin/vttablet) + # build all the binaries by default with CGO disabled + CGO_ENABLED=0 go install $(EXTRA_BUILD_FLAGS) $(VT_GO_PARALLEL) -ldflags "$(shell tools/build_version_flags.sh)" ./go/... + # embed local resources in the vttablet executable + (cd go/cmd/vttablet && go run github.com/GeertJohan/go.rice/rice append --exec=../../../bin/vttablet) + # build vtorc with CGO, because it depends on sqlite + CGO_ENABLED=1 go install $(EXTRA_BUILD_FLAGS) $(VT_GO_PARALLEL) -ldflags "$(shell tools/build_version_flags.sh)" ./go/cmd/vtorc/... debug: ifndef NOBANNER diff --git a/go.sum b/go.sum index 6db476c5fad..ab90da07441 100644 --- a/go.sum +++ b/go.sum @@ -52,6 +52,7 @@ github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e h1:4ZrkT/RzpnRO github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k= github.com/DataDog/datadog-go v2.2.0+incompatible h1:V5BKkxACZLjzHjSgBbr2gvLA2Ae49yhc6CSY7MLy5k4= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/GeertJohan/go.incremental v1.0.0 h1:7AH+pY1XUgQE4Y1HcXYaMqAI0m9yrFqo/jt0CW30vsg= github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= @@ -75,6 +76,7 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f h1:HR5nRmUQgXrwqZOwZ2DAc/aCi3Bu3xENpspW935vxu0= github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f/go.mod h1:f3HiCrHjHBdcm6E83vGaXh1KomZMA2P6aeo3hKx/wg0= github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/akavel/rsrc v0.8.0 h1:zjWn7ukO9Kc5Q62DOJCcxGpXC18RawVtYAGdz2aLlfw= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= @@ -407,6 +409,7 @@ github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -529,6 +532,7 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/ngdinhtoan/glide-cleanup v0.2.0/go.mod h1:UQzsmiDOb8YV3nOsCxK/c9zPpCZVNoHScRE3EO9pVMM= +github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229 h1:E2B8qYyeSgv5MXpmzZXRNp8IAQ4vjxIjhpAf5hv/tAg= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481 h1:Up6+btDp321ZG5/zdSLo48H9Iaq0UQGthrhWC6pCxzE= github.com/nozzle/throttler v0.0.0-20180817012639-2ea982251481/go.mod h1:yKZQO8QE2bHlgozqWDiRVqTFlLQSj30K/6SAK8EeYFw= @@ -694,7 +698,9 @@ github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6 github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= diff --git a/go/cmd/vtorc/main.go b/go/cmd/vtorc/main.go index 19c7063f233..e64ced875d0 100644 --- a/go/cmd/vtorc/main.go +++ b/go/cmd/vtorc/main.go @@ -19,6 +19,9 @@ package main import ( "flag" + _ "github.com/go-sql-driver/mysql" + _ "github.com/mattn/go-sqlite3" + "vitess.io/vitess/go/vt/orchestrator/app" "vitess.io/vitess/go/vt/orchestrator/config" "vitess.io/vitess/go/vt/orchestrator/external/golib/log" diff --git a/go/vt/orchestrator/db/db.go b/go/vt/orchestrator/db/db.go index 8472840569b..680d982a0c2 100644 --- a/go/vt/orchestrator/db/db.go +++ b/go/vt/orchestrator/db/db.go @@ -133,8 +133,10 @@ func OpenOrchestrator() (db *sql.DB, err error) { if err == nil && !fromCache { log.Debugf("Connected to orchestrator backend: sqlite on %v", config.Config.SQLite3DataFile) } - db.SetMaxOpenConns(1) - db.SetMaxIdleConns(1) + if db != nil { + db.SetMaxOpenConns(1) + db.SetMaxIdleConns(1) + } } else { if db, fromCache, err := openOrchestratorMySQLGeneric(); err != nil { return db, log.Errore(err) diff --git a/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go b/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go index a0f7209627e..74bfee3beff 100644 --- a/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go +++ b/go/vt/orchestrator/external/golib/sqlutils/sqlutils.go @@ -25,9 +25,6 @@ import ( "sync" "time" - _ "github.com/go-sql-driver/mysql" - _ "github.com/mattn/go-sqlite3" - "vitess.io/vitess/go/vt/orchestrator/external/golib/log" ) diff --git a/go/vt/orchestrator/inst/cluster_test.go b/go/vt/orchestrator/inst/cluster_test.go index 27b7f212aa4..640e89ab4af 100644 --- a/go/vt/orchestrator/inst/cluster_test.go +++ b/go/vt/orchestrator/inst/cluster_test.go @@ -21,6 +21,8 @@ import ( "testing" + _ "github.com/mattn/go-sqlite3" + "vitess.io/vitess/go/vt/orchestrator/config" "vitess.io/vitess/go/vt/orchestrator/external/golib/log" test "vitess.io/vitess/go/vt/orchestrator/external/golib/tests" From 8331e0339fc126b64ceaaee445720097aa0fdd63 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Sun, 18 Apr 2021 08:27:08 +0300 Subject: [PATCH 100/310] Add vtctldclient in binary packages Signed-off-by: Alkin Tezuysal --- tools/make-release-packages.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/make-release-packages.sh b/tools/make-release-packages.sh index 24f19641a60..d33eb9d3b6b 100755 --- a/tools/make-release-packages.sh +++ b/tools/make-release-packages.sh @@ -35,7 +35,7 @@ mkdir -p releases # Copy a subset of binaries from issue #5421 mkdir -p "${RELEASE_DIR}/bin" -for binary in vttestserver mysqlctl mysqlctld query_analyzer topo2topo vtaclcheck vtbackup vtbench vtclient vtcombo vtctl vtctlclient vtctld vtexplain vtgate vttablet vtorc vtworker vtworkerclient zk zkctl zkctld; do +for binary in vttestserver mysqlctl mysqlctld query_analyzer topo2topo vtaclcheck vtbackup vtbench vtclient vtcombo vtctl vtctldclient vtctlclient vtctld vtexplain vtgate vttablet vtorc vtworker vtworkerclient zk zkctl zkctld; do cp "bin/$binary" "${RELEASE_DIR}/bin/" done; From b1f9ae971b584aac281c5adf2e6932064c1366b8 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Wed, 21 Apr 2021 20:32:18 +0300 Subject: [PATCH 101/310] backport: upgrade tests vs v9 (#7899) * backport: upgrade tests vs v9 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * backport CI /etc/hosts fix Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * reintroducing port-range patch Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * reintroducing port-range patch Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * empty commit to kick CI Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * patch OS fo rupgrade test Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * patches around various additional tests Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * empty commit to kick CI Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> * empty commit to kick CI Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .github/workflows/cluster_endtoend_11.yml | 10 +++++ .github/workflows/cluster_endtoend_12.yml | 10 +++++ .github/workflows/cluster_endtoend_13.yml | 10 +++++ .github/workflows/cluster_endtoend_14.yml | 10 +++++ .github/workflows/cluster_endtoend_15.yml | 10 +++++ .github/workflows/cluster_endtoend_16.yml | 10 +++++ .github/workflows/cluster_endtoend_17.yml | 10 +++++ .github/workflows/cluster_endtoend_18.yml | 10 +++++ .github/workflows/cluster_endtoend_19.yml | 10 +++++ .github/workflows/cluster_endtoend_20.yml | 10 +++++ .github/workflows/cluster_endtoend_21.yml | 10 +++++ .github/workflows/cluster_endtoend_22.yml | 10 +++++ .github/workflows/cluster_endtoend_23.yml | 10 +++++ .github/workflows/cluster_endtoend_24.yml | 10 +++++ .github/workflows/cluster_endtoend_26.yml | 10 +++++ .github/workflows/cluster_endtoend_27.yml | 10 +++++ ...cluster_endtoend_onlineddl_declarative.yml | 10 +++++ .../cluster_endtoend_onlineddl_ghost.yml | 10 +++++ .../cluster_endtoend_onlineddl_revert.yml | 10 +++++ .../cluster_endtoend_onlineddl_vrepl.yml | 10 +++++ ...luster_endtoend_onlineddl_vrepl_stress.yml | 10 +++++ ...uster_endtoend_tabletmanager_throttler.yml | 12 +++++- ..._tabletmanager_throttler_custom_config.yml | 12 +++++- .../workflows/cluster_endtoend_upgrade.yml | 38 ++++++++++++------- .../cluster_endtoend_vreplication_basic.yml | 10 +++++ ...luster_endtoend_vreplication_cellalias.yml | 10 +++++ .../cluster_endtoend_vreplication_migrate.yml | 10 +++++ ...luster_endtoend_vreplication_multicell.yml | 10 +++++ .../cluster_endtoend_vreplication_v2.yml | 10 +++++ .../cluster_initial_sharding_multi.yml | 10 +++++ .github/workflows/e2e_race.yml | 10 +++++ .github/workflows/endtoend.yml | 10 +++++ .github/workflows/legacy_local_example.yml | 10 +++++ .github/workflows/local_example.yml | 10 +++++ .github/workflows/region_example.yml | 10 +++++ .github/workflows/unit_race.yml | 10 +++++ .github/workflows/unit_test_mariadb101.yml | 10 +++++ .github/workflows/unit_test_mariadb102.yml | 10 +++++ .github/workflows/unit_test_mariadb103.yml | 10 +++++ .github/workflows/unit_test_mysql57.yml | 10 +++++ .github/workflows/unit_test_mysql80.yml | 10 +++++ .github/workflows/unit_test_percona56.yml | 10 +++++ test/templates/cluster_endtoend_test.tpl | 10 +++++ test/templates/unit_test.tpl | 10 +++++ 44 files changed, 456 insertions(+), 16 deletions(-) diff --git a/.github/workflows/cluster_endtoend_11.yml b/.github/workflows/cluster_endtoend_11.yml index a6ad3e6ca96..5ec5d45cc72 100644 --- a/.github/workflows/cluster_endtoend_11.yml +++ b/.github/workflows/cluster_endtoend_11.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_12.yml b/.github/workflows/cluster_endtoend_12.yml index 149e53b5f11..77934b909bd 100644 --- a/.github/workflows/cluster_endtoend_12.yml +++ b/.github/workflows/cluster_endtoend_12.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_13.yml b/.github/workflows/cluster_endtoend_13.yml index ac7145a9d36..c3604cef464 100644 --- a/.github/workflows/cluster_endtoend_13.yml +++ b/.github/workflows/cluster_endtoend_13.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_14.yml b/.github/workflows/cluster_endtoend_14.yml index 54336976900..e5873512672 100644 --- a/.github/workflows/cluster_endtoend_14.yml +++ b/.github/workflows/cluster_endtoend_14.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_15.yml b/.github/workflows/cluster_endtoend_15.yml index fef2846e66b..0661e084b26 100644 --- a/.github/workflows/cluster_endtoend_15.yml +++ b/.github/workflows/cluster_endtoend_15.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_16.yml b/.github/workflows/cluster_endtoend_16.yml index e33dd8e1ea8..a21072bf604 100644 --- a/.github/workflows/cluster_endtoend_16.yml +++ b/.github/workflows/cluster_endtoend_16.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_17.yml b/.github/workflows/cluster_endtoend_17.yml index b4dea05e571..38944c257f1 100644 --- a/.github/workflows/cluster_endtoend_17.yml +++ b/.github/workflows/cluster_endtoend_17.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_18.yml b/.github/workflows/cluster_endtoend_18.yml index 33fa04723eb..85b25419b48 100644 --- a/.github/workflows/cluster_endtoend_18.yml +++ b/.github/workflows/cluster_endtoend_18.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_19.yml b/.github/workflows/cluster_endtoend_19.yml index 2e6458337d7..582b7db0227 100644 --- a/.github/workflows/cluster_endtoend_19.yml +++ b/.github/workflows/cluster_endtoend_19.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_20.yml b/.github/workflows/cluster_endtoend_20.yml index b5e502771a0..d53175a88f3 100644 --- a/.github/workflows/cluster_endtoend_20.yml +++ b/.github/workflows/cluster_endtoend_20.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_21.yml b/.github/workflows/cluster_endtoend_21.yml index 9234fb533df..10f52f04178 100644 --- a/.github/workflows/cluster_endtoend_21.yml +++ b/.github/workflows/cluster_endtoend_21.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_22.yml b/.github/workflows/cluster_endtoend_22.yml index 6aeb60371fc..c1bcb675bae 100644 --- a/.github/workflows/cluster_endtoend_22.yml +++ b/.github/workflows/cluster_endtoend_22.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_23.yml b/.github/workflows/cluster_endtoend_23.yml index b36d852fb59..f7105bc96cd 100644 --- a/.github/workflows/cluster_endtoend_23.yml +++ b/.github/workflows/cluster_endtoend_23.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_24.yml b/.github/workflows/cluster_endtoend_24.yml index 8baea8ff511..ef3eaa00ce8 100644 --- a/.github/workflows/cluster_endtoend_24.yml +++ b/.github/workflows/cluster_endtoend_24.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_26.yml b/.github/workflows/cluster_endtoend_26.yml index 3f6603c7d23..fdee5988cf0 100644 --- a/.github/workflows/cluster_endtoend_26.yml +++ b/.github/workflows/cluster_endtoend_26.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_27.yml b/.github/workflows/cluster_endtoend_27.yml index c7382cf9f2f..dea2e7336b9 100644 --- a/.github/workflows/cluster_endtoend_27.yml +++ b/.github/workflows/cluster_endtoend_27.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_onlineddl_declarative.yml b/.github/workflows/cluster_endtoend_onlineddl_declarative.yml index 284bfb72e9a..3a7381b37f2 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_declarative.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_declarative.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_onlineddl_ghost.yml b/.github/workflows/cluster_endtoend_onlineddl_ghost.yml index c2b9e3edbef..22b049e9347 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_ghost.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_ghost.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_onlineddl_revert.yml b/.github/workflows/cluster_endtoend_onlineddl_revert.yml index 76a94e8ec9d..a6937a9eb85 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_revert.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_revert.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml index a9a24072bb9..5bd8a46a61c 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml index b89c31e4019..56dd0231a4b 100644 --- a/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml +++ b/.github/workflows/cluster_endtoend_onlineddl_vrepl_stress.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler.yml index f7c9e7bdd2e..7caa3ccde42 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler.yml @@ -6,7 +6,7 @@ jobs: build: name: Run endtoend tests on Cluster (tabletmanager_throttler) - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_tabletmanager_throttler_custom_config.yml b/.github/workflows/cluster_endtoend_tabletmanager_throttler_custom_config.yml index c48d42e5c58..875efbed6da 100644 --- a/.github/workflows/cluster_endtoend_tabletmanager_throttler_custom_config.yml +++ b/.github/workflows/cluster_endtoend_tabletmanager_throttler_custom_config.yml @@ -6,7 +6,7 @@ jobs: build: name: Run endtoend tests on Cluster (tabletmanager_throttler_custom_config) - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - name: Set up Go @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_upgrade.yml b/.github/workflows/cluster_endtoend_upgrade.yml index 1017efb3578..85528a34425 100644 --- a/.github/workflows/cluster_endtoend_upgrade.yml +++ b/.github/workflows/cluster_endtoend_upgrade.yml @@ -13,15 +13,25 @@ jobs: with: go-version: 1.15 - - name: Check out v8.0.0 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out v9.0.0 uses: actions/checkout@v2 with: - ref: v8.0.0 + ref: v9.0.0 - name: Get dependencies run: | # This prepares general purpose binary dependencies - # as well as v8.0.0 specific go modules + # as well as v9.0.0 specific go modules sudo apt-get update sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata sudo service mysql stop @@ -36,28 +46,28 @@ jobs: sudo apt-get update sudo apt-get install percona-xtrabackup-24 - - name: Building v8.0.0 binaries + - name: Building v9.0.0 binaries timeout-minutes: 10 run: | - # We build v8.0.0 binaries and save them in a temporary location + # We build v9.0.0 binaries and save them in a temporary location source build.env make build - mkdir -p /tmp/vitess-build-v8.0.0/ - cp -R bin /tmp/vitess-build-v8.0.0/ + mkdir -p /tmp/vitess-build-v9.0.0/ + cp -R bin /tmp/vitess-build-v9.0.0/ - name: Check out HEAD uses: actions/checkout@v2 - - name: Run cluster endtoend test v8.0.0 (create cluster) + - name: Run cluster endtoend test v9.0.0 (create cluster) timeout-minutes: 5 run: | - # By checking out we deleted bin/ directory. We now restore our pre-built v8.0.0 binaries - cp -R /tmp/vitess-build-v8.0.0/bin . + # By checking out we deleted bin/ directory. We now restore our pre-built v9.0.0 binaries + cp -R /tmp/vitess-build-v9.0.0/bin . # create the directory where we store test data; ensure it is empty: rm -rf /tmp/vtdataroot mkdir -p /tmp/vtdataroot source build.env - # We pass -skip-build so that we use the v8.0.0 binaries, not HEAD binaries + # We pass -skip-build so that we use the v9.0.0 binaries, not HEAD binaries eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28 - name: Check out HEAD @@ -74,7 +84,7 @@ jobs: mkdir -p /tmp/vitess-build-head/ cp -R bin /tmp/vitess-build-head/ - - name: Run cluster endtoend test HEAD based on v8.0.0 data (upgrade path) + - name: Run cluster endtoend test HEAD based on v9.0.0 data (upgrade path) timeout-minutes: 5 run: | # /tmp/vtdataroot exists from previous test @@ -95,11 +105,11 @@ jobs: eatmydata -- go run test.go -skip-build -keep-data -docker=false -print-log -follow -shard 28 - - name: Run cluster endtoend test v8.0.0 based on HEAD data (downgrade path) + - name: Run cluster endtoend test v9.0.0 based on HEAD data (downgrade path) timeout-minutes: 5 run: | # /tmp/vtdataroot exists from previous test - cp -R /tmp/vitess-build-v8.0.0/bin . + cp -R /tmp/vitess-build-v9.0.0/bin . source build.env # We again built manually and there's no need for the test to build. diff --git a/.github/workflows/cluster_endtoend_vreplication_basic.yml b/.github/workflows/cluster_endtoend_vreplication_basic.yml index 9c3b59123d9..427d8675d06 100644 --- a/.github/workflows/cluster_endtoend_vreplication_basic.yml +++ b/.github/workflows/cluster_endtoend_vreplication_basic.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml index eccae39a07c..efdf95423d6 100644 --- a/.github/workflows/cluster_endtoend_vreplication_cellalias.yml +++ b/.github/workflows/cluster_endtoend_vreplication_cellalias.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_vreplication_migrate.yml b/.github/workflows/cluster_endtoend_vreplication_migrate.yml index b283b13a4a3..1e9f02b0153 100644 --- a/.github/workflows/cluster_endtoend_vreplication_migrate.yml +++ b/.github/workflows/cluster_endtoend_vreplication_migrate.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_vreplication_multicell.yml b/.github/workflows/cluster_endtoend_vreplication_multicell.yml index 6dca34502e5..72c92ebf610 100644 --- a/.github/workflows/cluster_endtoend_vreplication_multicell.yml +++ b/.github/workflows/cluster_endtoend_vreplication_multicell.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_endtoend_vreplication_v2.yml b/.github/workflows/cluster_endtoend_vreplication_v2.yml index 742483c3c78..a80745f35c7 100644 --- a/.github/workflows/cluster_endtoend_vreplication_v2.yml +++ b/.github/workflows/cluster_endtoend_vreplication_v2.yml @@ -14,6 +14,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/cluster_initial_sharding_multi.yml b/.github/workflows/cluster_initial_sharding_multi.yml index 147b8e7e1cf..9d15898ce32 100644 --- a/.github/workflows/cluster_initial_sharding_multi.yml +++ b/.github/workflows/cluster_initial_sharding_multi.yml @@ -12,6 +12,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/e2e_race.yml b/.github/workflows/e2e_race.yml index b6ce4793970..8c596e85569 100644 --- a/.github/workflows/e2e_race.yml +++ b/.github/workflows/e2e_race.yml @@ -12,6 +12,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/endtoend.yml b/.github/workflows/endtoend.yml index 8be2dbb3179..7e3181aaa4e 100644 --- a/.github/workflows/endtoend.yml +++ b/.github/workflows/endtoend.yml @@ -12,6 +12,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/legacy_local_example.yml b/.github/workflows/legacy_local_example.yml index 2033da389af..83f680c0406 100644 --- a/.github/workflows/legacy_local_example.yml +++ b/.github/workflows/legacy_local_example.yml @@ -17,6 +17,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/local_example.yml b/.github/workflows/local_example.yml index acddcc357fa..5f899bd761f 100644 --- a/.github/workflows/local_example.yml +++ b/.github/workflows/local_example.yml @@ -17,6 +17,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/region_example.yml b/.github/workflows/region_example.yml index b31b9af6151..ba09878b1f0 100644 --- a/.github/workflows/region_example.yml +++ b/.github/workflows/region_example.yml @@ -17,6 +17,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_race.yml b/.github/workflows/unit_race.yml index d280afe62a6..b362b2b714e 100644 --- a/.github/workflows/unit_race.yml +++ b/.github/workflows/unit_race.yml @@ -12,6 +12,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_test_mariadb101.yml b/.github/workflows/unit_test_mariadb101.yml index f3e08c7df17..c6120a09303 100644 --- a/.github/workflows/unit_test_mariadb101.yml +++ b/.github/workflows/unit_test_mariadb101.yml @@ -13,6 +13,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_test_mariadb102.yml b/.github/workflows/unit_test_mariadb102.yml index be554bc6e41..17ebdba01a5 100644 --- a/.github/workflows/unit_test_mariadb102.yml +++ b/.github/workflows/unit_test_mariadb102.yml @@ -13,6 +13,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_test_mariadb103.yml b/.github/workflows/unit_test_mariadb103.yml index 73bbe067dd9..f30d035eaa9 100644 --- a/.github/workflows/unit_test_mariadb103.yml +++ b/.github/workflows/unit_test_mariadb103.yml @@ -13,6 +13,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_test_mysql57.yml b/.github/workflows/unit_test_mysql57.yml index e9eabae2e5d..3c7e077ad32 100644 --- a/.github/workflows/unit_test_mysql57.yml +++ b/.github/workflows/unit_test_mysql57.yml @@ -13,6 +13,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_test_mysql80.yml b/.github/workflows/unit_test_mysql80.yml index 57cd16f2487..80f224e77c2 100644 --- a/.github/workflows/unit_test_mysql80.yml +++ b/.github/workflows/unit_test_mysql80.yml @@ -13,6 +13,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/.github/workflows/unit_test_percona56.yml b/.github/workflows/unit_test_percona56.yml index 937e32bf34e..72bc5a24d61 100644 --- a/.github/workflows/unit_test_percona56.yml +++ b/.github/workflows/unit_test_percona56.yml @@ -13,6 +13,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index 2f4451ad3c2..7a6548a71a0 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -12,6 +12,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index 31b4c7146f8..37a20971d54 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -11,6 +11,16 @@ jobs: with: go-version: 1.15 + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + - name: Check out code uses: actions/checkout@v2 From 13e33bbbd9c8bde9568097c6984d525e2e42e505 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 22 Apr 2021 08:40:32 +0530 Subject: [PATCH 102/310] default to false for system settings to be changed per session at the database connection level Signed-off-by: Harshit Gangal --- go/vt/vtgate/vtgate.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 33e18832d6b..1cbddfa9fd5 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -76,7 +76,7 @@ var ( warnPayloadSize = flag.Int("warn_payload_size", 0, "The warning threshold for query payloads in bytes. A payload greater than this threshold will cause the VtGateWarnings.WarnPayloadSizeExceeded counter to be incremented.") // Put set-passthrough under a flag. - sysVarSetEnabled = flag.Bool("enable_system_settings", true, "This will enable the system settings to be changed per session at the database connection level") + sysVarSetEnabled = flag.Bool("enable_system_settings", false, "This will enable the system settings to be changed per session at the database connection level") plannerVersion = flag.String("planner_version", "v3", "Sets the default planner to use when the session has not changed it. Valid values are: V3, Gen4, Gen4Greedy and Gen4Fallback. Gen4Fallback tries the new gen4 planner and falls back to the V3 planner if the gen4 fails. All Gen4 versions should be considered experimental!") // lockHeartbeatTime is used to set the next heartbeat time. From 654db52d1e7439c48cf5e35ae519892a51a34a1c Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 22 Apr 2021 09:04:31 +0530 Subject: [PATCH 103/310] java: prepare java version for release 10.0 Signed-off-by: Harshit Gangal --- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/client/pom.xml b/java/client/pom.xml index 3cf8a4c7528..f3315380391 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0-SNAPSHOT + 10.0.0 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index 2e9bb0dd09e..a0edaa1ab0d 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0-SNAPSHOT + 10.0.0 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 4bce8898db4..c09f6a6cd7d 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0-SNAPSHOT + 10.0.0 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 3bca87f6248..3b228313b05 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0-SNAPSHOT + 10.0.0 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index fe74f514a23..b9a42eddcf0 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 10.0.0-SNAPSHOT + 10.0.0 pom Vitess Java Client libraries [Parent] From ffd86306886c43e478971c85da33bebf8ab974a1 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 22 Apr 2021 09:05:54 +0300 Subject: [PATCH 104/310] vtctl: return error on invalid ddl_strategy Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vtctl/vtctl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 37ad61922ce..44aed50570f 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -2840,7 +2840,7 @@ func commandApplySchema(ctx context.Context, wr *wrangler.Wrangler, subFlags *fl executor.SkipPreflight() } if err := executor.SetDDLStrategy(*ddlStrategy); err != nil { - return nil + return err } return schemamanager.Run( From f5c2cbb46e5ba85dc107174dfa0bcfe9da16d817 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 20 Apr 2021 18:16:07 +0200 Subject: [PATCH 105/310] Squashed backport of https://github.com/vitessio/vitess/pull/7903 * make sure to close the right context when done * added some sleep to wait for goroutines to close * change test expectation from equal to actual being less than or equal Fixes #7908 Signed-off-by: Harshit Gangal Signed-off-by: Andres Taylor --- go/vt/vtgate/engine/merge_sort.go | 5 ++-- go/vt/vtgate/executor_select_test.go | 35 +++++++++++++++++++++++ go/vt/vttablet/sandboxconn/sandboxconn.go | 25 ++++++++++++++-- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/go/vt/vtgate/engine/merge_sort.go b/go/vt/vtgate/engine/merge_sort.go index b87aa981765..a93b2ba4515 100644 --- a/go/vt/vtgate/engine/merge_sort.go +++ b/go/vt/vtgate/engine/merge_sort.go @@ -79,7 +79,7 @@ func (ms *MergeSort) StreamExecute(vcursor VCursor, bindVars map[string]*querypb handles := make([]*streamHandle, len(ms.Primitives)) for i, input := range ms.Primitives { - handles[i] = runOneStream(vcursor, input, bindVars, wantfields) + handles[i] = runOneStream(ctx, vcursor, input, bindVars, wantfields) // Need fields only from first handle, if wantfields was true. wantfields = false } @@ -182,12 +182,11 @@ type streamHandle struct { } // runOnestream starts a streaming query on one shard, and returns a streamHandle for it. -func runOneStream(vcursor VCursor, input StreamExecutor, bindVars map[string]*querypb.BindVariable, wantfields bool) *streamHandle { +func runOneStream(ctx context.Context, vcursor VCursor, input StreamExecutor, bindVars map[string]*querypb.BindVariable, wantfields bool) *streamHandle { handle := &streamHandle{ fields: make(chan []*querypb.Field, 1), row: make(chan []sqltypes.Value, 10), } - ctx := vcursor.Context() go func() { defer close(handle.fields) diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 8025ac9e573..6f25dc460bc 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -18,8 +18,10 @@ package vtgate import ( "fmt" + "runtime" "strings" "testing" + "time" "vitess.io/vitess/go/cache" "vitess.io/vitess/go/test/utils" @@ -2336,3 +2338,36 @@ func TestSelectFromInformationSchema(t *testing.T) { require.NoError(t, err) assert.Equal(t, sbc1.StringQueries(), []string{"select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname"}) } + +func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { + // Special setup: Don't use createLegacyExecutorEnv. + cell := "aa" + hc := discovery.NewFakeHealthCheck() + s := createSandbox("TestExecutor") + s.VSchema = executorVSchema + getSandbox(KsTestUnsharded).VSchema = unshardedVSchema + serv := new(sandboxTopo) + resolver := newTestResolver(hc, serv, cell) + shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"} + count := 1 + for _, shard := range shards { + sbc := hc.AddTestTablet(cell, shard, 1, "TestExecutor", shard, topodatapb.TabletType_MASTER, true, 1, nil) + sbc.SetResults([]*sqltypes.Result{ + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|weight_string(id)", "int32|int32|varchar"), fmt.Sprintf("%d|%d|NULL", count, count)), + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col|weight_string(id)", "int32|int32|varchar"), fmt.Sprintf("%d|%d|NULL", count+10, count)), + }) + count++ + } + executor := NewExecutor(context.Background(), serv, cell, resolver, true, false, testBufferSize, cache.DefaultConfig) + before := runtime.NumGoroutine() + + query := "select id, col from user order by id limit 2" + gotResult, err := executorStream(executor, query) + require.NoError(t, err) + + wantResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col", "int32|int32"), "1|1", "2|2") + utils.MustMatch(t, wantResult, gotResult) + // some sleep to close all goroutines. + time.Sleep(100 * time.Millisecond) + assert.GreaterOrEqual(t, before, runtime.NumGoroutine(), "left open goroutines lingering") +} diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 63d8819d516..7bc73446b1c 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -207,10 +207,25 @@ func (sbc *SandboxConn) StreamExecute(ctx context.Context, target *querypb.Targe return err } parse, _ := sqlparser.Parse(query) - nextRs := sbc.getNextResult(parse) - sbc.sExecMu.Unlock() - return callback(nextRs) + if sbc.results == nil { + nextRs := sbc.getNextResult(parse) + sbc.sExecMu.Unlock() + return callback(nextRs) + } + + for len(sbc.results) > 0 { + nextRs := sbc.getNextResult(parse) + sbc.sExecMu.Unlock() + err := callback(nextRs) + if err != nil { + return err + } + sbc.sExecMu.Lock() + } + + sbc.sExecMu.Unlock() + return nil } // Begin is part of the QueryService interface. @@ -581,6 +596,10 @@ func (sbc *SandboxConn) setTxReservedID(transactionID int64, reservedID int64) { sbc.txIDToRID[transactionID] = reservedID } +func (sbc *SandboxConn) ResultsAllFetched() bool { + return len(sbc.results) == 0 +} + func (sbc *SandboxConn) getTxReservedID(txID int64) int64 { sbc.mapMu.Lock() defer sbc.mapMu.Unlock() From a2a5d5436aa54677b027e39f1884baf7f2610b5e Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 8 Apr 2021 15:46:27 +0200 Subject: [PATCH 106/310] Update rowlog for the API change made for the vstream skew alignment feature Signed-off-by: Rohit Nayak --- tools/rowlog/rowlog.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/rowlog/rowlog.go b/tools/rowlog/rowlog.go index f90a6a48a44..e4458005f4d 100644 --- a/tools/rowlog/rowlog.go +++ b/tools/rowlog/rowlog.go @@ -12,6 +12,7 @@ import ( "strings" "sync" "time" + vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" @@ -155,7 +156,7 @@ func startStreaming(ctx context.Context, vtgate, vtctld, keyspace, tablet, table log.Fatal(err) } defer conn.Close() - reader, err := conn.VStream(ctx, topodatapb.TabletType_MASTER, vgtid, filter) + reader, err := conn.VStream(ctx, topodatapb.TabletType_MASTER, vgtid, filter, &vtgatepb.VStreamFlags{}) var fields []*query.Field var gtid string var plan *TablePlan From 1901e8ea9f9efe84c8d21f9821f26d9308ceb1e1 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 22 Apr 2021 23:20:21 +0530 Subject: [PATCH 107/310] squashed backport of PR 7879 Signed-off-by: Harshit Gangal --- .../endtoend/vtgate/reservedconn/main_test.go | 6 +- .../reservedconn/reconnect1/main_test.go | 150 ++++++++++++++++++ .../reservedconn/reconnect2/main_test.go | 134 ++++++++++++++++ go/vt/discovery/fake_healthcheck.go | 19 ++- go/vt/discovery/healthcheck.go | 21 ++- go/vt/srvtopo/resolver.go | 2 +- go/vt/vterrors/constants.go | 34 ++++ go/vt/vtgate/discoverygateway.go | 2 +- go/vt/vtgate/gateway.go | 4 +- go/vt/vtgate/safe_session.go | 2 +- go/vt/vtgate/scatter_conn.go | 147 ++++++++++------- go/vt/vtgate/scatter_conn_test.go | 64 ++++++++ go/vt/vtgate/tabletgateway.go | 4 +- go/vt/vtgate/tx_conn.go | 2 +- go/vt/vttablet/sandboxconn/sandboxconn.go | 2 +- .../tabletconntest/fakequeryservice.go | 2 +- go/vt/vttablet/tabletserver/state_manager.go | 33 ++-- .../tabletserver/state_manager_test.go | 4 +- test/config.json | 18 +++ 19 files changed, 537 insertions(+), 113 deletions(-) create mode 100644 go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go create mode 100644 go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go create mode 100644 go/vt/vterrors/constants.go diff --git a/go/test/endtoend/vtgate/reservedconn/main_test.go b/go/test/endtoend/vtgate/reservedconn/main_test.go index e3b5ec78567..ebe133a2c81 100644 --- a/go/test/endtoend/vtgate/reservedconn/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/main_test.go @@ -126,10 +126,8 @@ func TestMain(m *testing.M) { } // Start vtgate - clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s"} - vtgateProcess := clusterInstance.NewVtgateInstance() - vtgateProcess.SysVarSetEnabled = true - if err := vtgateProcess.Setup(); err != nil { + clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s", "-enable_system_settings=true"} // enable reserved connection. + if err := clusterInstance.StartVtgate(); err != nil { return 1 } diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go new file mode 100644 index 00000000000..598d23345fe --- /dev/null +++ b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go @@ -0,0 +1,150 @@ +/* +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 reservedconn + +import ( + "context" + "flag" + "os" + "testing" + + "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 + vtParams mysql.ConnParams + keyspaceName = "ks" + cell = "zone1" + hostname = "localhost" + sqlSchema = `create table test(id bigint primary key)Engine=InnoDB;` + + vSchema = ` + { + "sharded":true, + "vindexes": { + "hash_index": { + "type": "hash" + } + }, + "tables": { + "test":{ + "column_vindexes": [ + { + "column": "id", + "name": "hash_index" + } + ] + } + } + } + ` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + 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: sqlSchema, + VSchema: vSchema, + } + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, true); err != nil { + return 1 + } + + // Start vtgate + clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s", "-enable_system_settings=true"} // enable reserved connection. + if err := clusterInstance.StartVtgate(); err != nil { + return 1 + } + + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + return m.Run() + }() + os.Exit(exitCode) +} + +func TestServingChange(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + checkedExec(t, conn, "use @rdonly") + checkedExec(t, conn, "set sql_mode = ''") + + // to see rdonly is available and + // also this will create reserved connection on rdonly on -80 and 80- shards. + _, err = exec(t, conn, "select * from test") + for err != nil { + _, err = exec(t, conn, "select * from test") + } + + // changing rdonly tablet to spare (non serving). + rdonlyTablet := clusterInstance.Keyspaces[0].Shards[0].Rdonly() + err = clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", rdonlyTablet.Alias, "spare") + require.NoError(t, err) + + // this should fail as there is no rdonly present + _, err = exec(t, conn, "select * from test") + require.Error(t, err) + + // changing replica tablet to rdonly to make rdonly available for serving. + replicaTablet := clusterInstance.Keyspaces[0].Shards[0].Replica() + err = clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", replicaTablet.Alias, "rdonly") + require.NoError(t, err) + + // to see/make the new rdonly available + err = clusterInstance.VtctlclientProcess.ExecuteCommand("Ping", replicaTablet.Alias) + require.NoError(t, err) + + // this should pass now as there is rdonly present + _, err = exec(t, conn, "select * from test") + assert.NoError(t, err) +} + +func exec(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { + t.Helper() + return conn.ExecuteFetch(query, 1000, true) +} + +func checkedExec(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 +} diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go new file mode 100644 index 00000000000..627f203647e --- /dev/null +++ b/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go @@ -0,0 +1,134 @@ +/* +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 reservedconn + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + + "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 + vtParams mysql.ConnParams + keyspaceName = "ks" + cell = "zone1" + hostname = "localhost" + sqlSchema = `create table test(id bigint primary key)Engine=InnoDB;` + + vSchema = ` + { + "sharded":true, + "vindexes": { + "hash_index": { + "type": "hash" + } + }, + "tables": { + "test":{ + "column_vindexes": [ + { + "column": "id", + "name": "hash_index" + } + ] + } + } + } + ` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + 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: sqlSchema, + VSchema: vSchema, + } + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-transaction-timeout", "5"} + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, true); err != nil { + return 1 + } + + // Start vtgate + clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s", "-enable_system_settings=true"} // enable reserved connection. + if err := clusterInstance.StartVtgate(); err != nil { + return 1 + } + + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + return m.Run() + }() + os.Exit(exitCode) +} + +func TestTabletChange(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + checkedExec(t, conn, "use @master") + checkedExec(t, conn, "set sql_mode = ''") + + // this will create reserved connection on master on -80 and 80- shards. + checkedExec(t, conn, "select * from test") + + // Change Master + err = clusterInstance.VtctlclientProcess.ExecuteCommand("PlannedReparentShard", "-keyspace_shard", fmt.Sprintf("%s/%s", keyspaceName, "-80")) + require.NoError(t, err) + + // this should pass as there is new master tablet and is serving. + _, err = exec(t, conn, "select * from test") + assert.NoError(t, err) +} + +func exec(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { + t.Helper() + return conn.ExecuteFetch(query, 1000, true) +} + +func checkedExec(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 +} diff --git a/go/vt/discovery/fake_healthcheck.go b/go/vt/discovery/fake_healthcheck.go index c762eb48bec..bbb1ec98baa 100644 --- a/go/vt/discovery/fake_healthcheck.go +++ b/go/vt/discovery/fake_healthcheck.go @@ -21,20 +21,18 @@ import ( "sort" "sync" - "vitess.io/vitess/go/sync2" - "github.com/golang/protobuf/proto" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" - + "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/queryservice" "vitess.io/vitess/go/vt/vttablet/sandboxconn" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) var ( @@ -146,16 +144,23 @@ func (fhc *FakeHealthCheck) ReplaceTablet(old, new *topodatapb.Tablet) { } // TabletConnection returns the TabletConn of the given tablet. -func (fhc *FakeHealthCheck) TabletConnection(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (fhc *FakeHealthCheck) TabletConnection(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) { aliasStr := topoproto.TabletAliasString(alias) fhc.mu.RLock() defer fhc.mu.RUnlock() for _, item := range fhc.items { if proto.Equal(alias, item.ts.Tablet.Alias) { + if !item.ts.Serving { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) + } + if target != nil && !proto.Equal(item.ts.Target, target) { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, item.ts.Target, target) + } + return item.ts.Conn, nil } } - return nil, vterrors.Errorf(vtrpc.Code_NOT_FOUND, "tablet %v not found", aliasStr) + return nil, vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "tablet %v not found", aliasStr) } // CacheStatus returns the status for each tablet diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 4af9dfd7202..90a64a788aa 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -45,19 +45,18 @@ import ( "sync" "time" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vttablet/queryservice" + "github.com/golang/protobuf/proto" "vitess.io/vitess/go/flagutil" - - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/queryservice" ) var ( @@ -177,7 +176,7 @@ type HealthCheck interface { WaitForAllServingTablets(ctx context.Context, targets []*query.Target) error // TabletConnection returns the TabletConn of the given tablet. - TabletConnection(alias *topodata.TabletAlias) (queryservice.QueryService, error) + TabletConnection(alias *topodata.TabletAlias, target *query.Target) (queryservice.QueryService, error) // RegisterStats registers the connection counts stats RegisterStats() @@ -693,7 +692,7 @@ func (hc *HealthCheckImpl) waitForTablets(ctx context.Context, targets []*query. } // TabletConnection returns the Connection to a given tablet. -func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias) (queryservice.QueryService, error) { +func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias, target *query.Target) (queryservice.QueryService, error) { hc.mu.Lock() thc := hc.healthByAlias[tabletAliasString(topoproto.TabletAliasString(alias))] hc.mu.Unlock() @@ -701,6 +700,12 @@ func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias) (querys //TODO: test that throws this error return nil, vterrors.Errorf(vtrpc.Code_NOT_FOUND, "tablet: %v is either down or nonexistent", alias) } + if !thc.Serving { + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, vterrors.NotServing) + } + if target != nil && !proto.Equal(thc.Target, target) { + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, thc.Target, target) + } return thc.Connection(), nil } diff --git a/go/vt/srvtopo/resolver.go b/go/vt/srvtopo/resolver.go index 7134b0b9852..e668e0e248c 100644 --- a/go/vt/srvtopo/resolver.go +++ b/go/vt/srvtopo/resolver.go @@ -40,7 +40,7 @@ type Gateway interface { queryservice.QueryService // QueryServiceByAlias returns a QueryService - QueryServiceByAlias(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) + QueryServiceByAlias(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) } // A Resolver can resolve keyspace ids and key ranges into ResolvedShard* diff --git a/go/vt/vterrors/constants.go b/go/vt/vterrors/constants.go new file mode 100644 index 00000000000..d66a97464d7 --- /dev/null +++ b/go/vt/vterrors/constants.go @@ -0,0 +1,34 @@ +/* +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 vterrors + +import "regexp" + +// Operation not allowed error +const ( + NotServing = "operation not allowed in state NOT_SERVING" + ShuttingDown = "operation not allowed in state SHUTTING_DOWN" +) + +// RxOp regex for operation not allowed error +var RxOp = regexp.MustCompile("operation not allowed in state (NOT_SERVING|SHUTTING_DOWN)") + +// WrongTablet for invalid tablet type error +const WrongTablet = "wrong tablet type" + +// RxWrongTablet regex for invalid tablet type error +var RxWrongTablet = regexp.MustCompile("(wrong|invalid) tablet type") diff --git a/go/vt/vtgate/discoverygateway.go b/go/vt/vtgate/discoverygateway.go index e324e998efd..b5d24c28829 100644 --- a/go/vt/vtgate/discoverygateway.go +++ b/go/vt/vtgate/discoverygateway.go @@ -405,6 +405,6 @@ func (dg *DiscoveryGateway) getStatsAggregator(target *querypb.Target) *TabletSt } // QueryServiceByAlias satisfies the Gateway interface -func (dg *DiscoveryGateway) QueryServiceByAlias(_ *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (dg *DiscoveryGateway) QueryServiceByAlias(_ *topodatapb.TabletAlias, _ *querypb.Target) (queryservice.QueryService, error) { return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "DiscoveryGateway does not implement QueryServiceByAlias") } diff --git a/go/vt/vtgate/gateway.go b/go/vt/vtgate/gateway.go index 1398ad5419e..86a015ab77a 100644 --- a/go/vt/vtgate/gateway.go +++ b/go/vt/vtgate/gateway.go @@ -17,6 +17,8 @@ import ( "flag" "time" + querypb "vitess.io/vitess/go/vt/proto/query" + "context" "vitess.io/vitess/go/vt/log" @@ -68,7 +70,7 @@ type Gateway interface { TabletsCacheStatus() discovery.TabletsCacheStatusList // TabletByAlias returns a QueryService - QueryServiceByAlias(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) + QueryServiceByAlias(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) } // Creator is the factory method which can create the actual gateway object. diff --git a/go/vt/vtgate/safe_session.go b/go/vt/vtgate/safe_session.go index 05db3b7ffa4..dd63c2cd301 100644 --- a/go/vt/vtgate/safe_session.go +++ b/go/vt/vtgate/safe_session.go @@ -533,7 +533,7 @@ func removeShard(tabletAlias *topodatapb.TabletAlias, sessions []*vtgatepb.Sessi } } if idx == -1 { - return sessions, nil + return nil, vterrors.New(vtrpcpb.Code_INTERNAL, "[BUG] tried to remove missing shard") } return append(sessions[:idx], sessions[idx+1:]...), nil } diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index ad8df6b6a0c..ea8e27b26c9 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -145,6 +145,14 @@ func (stc *ScatterConn) endAction(startTime time.Time, allErrors *concurrency.Al stc.timings.Record(statsKey, startTime) } +type reset int + +const ( + none reset = iota + shard + newQS +) + // ExecuteMultiShard is like Execute, // but each shard gets its own Sql Queries and BindVariables. // @@ -206,60 +214,82 @@ func (stc *ScatterConn) ExecuteMultiShard( if autocommit { // As this is auto-commit, the transactionID is supposed to be zero. - if info.transactionID != int64(0) { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "in autocommit mode, transactionID should be zero but was: %d", info.transactionID) + if transactionID != int64(0) { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "in autocommit mode, transactionID should be zero but was: %d", transactionID) } } qs, err = getQueryService(rs, info) if err != nil { - return nil, err + // an error here could mean that the tablet we were targeting earlier has changed type. + // if we have a transaction, we'll have to fail, but if we only had a reserved connection, + // we can create a new reserved connection to a new tablet that is on the right shard + // and has the right type + switch info.actionNeeded { + case nothing: + info.actionNeeded = reserve + case begin: + info.actionNeeded = reserveBegin + default: + return nil, err + } + retry := checkAndResetShardSession(info, err, session) + if retry != newQS { + return nil, err + } + qs = rs.Gateway + } + + retryRequest := func(exec func()) { + retry := checkAndResetShardSession(info, err, session) + switch retry { + case newQS: + // Current tablet is not available, try querying new tablet using gateway. + qs = rs.Gateway + fallthrough + case shard: + // if we need to reset a reserved connection, here is our chance to try executing again, + // against a new connection + exec() + } } switch info.actionNeeded { case nothing: innerqr, err = qs.Execute(ctx, rs.Target, queries[i].Sql, queries[i].BindVariables, info.transactionID, info.reservedID, opts) if err != nil { - shouldRetry := checkAndResetShardSession(info, err, session) - if shouldRetry { - // we seem to have lost our connection. if it was a reserved connection, let's try to recreate it + retryRequest(func() { + // we seem to have lost our connection. it was a reserved connection, let's try to recreate it info.actionNeeded = reserve innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, 0 /*transactionId*/, opts) - } - if err != nil { - return info.updateReservedID(reservedID, alias), err - } + }) } case begin: - innerqr, transactionID, alias, err = qs.BeginExecute(ctx, rs.Target, session.Savepoints, queries[i].Sql, queries[i].BindVariables, info.reservedID, opts) + innerqr, transactionID, alias, err = qs.BeginExecute(ctx, rs.Target, session.Savepoints, queries[i].Sql, queries[i].BindVariables, reservedID, opts) if err != nil { if transactionID != 0 { - return info.updateTransactionID(transactionID, alias), err + // if we had an open transaction, we can't repair anything and have to exit here. + // we still keep the transaction open - an error doesn't immediately close the transaction + break } - shouldRetry := checkAndResetShardSession(info, err, session) - if shouldRetry { - // we seem to have lost our connection. if it was a reserved connection, let's try to recreate it + retryRequest(func() { + // we seem to have lost our connection. it was a reserved connection, let's try to recreate it info.actionNeeded = reserveBegin innerqr, transactionID, reservedID, alias, err = qs.ReserveBeginExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, opts) - } - if err != nil { - return info.updateTransactionAndReservedID(transactionID, reservedID, alias), err - } - + }) } case reserve: - innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, info.transactionID, opts) - if err != nil { - return info.updateReservedID(reservedID, alias), err - } + innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, transactionID, opts) case reserveBegin: innerqr, transactionID, reservedID, alias, err = qs.ReserveBeginExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, opts) - if err != nil { - return info.updateTransactionAndReservedID(transactionID, reservedID, alias), err - } default: return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected actionNeeded on query execution: %v", info.actionNeeded) } + // We need to new shard info irrespective of the error. + newInfo := info.updateTransactionAndReservedID(transactionID, reservedID, alias) + if err != nil { + return newInfo, err + } mu.Lock() defer mu.Unlock() @@ -267,7 +297,7 @@ func (stc *ScatterConn) ExecuteMultiShard( if ignoreMaxMemoryRows || len(qr.Rows) <= *maxMemoryRows { qr.AppendResult(innerqr) } - return info.updateTransactionAndReservedID(transactionID, reservedID, alias), nil + return newInfo, nil }, ) @@ -278,28 +308,32 @@ func (stc *ScatterConn) ExecuteMultiShard( return qr, allErrors.GetErrors() } -var errRegx = regexp.MustCompile("transaction ([a-z0-9:]+) (?:ended|not found)") - -func checkAndResetShardSession(info *shardActionInfo, err error, session *SafeSession) bool { - if info.reservedID != 0 && info.transactionID == 0 && wasConnectionClosed(err) { - session.ResetShard(info.alias) - return true +func checkAndResetShardSession(info *shardActionInfo, err error, session *SafeSession) reset { + retry := none + if info.reservedID != 0 && info.transactionID == 0 { + if wasConnectionClosed(err) { + retry = shard + } + if requireNewQS(err) { + retry = newQS + } } - return false + if retry != none { + _ = session.ResetShard(info.alias) + } + return retry } func getQueryService(rs *srvtopo.ResolvedShard, info *shardActionInfo) (queryservice.QueryService, error) { _, usingLegacyGw := rs.Gateway.(*DiscoveryGateway) - if usingLegacyGw { - switch info.actionNeeded { - case reserve, reserveBegin: - return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "reserved connections are not supported on old gen gateway") - } + if usingLegacyGw && + (info.actionNeeded == reserve || info.actionNeeded == reserveBegin) { + return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "reserved connections are not supported on old gen gateway") } if usingLegacyGw || info.alias == nil { return rs.Gateway, nil } - return rs.Gateway.QueryServiceByAlias(info.alias) + return rs.Gateway.QueryServiceByAlias(info.alias, rs.Target) } func (stc *ScatterConn) processOneStreamingResult(mu *sync.Mutex, fieldSent *bool, qr *sqltypes.Result, callback func(*sqltypes.Result) error) error { @@ -675,12 +709,21 @@ func (stc *ScatterConn) ExecuteLock( return qr, err } +var txClosed = regexp.MustCompile("transaction ([a-z0-9:]+) (?:ended|not found)") + func wasConnectionClosed(err error) bool { sqlErr := mysql.NewSQLErrorFromError(err).(*mysql.SQLError) + message := sqlErr.Error() return sqlErr.Number() == mysql.CRServerGone || sqlErr.Number() == mysql.CRServerLost || - (sqlErr.Number() == mysql.ERQueryInterrupted && errRegx.MatchString(sqlErr.Error())) + (sqlErr.Number() == mysql.ERQueryInterrupted && txClosed.MatchString(message)) +} + +func requireNewQS(err error) bool { + code := vterrors.Code(err) + msg := err.Error() + return code == vtrpcpb.Code_FAILED_PRECONDITION && (vterrors.RxOp.MatchString(msg) || vterrors.RxWrongTablet.MatchString(msg)) } // actionInfo looks at the current session, and returns information about what needs to be done for this tablet @@ -738,25 +781,9 @@ type shardActionInfo struct { alias *topodatapb.TabletAlias } -func (sai *shardActionInfo) updateTransactionID(txID int64, alias *topodatapb.TabletAlias) *shardActionInfo { - if txID == 0 { - // As transaction id is ZERO, there is nothing to update in session shard sessions. - return nil - } - return sai.updateTransactionAndReservedID(txID, sai.reservedID, alias) -} - -func (sai *shardActionInfo) updateReservedID(rID int64, alias *topodatapb.TabletAlias) *shardActionInfo { - if rID == 0 { - // As reserved id is ZERO, there is nothing to update in session shard sessions. - return nil - } - return sai.updateTransactionAndReservedID(sai.transactionID, rID, alias) -} - func (sai *shardActionInfo) updateTransactionAndReservedID(txID int64, rID int64, alias *topodatapb.TabletAlias) *shardActionInfo { - if txID == 0 && rID == 0 { - // As transaction id and reserved id is ZERO, there is nothing to update in session shard sessions. + if txID == sai.transactionID && rID == sai.reservedID { + // As transaction id and reserved id have not changed, there is nothing to update in session shard sessions. return nil } newInfo := *sai diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index 5f84a56246d..4a5a8dcd8d5 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -19,6 +19,8 @@ package vtgate import ( "testing" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "github.com/stretchr/testify/assert" "vitess.io/vitess/go/mysql" @@ -321,6 +323,68 @@ func TestReservedConnFail(t *testing.T) { assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + + sbc0.Queries = nil + sbc0.EphemeralShardErr = vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "operation not allowed in state NOT_SERVING during query: query1") + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + + sbc0.Queries = nil + sbc0.EphemeralShardErr = vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: REPLICA, want: MASTER or MASTER") + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + oldAlias := session.Session.ShardSessions[0].TabletAlias + + // Test Setup + tablet0 := sbc0.Tablet() + ths := hc.GetHealthyTabletStats(&querypb.Target{ + Keyspace: tablet0.GetKeyspace(), + Shard: tablet0.GetShard(), + TabletType: tablet0.GetType(), + }) + sbc0Th := ths[0] + sbc0Th.Serving = false + sbc0Rep := hc.AddTestTablet("aa", "0", 2, keyspace, "0", topodatapb.TabletType_REPLICA, true, 1, nil) + + sbc0.Queries = nil + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 0, len(sbc0.Queries), "no attempt should be made as the tablet is not serving") + assert.Equal(t, 1, len(sbc0Rep.Queries), "first attempt should pass as it is healthy") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") + oldRId = session.Session.ShardSessions[0].ReservedId + oldAlias = session.Session.ShardSessions[0].TabletAlias + + // Test Setup + tablet0Rep := sbc0Rep.Tablet() + newThs := hc.GetHealthyTabletStats(&querypb.Target{ + Keyspace: tablet0Rep.GetKeyspace(), + Shard: tablet0Rep.GetShard(), + TabletType: tablet0Rep.GetType(), + }) + sbc0RepTh := newThs[0] + sbc0RepTh.Target = &querypb.Target{ + Keyspace: tablet0Rep.GetKeyspace(), + Shard: tablet0Rep.GetShard(), + TabletType: topodatapb.TabletType_SPARE, + } + sbc0Th.Serving = true + + sbc0Rep.Queries = nil + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 1, len(sbc0.Queries), "first attempt should pass as it is healthy and matches the target") + assert.Equal(t, 0, len(sbc0Rep.Queries), " no attempt should be made as the tablet target is changed") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") } func TestIsConnClosed(t *testing.T) { diff --git a/go/vt/vtgate/tabletgateway.go b/go/vt/vtgate/tabletgateway.go index 5556cafdb80..504945bd70a 100644 --- a/go/vt/vtgate/tabletgateway.go +++ b/go/vt/vtgate/tabletgateway.go @@ -132,8 +132,8 @@ func NewTabletGateway(ctx context.Context, hc discovery.HealthCheck, serv srvtop } // QueryServiceByAlias satisfies the Gateway interface -func (gw *TabletGateway) QueryServiceByAlias(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) { - return gw.hc.TabletConnection(alias) +func (gw *TabletGateway) QueryServiceByAlias(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) { + return gw.hc.TabletConnection(alias, target) } // RegisterStats registers the stats to export the lag since the last refresh diff --git a/go/vt/vtgate/tx_conn.go b/go/vt/vtgate/tx_conn.go index 4747dcf2664..b056b8db508 100644 --- a/go/vt/vtgate/tx_conn.go +++ b/go/vt/vtgate/tx_conn.go @@ -87,7 +87,7 @@ func (txc *TxConn) queryService(alias *topodatapb.TabletAlias) (queryservice.Que if qs != nil { return qs, nil } - return txc.gateway.QueryServiceByAlias(alias) + return txc.gateway.QueryServiceByAlias(alias, nil) } func (txc *TxConn) commitShard(ctx context.Context, s *vtgatepb.Session_ShardSession) error { diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 63d8819d516..c99e826b0dd 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -481,7 +481,7 @@ func (sbc *SandboxConn) VStreamResults(ctx context.Context, target *querypb.Targ } // QueryServiceByAlias is part of the Gateway interface. -func (sbc *SandboxConn) QueryServiceByAlias(_ *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (sbc *SandboxConn) QueryServiceByAlias(_ *topodatapb.TabletAlias, _ *querypb.Target) (queryservice.QueryService, error) { return sbc, nil } diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index 84849ea06ea..9fb15d053d5 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -720,7 +720,7 @@ func (f *FakeQueryService) VStreamResults(ctx context.Context, target *querypb.T } // QueryServiceByAlias satisfies the Gateway interface -func (f *FakeQueryService) QueryServiceByAlias(_ *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (f *FakeQueryService) QueryServiceByAlias(_ *topodatapb.TabletAlias, _ *querypb.Target) (queryservice.QueryService, error) { panic("not implemented") } diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index c1498e43f44..39cab911fd2 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -348,36 +348,19 @@ func (sm *stateManager) StartRequest(ctx context.Context, target *querypb.Target if sm.state != StateServing || !sm.replHealthy { // This specific error string needs to be returned for vtgate buffering to work. - return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "operation not allowed in state NOT_SERVING") + return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) } shuttingDown := sm.wantState != StateServing if shuttingDown && !allowOnShutdown { // This specific error string needs to be returned for vtgate buffering to work. - return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "operation not allowed in state SHUTTING_DOWN") + return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.ShuttingDown) } - if target != nil { - switch { - case target.Keyspace != sm.target.Keyspace: - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid keyspace %v does not match expected %v", target.Keyspace, sm.target.Keyspace) - case target.Shard != sm.target.Shard: - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid shard %v does not match expected %v", target.Shard, sm.target.Shard) - case target.TabletType != sm.target.TabletType: - for _, otherType := range sm.alsoAllow { - if target.TabletType == otherType { - goto ok - } - } - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: %v, want: %v or %v", target.TabletType, sm.target.TabletType, sm.alsoAllow) - } - } else { - if !tabletenv.IsLocalContext(ctx) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No target") - } + err = sm.verifyTargetLocked(ctx, target) + if err != nil { + return err } - -ok: sm.requests.Add(1) return nil } @@ -392,6 +375,10 @@ func (sm *stateManager) EndRequest() { func (sm *stateManager) VerifyTarget(ctx context.Context, target *querypb.Target) error { sm.mu.Lock() defer sm.mu.Unlock() + return sm.verifyTargetLocked(ctx, target) +} + +func (sm *stateManager) verifyTargetLocked(ctx context.Context, target *querypb.Target) error { if target != nil { switch { case target.Keyspace != sm.target.Keyspace: @@ -404,7 +391,7 @@ func (sm *stateManager) VerifyTarget(ctx context.Context, target *querypb.Target return nil } } - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: %v, want: %v or %v", target.TabletType, sm.target.TabletType, sm.alsoAllow) + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: %v, want: %v or %v", vterrors.WrongTablet, sm.target.TabletType, sm.target.TabletType, sm.alsoAllow) } } else { if !tabletenv.IsLocalContext(ctx) { diff --git a/go/vt/vttablet/tabletserver/state_manager_test.go b/go/vt/vttablet/tabletserver/state_manager_test.go index 577dbc8f6ad..53396e052ba 100644 --- a/go/vt/vttablet/tabletserver/state_manager_test.go +++ b/go/vt/vttablet/tabletserver/state_manager_test.go @@ -531,9 +531,9 @@ func TestStateManagerValidations(t *testing.T) { target.Shard = "" target.TabletType = topodatapb.TabletType_REPLICA err = sm.StartRequest(ctx, target, false) - assert.Contains(t, err.Error(), "invalid tablet type") + assert.Contains(t, err.Error(), "wrong tablet type") err = sm.VerifyTarget(ctx, target) - assert.Contains(t, err.Error(), "invalid tablet type") + assert.Contains(t, err.Error(), "wrong tablet type") sm.alsoAllow = []topodatapb.TabletType{topodatapb.TabletType_REPLICA} err = sm.StartRequest(ctx, target, false) diff --git a/test/config.json b/test/config.json index e111dfe4832..b33c0dca1ca 100644 --- a/test/config.json +++ b/test/config.json @@ -562,6 +562,24 @@ "RetryMax": 0, "Tags": [] }, + "vtgate_reserved_conn1": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_reserved_conn2": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, "vtgate_transaction": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/transaction"], From a67fd8f36b4dbf32668682f98c26d965ac331f2d Mon Sep 17 00:00:00 2001 From: Richard Bailey Date: Wed, 14 Apr 2021 19:55:12 -0700 Subject: [PATCH 108/310] Fix bug in vtgate when running with keyspace filtering (#199) This checks if a vtgate is currently filtering keyspaces before requesting the TopoServer. This is necessary because a TopoServer can't be accessed in those cases as the filtered Topo in those cases could make it unsafe to make writes since all reads would be returning a subset of the actual topo data. The only use of the requested topoServer that I found was in the DDL handling path and was introduced in vitessio#6547. This is deployed on dev but should get testing (endtoend or unit, unclear on best path atm) before going upstream. # Conflicts: # go/vt/vtgate/vcursor_impl.go Signed-off-by: Richard Bailey --- go/vt/discovery/healthcheck.go | 5 +++++ go/vt/vtgate/discoverygateway.go | 4 ++-- go/vt/vtgate/vcursor_impl.go | 11 +++++++++-- go/vt/vtgate/vtgate.go | 4 ++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 4af9dfd7202..6d2416cd754 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -148,6 +148,11 @@ func init() { flag.Var(&KeyspacesToWatch, "keyspaces_to_watch", "Specifies which keyspaces this vtgate should have access to while routing queries or accessing the vschema") } +// FilteringKeyspaces returns true if any keyspaces have been configured to be filtered. +func FilteringKeyspaces() bool { + return len(KeyspacesToWatch) > 0 +} + // TabletRecorder is a sub interface of HealthCheck. // It is separated out to enable unit testing. type TabletRecorder interface { diff --git a/go/vt/vtgate/discoverygateway.go b/go/vt/vtgate/discoverygateway.go index e324e998efd..f0c2fed433a 100644 --- a/go/vt/vtgate/discoverygateway.go +++ b/go/vt/vtgate/discoverygateway.go @@ -126,7 +126,7 @@ func NewDiscoveryGateway(ctx context.Context, hc discovery.LegacyHealthCheck, se } var recorder discovery.LegacyTabletRecorder = dg.hc if len(discovery.TabletFilters) > 0 { - if len(discovery.KeyspacesToWatch) > 0 { + if discovery.FilteringKeyspaces() { log.Exitf("Only one of -keyspaces_to_watch and -tablet_filters may be specified at a time") } @@ -135,7 +135,7 @@ func NewDiscoveryGateway(ctx context.Context, hc discovery.LegacyHealthCheck, se log.Exitf("Cannot parse tablet_filters parameter: %v", err) } recorder = fbs - } else if len(discovery.KeyspacesToWatch) > 0 { + } else if discovery.FilteringKeyspaces() { recorder = discovery.NewLegacyFilterByKeyspace(recorder, discovery.KeyspacesToWatch) } diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index f60af6dca2b..0e5bc215689 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -42,6 +42,7 @@ import ( "context" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/srvtopo" @@ -163,7 +164,8 @@ func newVCursorImpl( vschema *vindexes.VSchema, resolver *srvtopo.Resolver, serv srvtopo.Server, - warnShardedOnly bool) (*vcursorImpl, error) { + warnShardedOnly bool, +) (*vcursorImpl, error) { keyspace, tabletType, destination, err := parseDestinationTarget(safeSession.TargetString, vschema) if err != nil { return nil, err @@ -174,7 +176,9 @@ func newVCursorImpl( return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "transaction is supported only for master tablet type, current type: %v", tabletType) } var ts *topo.Server - if serv != nil { + // We don't have access to the underlying TopoServer if this vtgate is + // filtering keyspaces because we don't have an accurate view of the topo. + if serv != nil && !discovery.FilteringKeyspaces() { ts, err = serv.GetTopoServer() if err != nil { return nil, err @@ -588,6 +592,9 @@ func (vc *vcursorImpl) TabletType() topodatapb.TabletType { // SubmitOnlineDDL implements the VCursor interface func (vc *vcursorImpl) SubmitOnlineDDL(onlineDDl *schema.OnlineDDL) error { + if vc.topoServer == nil { + return vterrors.New(vtrpcpb.Code_INTERNAL, "Unable to apply DDL toposerver unavailable, ensure this vtgate is not using filtered keyspaces") + } conn, err := vc.topoServer.ConnForCell(vc.ctx, topo.GlobalCell) if err != nil { return err diff --git a/go/vt/vtgate/vtgate.go b/go/vt/vtgate/vtgate.go index 1cbddfa9fd5..fc8f10e8e6d 100644 --- a/go/vt/vtgate/vtgate.go +++ b/go/vt/vtgate/vtgate.go @@ -172,7 +172,7 @@ func Init(ctx context.Context, serv srvtopo.Server, cell string, tabletTypesToWa // If we want to filter keyspaces replace the srvtopo.Server with a // filtering server - if len(discovery.KeyspacesToWatch) > 0 { + if discovery.FilteringKeyspaces() { log.Infof("Keyspace filtering enabled, selecting %v", discovery.KeyspacesToWatch) var err error serv, err = srvtopo.NewKeyspaceFilteringServer(serv, discovery.KeyspacesToWatch) @@ -505,7 +505,7 @@ func LegacyInit(ctx context.Context, hc discovery.LegacyHealthCheck, serv srvtop // If we want to filter keyspaces replace the srvtopo.Server with a // filtering server - if len(discovery.KeyspacesToWatch) > 0 { + if discovery.FilteringKeyspaces() { log.Infof("Keyspace filtering enabled, selecting %v", discovery.KeyspacesToWatch) var err error serv, err = srvtopo.NewKeyspaceFilteringServer(serv, discovery.KeyspacesToWatch) From 9fb0a1ef895ce860f6ed115e4add4bc9da7c38a8 Mon Sep 17 00:00:00 2001 From: Richard Bailey Date: Wed, 14 Apr 2021 19:55:29 -0700 Subject: [PATCH 109/310] Add new test to prevent keyspaces_to_watch regression Signed-off-by: Richard Bailey --- .../keyspace_watches/keyspace_watch_test.go | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go diff --git a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go new file mode 100644 index 00000000000..8e900a7ee93 --- /dev/null +++ b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go @@ -0,0 +1,138 @@ +/* +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. +*/ + +/* +Test the vtgate's ability to route while watching a subset of keyspaces. +*/ + +package keyspacewatches + +import ( + "database/sql" + "fmt" + "math/rand" + "os" + "sync" + "testing" + "time" + + _ "github.com/go-sql-driver/mysql" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/mysql" + "vitess.io/vitess/go/test/endtoend/cluster" +) + +var ( + vtParams mysql.ConnParams + keyspaceUnshardedName = "ks1" + cell = "zone1" + hostname = "localhost" + mysqlAuthServerStatic = "mysql_auth_server_static.json" + sqlSchema = ` + create table keyspaces_to_watch_test( + id BIGINT NOT NULL, + msg VARCHAR(64) NOT NULL, + PRIMARY KEY (id) + ) Engine=InnoDB;` + wg = &sync.WaitGroup{} +) + +// createConfig creates a config file in TmpDir in vtdataroot and writes the given data. +func createConfig(clusterInstance *cluster.LocalProcessCluster, name, data string) error { + // creating new file + f, err := os.Create(clusterInstance.TmpDirectory + "/" + name) + if err != nil { + return err + } + + if data == "" { + return nil + } + + // write the given data + _, err = fmt.Fprint(f, data) + return err +} + +func createCluster() (*cluster.LocalProcessCluster, int) { + clusterInstance := cluster.NewCluster(cell, hostname) + + // Start topo server + if err := clusterInstance.StartTopo(); err != nil { + return nil, 1 + } + + // create auth server config + SQLConfig := `{ + "testuser1": { + "Password": "testpassword1", + "UserData": "vtgate client 1" + } + }` + if err := createConfig(clusterInstance, mysqlAuthServerStatic, SQLConfig); err != nil { + return nil, 1 + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceUnshardedName, + SchemaSQL: sqlSchema, + } + if err := clusterInstance.StartUnshardedKeyspace(*keyspace, 1, false); err != nil { + return nil, 1 + } + + clusterInstance.VtGateExtraArgs = []string{ + "-mysql_auth_server_static_file", clusterInstance.TmpDirectory + "/" + mysqlAuthServerStatic, + "-keyspaces_to_watch", "ks1", + } + + // Start vtgate + if err := clusterInstance.StartVtgate(); err != nil { + return nil, 1 + } + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + rand.Seed(time.Now().UnixNano()) + return clusterInstance, 0 +} + +func TestRoutingWithKeyspacesToWatch(t *testing.T) { + defer cluster.PanicHandler(t) + + clusterInstance, exitCode := createCluster() + defer clusterInstance.Teardown() + + if exitCode != 0 { + os.Exit(exitCode) + } + + dsn := fmt.Sprintf( + "testuser1:testpassword1@tcp(%s:%v)/", + clusterInstance.Hostname, + clusterInstance.VtgateMySQLPort, + ) + db, err := sql.Open("mysql", dsn) + require.Nil(t, err) + defer db.Close() + + // if this returns w/o failing the test we're good to go + _, err = db.Exec("select * from keyspaces_to_watch_test") + require.Nil(t, err) +} From d9b66cb5869f89c6fc4d1ae6c1fe0d4fcab0de2e Mon Sep 17 00:00:00 2001 From: Richard Date: Fri, 16 Apr 2021 14:33:08 -0700 Subject: [PATCH 110/310] resolve lint / dead code error edit made in the GH web ui soooo, let's see if this doesn't break things Signed-off-by: Richard Bailey --- go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go index 8e900a7ee93..033fd602eac 100644 --- a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go +++ b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go @@ -48,7 +48,6 @@ var ( msg VARCHAR(64) NOT NULL, PRIMARY KEY (id) ) Engine=InnoDB;` - wg = &sync.WaitGroup{} ) // createConfig creates a config file in TmpDir in vtdataroot and writes the given data. From 309165887a0c07e19fadef004745f0ea0da295c9 Mon Sep 17 00:00:00 2001 From: Richard Date: Fri, 16 Apr 2021 14:43:22 -0700 Subject: [PATCH 111/310] remove unused import Evidently I program in the web ui now Signed-off-by: Richard --- go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go index 033fd602eac..9fc3c9d59ea 100644 --- a/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go +++ b/go/test/endtoend/vtgate/keyspace_watches/keyspace_watch_test.go @@ -25,7 +25,6 @@ import ( "fmt" "math/rand" "os" - "sync" "testing" "time" From 2e289f890eea242de2eb698cea456a4c90513eec Mon Sep 17 00:00:00 2001 From: deepthi Date: Thu, 22 Apr 2021 12:51:59 -0700 Subject: [PATCH 112/310] vcursor: better error message Signed-off-by: deepthi --- go/vt/vtgate/vcursor_impl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/vcursor_impl.go b/go/vt/vtgate/vcursor_impl.go index 0e5bc215689..9477be91939 100644 --- a/go/vt/vtgate/vcursor_impl.go +++ b/go/vt/vtgate/vcursor_impl.go @@ -593,7 +593,7 @@ func (vc *vcursorImpl) TabletType() topodatapb.TabletType { // SubmitOnlineDDL implements the VCursor interface func (vc *vcursorImpl) SubmitOnlineDDL(onlineDDl *schema.OnlineDDL) error { if vc.topoServer == nil { - return vterrors.New(vtrpcpb.Code_INTERNAL, "Unable to apply DDL toposerver unavailable, ensure this vtgate is not using filtered keyspaces") + return vterrors.New(vtrpcpb.Code_INTERNAL, "Unable to apply DDL because toposerver is unavailable, ensure this vtgate is not using filtered keyspaces") } conn, err := vc.topoServer.ConnForCell(vc.ctx, topo.GlobalCell) if err != nil { From 03530211e181fe0dad13cb02499258be368e807d Mon Sep 17 00:00:00 2001 From: crowu Date: Wed, 21 Apr 2021 10:29:50 -0700 Subject: [PATCH 113/310] Check tablet alias before removing after error stream Signed-off-by: crowu --- go/vt/discovery/healthcheck.go | 8 ++- go/vt/discovery/healthcheck_test.go | 78 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 4af9dfd7202..c2788efa56b 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -390,6 +390,11 @@ func (hc *HealthCheckImpl) deleteTablet(tablet *topodata.Tablet) { // which will call finalizeConn, which will close the connection. th.cancelFunc() delete(hc.healthByAlias, tabletAlias) + // delete from map by keyspace.shard.tabletType + hc.deleteHealthDateLocked(key, tabletAlias) +} + +func (hc *HealthCheckImpl) deleteHealthDateLocked(key keyspaceShardTabletType, tabletAlias tabletAliasString) { // delete from map by keyspace.shard.tabletType ths, ok := hc.healthData[key] if !ok { @@ -448,8 +453,7 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, prevTarget *query.Targ } } case isPrimary && !isPrimaryUp: - // No healthy master tablet - hc.healthy[targetKey] = []*TabletHealth{} + hc.deleteHealthDateLocked(targetKey, tabletAlias) } if !trivialUpdate { diff --git a/go/vt/discovery/healthcheck_test.go b/go/vt/discovery/healthcheck_test.go index 73ba30a665f..54d3c303a12 100644 --- a/go/vt/discovery/healthcheck_test.go +++ b/go/vt/discovery/healthcheck_test.go @@ -324,6 +324,84 @@ func TestHealthCheckErrorOnPrimary(t *testing.T) { assert.Empty(t, a, "wrong result, expected empty list") } +func TestHealthCheckErrorOnPrimaryAfterExternalReparent(t *testing.T) { + ts := memorytopo.NewServer("cell") + hc := createTestHc(ts) + defer hc.Close() + + resultChan := hc.Subscribe() + + tablet1 := createTestTablet(0, "cell", "a") + input1 := make(chan *querypb.StreamHealthResponse) + fc1 := createFakeConn(tablet1, input1) + fc1.errCh = make(chan error) + hc.AddTablet(tablet1) + <-resultChan + + tablet2 := createTestTablet(1, "cell", "b") + tablet2.Type = topodatapb.TabletType_REPLICA + input2 := make(chan *querypb.StreamHealthResponse) + createFakeConn(tablet2, input2) + hc.AddTablet(tablet2) + <-resultChan + + shr2 := &querypb.StreamHealthResponse{ + TabletAlias: tablet2.Alias, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_REPLICA}, + Serving: true, + TabletExternallyReparentedTimestamp: 0, + RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 10, CpuUsage: 0.2}, + } + input2 <- shr2 + <-resultChan + shr1 := &querypb.StreamHealthResponse{ + TabletAlias: tablet1.Alias, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + TabletExternallyReparentedTimestamp: 10, + RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 0, CpuUsage: 0.2}, + } + input1 <- shr1 + <-resultChan + // tablet 1 is the primary now + health := []*TabletHealth{{ + Tablet: tablet1, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 0, CpuUsage: 0.2}, + MasterTermStartTime: 10, + }} + a := hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}) + mustMatch(t, health, a, "unexpected result") + + shr2 = &querypb.StreamHealthResponse{ + TabletAlias: tablet2.Alias, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + TabletExternallyReparentedTimestamp: 20, + RealtimeStats: &querypb.RealtimeStats{SecondsBehindMaster: 0, CpuUsage: 0.2}, + } + input2 <- shr2 + <-resultChan + // reparent: tablet 2 is the primary now + health = []*TabletHealth{{ + Tablet: tablet2, + Target: &querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}, + Serving: true, + Stats: &querypb.RealtimeStats{SecondsBehindMaster: 0, CpuUsage: 0.2}, + MasterTermStartTime: 20, + }} + a = hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}) + mustMatch(t, health, a, "unexpected result") + + // Stream error from tablet 1 + fc1.errCh <- fmt.Errorf("some stream error") + <-resultChan + // tablet 2 should still be the master + a = hc.GetHealthyTabletStats(&querypb.Target{Keyspace: "k", Shard: "s", TabletType: topodatapb.TabletType_MASTER}) + mustMatch(t, health, a, "unexpected result") +} + func TestHealthCheckVerifiesTabletAlias(t *testing.T) { ts := memorytopo.NewServer("cell") hc := createTestHc(ts) From a7cfe60627c5c07abfb5aa2566424a64ab1d3d22 Mon Sep 17 00:00:00 2001 From: crowu Date: Wed, 21 Apr 2021 16:19:19 -0700 Subject: [PATCH 114/310] Only modify healthy map Signed-off-by: crowu --- go/vt/discovery/healthcheck.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index c2788efa56b..cbfb302ef6e 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -390,11 +390,6 @@ func (hc *HealthCheckImpl) deleteTablet(tablet *topodata.Tablet) { // which will call finalizeConn, which will close the connection. th.cancelFunc() delete(hc.healthByAlias, tabletAlias) - // delete from map by keyspace.shard.tabletType - hc.deleteHealthDateLocked(key, tabletAlias) -} - -func (hc *HealthCheckImpl) deleteHealthDateLocked(key keyspaceShardTabletType, tabletAlias tabletAliasString) { // delete from map by keyspace.shard.tabletType ths, ok := hc.healthData[key] if !ok { @@ -453,7 +448,14 @@ func (hc *HealthCheckImpl) updateHealth(th *TabletHealth, prevTarget *query.Targ } } case isPrimary && !isPrimaryUp: - hc.deleteHealthDateLocked(targetKey, tabletAlias) + if healthy, ok := hc.healthy[targetKey]; ok && len(healthy) > 0 { + // isPrimary is true here therefore we should only have 1 tablet in healthy + alias := tabletAliasString(topoproto.TabletAliasString(healthy[0].Tablet.Alias)) + // Clear healthy list for primary if the existing tablet is down + if alias == tabletAlias { + hc.healthy[targetKey] = []*TabletHealth{} + } + } } if !trivialUpdate { From 3e2384698a5b91852c69edcb8efb53eb30e233f0 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Fri, 26 Mar 2021 21:55:13 -0700 Subject: [PATCH 115/310] First cut at allowing modification of tablet unhealthy_threshold via debugEnv. Signed-off-by: Jacques Grove --- go.mod | 1 + go/vt/vttablet/tabletserver/debugenv.go | 21 ++++++++++++++++++ .../vttablet/tabletserver/health_streamer.go | 22 ++++++++++++++++--- go/vt/vttablet/tabletserver/state_manager.go | 12 +++++++--- 4 files changed, 50 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 3f78eaf5157..a9af8dcd48a 100644 --- a/go.mod +++ b/go.mod @@ -96,6 +96,7 @@ require ( github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible // indirect github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b + go.uber.org/atomic v1.4.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/lint v0.0.0-20190930215403-16217165b5de golang.org/x/net v0.0.0-20201021035429-f5854403a974 diff --git a/go/vt/vttablet/tabletserver/debugenv.go b/go/vt/vttablet/tabletserver/debugenv.go index 50a200ec3ad..87d2a81a424 100644 --- a/go/vt/vttablet/tabletserver/debugenv.go +++ b/go/vt/vttablet/tabletserver/debugenv.go @@ -23,6 +23,7 @@ import ( "net/http" "strconv" "text/template" + "time" "vitess.io/vitess/go/acl" "vitess.io/vitess/go/vt/log" @@ -72,6 +73,15 @@ func debugEnvHandler(tsv *TabletServer, w http.ResponseWriter, r *http.Request) f(ival) msg = fmt.Sprintf("Setting %v to: %v", varname, value) } + setDurationVal := func(f func(time.Duration)) { + durationVal, err := time.ParseDuration(value) + if err != nil { + msg = fmt.Sprintf("Failed setting value for %v: %v", varname, err) + return + } + f(durationVal) + msg = fmt.Sprintf("Setting %v to: %v", varname, value) + } switch varname { case "PoolSize": setIntVal(tsv.SetPoolSize) @@ -85,6 +95,10 @@ func debugEnvHandler(tsv *TabletServer, w http.ResponseWriter, r *http.Request) setIntVal(tsv.SetMaxResultSize) case "WarnResultSize": setIntVal(tsv.SetWarnResultSize) + case "UnhealthyThreshold": + setDurationVal(tsv.Config().Healthcheck.UnhealthyThresholdSeconds.Set) + setDurationVal(tsv.hs.SetUnhealthyThreshold) + setDurationVal(tsv.sm.SetUnhealthyThreshold) case "Consolidator": tsv.SetConsolidatorMode(value) msg = fmt.Sprintf("Setting %v to: %v", varname, value) @@ -98,12 +112,19 @@ func debugEnvHandler(tsv *TabletServer, w http.ResponseWriter, r *http.Request) Value: fmt.Sprintf("%v", f()), }) } + addDurationVar := func(varname string, f func() time.Duration) { + vars = append(vars, envValue{ + VarName: varname, + Value: fmt.Sprintf("%v", f()), + }) + } addIntVar("PoolSize", tsv.PoolSize) addIntVar("StreamPoolSize", tsv.StreamPoolSize) addIntVar("TxPoolSize", tsv.TxPoolSize) addIntVar("QueryCacheCapacity", tsv.QueryPlanCacheCap) addIntVar("MaxResultSize", tsv.MaxResultSize) addIntVar("WarnResultSize", tsv.WarnResultSize) + addDurationVar("UnhealthyThreshold", tsv.Config().Healthcheck.UnhealthyThresholdSeconds.Get) vars = append(vars, envValue{ VarName: "Consolidator", Value: tsv.ConsolidatorMode(), diff --git a/go/vt/vttablet/tabletserver/health_streamer.go b/go/vt/vttablet/tabletserver/health_streamer.go index b42fcb4f1d6..0c06a0d4d16 100644 --- a/go/vt/vttablet/tabletserver/health_streamer.go +++ b/go/vt/vttablet/tabletserver/health_streamer.go @@ -27,6 +27,8 @@ import ( "github.com/golang/protobuf/proto" + "go.uber.org/atomic" + "vitess.io/vitess/go/history" "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" @@ -51,7 +53,7 @@ var ( type healthStreamer struct { stats *tabletenv.Stats degradedThreshold time.Duration - unhealthyThreshold time.Duration + unhealthyThreshold *atomic.Duration mu sync.Mutex ctx context.Context @@ -66,7 +68,7 @@ func newHealthStreamer(env tabletenv.Env, alias topodatapb.TabletAlias) *healthS return &healthStreamer{ stats: env.Stats(), degradedThreshold: env.Config().Healthcheck.DegradedThresholdSeconds.Get(), - unhealthyThreshold: env.Config().Healthcheck.UnhealthyThresholdSeconds.Get(), + unhealthyThreshold: atomic.NewDuration(env.Config().Healthcheck.UnhealthyThresholdSeconds.Get()), clients: make(map[chan *querypb.StreamHealthResponse]struct{}), state: &querypb.StreamHealthResponse{ @@ -220,7 +222,7 @@ func (hs *healthStreamer) AppendDetails(details []*kv) []*kv { sbm := time.Duration(hs.state.RealtimeStats.SecondsBehindMaster) * time.Second class := healthyClass switch { - case sbm > hs.unhealthyThreshold: + case sbm > hs.unhealthyThreshold.Load(): class = unhealthyClass case sbm > hs.degradedThreshold: class = unhappyClass @@ -240,3 +242,17 @@ func (hs *healthStreamer) AppendDetails(details []*kv) []*kv { return details } + +func (hs *healthStreamer) SetUnhealthyThreshold(v time.Duration) { + hs.unhealthyThreshold.Store(v) + shr := proto.Clone(hs.state).(*querypb.StreamHealthResponse) + for ch := range hs.clients { + select { + case ch <- shr: + default: + log.Info("Resetting health streamer clients due to unhealthy threshold change") + close(ch) + delete(hs.clients, ch) + } + } +} diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index c1498e43f44..8f1810f59b7 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -22,6 +22,8 @@ import ( "sync" "time" + "go.uber.org/atomic" + "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/timer" "vitess.io/vitess/go/vt/log" @@ -122,7 +124,7 @@ type stateManager struct { checkMySQLThrottler *sync2.Semaphore timebombDuration time.Duration - unhealthyThreshold time.Duration + unhealthyThreshold *atomic.Duration shutdownGracePeriod time.Duration transitionGracePeriod time.Duration } @@ -187,7 +189,7 @@ func (sm *stateManager) Init(env tabletenv.Env, target querypb.Target) { sm.checkMySQLThrottler = sync2.NewSemaphore(1, 0) sm.timebombDuration = env.Config().OltpReadPool.TimeoutSeconds.Get() * 10 sm.hcticks = timer.NewTimer(env.Config().Healthcheck.IntervalSeconds.Get()) - sm.unhealthyThreshold = env.Config().Healthcheck.UnhealthyThresholdSeconds.Get() + sm.unhealthyThreshold = atomic.NewDuration(env.Config().Healthcheck.UnhealthyThresholdSeconds.Get()) sm.shutdownGracePeriod = env.Config().GracePeriods.ShutdownSeconds.Get() sm.transitionGracePeriod = env.Config().GracePeriods.TransitionSeconds.Get() } @@ -640,7 +642,7 @@ func (sm *stateManager) refreshReplHealthLocked() (time.Duration, error) { } sm.replHealthy = false } else { - if lag > sm.unhealthyThreshold { + if lag > sm.unhealthyThreshold.Load() { if sm.replHealthy { log.Infof("Going unhealthy due to high replication lag: %v", lag) } @@ -768,3 +770,7 @@ func (sm *stateManager) IsServingString() string { } return "NOT_SERVING" } + +func (sm *stateManager) SetUnhealthyThreshold(v time.Duration) { + sm.unhealthyThreshold.Store(v) +} From 4b729a8d5c9547ac47b4a32d2de252325f7d86f8 Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Tue, 6 Apr 2021 15:10:45 -0700 Subject: [PATCH 116/310] Swap out uber/atomic with sync2 Signed-off-by: Jacques Grove --- go/vt/vttablet/tabletserver/health_streamer.go | 11 +++++------ go/vt/vttablet/tabletserver/state_manager.go | 10 ++++------ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/go/vt/vttablet/tabletserver/health_streamer.go b/go/vt/vttablet/tabletserver/health_streamer.go index 0c06a0d4d16..36e856d3e8e 100644 --- a/go/vt/vttablet/tabletserver/health_streamer.go +++ b/go/vt/vttablet/tabletserver/health_streamer.go @@ -27,9 +27,8 @@ import ( "github.com/golang/protobuf/proto" - "go.uber.org/atomic" - "vitess.io/vitess/go/history" + "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/vt/log" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" @@ -53,7 +52,7 @@ var ( type healthStreamer struct { stats *tabletenv.Stats degradedThreshold time.Duration - unhealthyThreshold *atomic.Duration + unhealthyThreshold sync2.AtomicDuration mu sync.Mutex ctx context.Context @@ -68,7 +67,7 @@ func newHealthStreamer(env tabletenv.Env, alias topodatapb.TabletAlias) *healthS return &healthStreamer{ stats: env.Stats(), degradedThreshold: env.Config().Healthcheck.DegradedThresholdSeconds.Get(), - unhealthyThreshold: atomic.NewDuration(env.Config().Healthcheck.UnhealthyThresholdSeconds.Get()), + unhealthyThreshold: sync2.NewAtomicDuration(env.Config().Healthcheck.UnhealthyThresholdSeconds.Get()), clients: make(map[chan *querypb.StreamHealthResponse]struct{}), state: &querypb.StreamHealthResponse{ @@ -222,7 +221,7 @@ func (hs *healthStreamer) AppendDetails(details []*kv) []*kv { sbm := time.Duration(hs.state.RealtimeStats.SecondsBehindMaster) * time.Second class := healthyClass switch { - case sbm > hs.unhealthyThreshold.Load(): + case sbm > hs.unhealthyThreshold.Get(): class = unhealthyClass case sbm > hs.degradedThreshold: class = unhappyClass @@ -244,7 +243,7 @@ func (hs *healthStreamer) AppendDetails(details []*kv) []*kv { } func (hs *healthStreamer) SetUnhealthyThreshold(v time.Duration) { - hs.unhealthyThreshold.Store(v) + hs.unhealthyThreshold.Set(v) shr := proto.Clone(hs.state).(*querypb.StreamHealthResponse) for ch := range hs.clients { select { diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index 8f1810f59b7..a18a5ec091d 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -22,8 +22,6 @@ import ( "sync" "time" - "go.uber.org/atomic" - "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/timer" "vitess.io/vitess/go/vt/log" @@ -124,7 +122,7 @@ type stateManager struct { checkMySQLThrottler *sync2.Semaphore timebombDuration time.Duration - unhealthyThreshold *atomic.Duration + unhealthyThreshold sync2.AtomicDuration shutdownGracePeriod time.Duration transitionGracePeriod time.Duration } @@ -189,7 +187,7 @@ func (sm *stateManager) Init(env tabletenv.Env, target querypb.Target) { sm.checkMySQLThrottler = sync2.NewSemaphore(1, 0) sm.timebombDuration = env.Config().OltpReadPool.TimeoutSeconds.Get() * 10 sm.hcticks = timer.NewTimer(env.Config().Healthcheck.IntervalSeconds.Get()) - sm.unhealthyThreshold = atomic.NewDuration(env.Config().Healthcheck.UnhealthyThresholdSeconds.Get()) + sm.unhealthyThreshold = sync2.NewAtomicDuration(env.Config().Healthcheck.UnhealthyThresholdSeconds.Get()) sm.shutdownGracePeriod = env.Config().GracePeriods.ShutdownSeconds.Get() sm.transitionGracePeriod = env.Config().GracePeriods.TransitionSeconds.Get() } @@ -642,7 +640,7 @@ func (sm *stateManager) refreshReplHealthLocked() (time.Duration, error) { } sm.replHealthy = false } else { - if lag > sm.unhealthyThreshold.Load() { + if lag > sm.unhealthyThreshold.Get() { if sm.replHealthy { log.Infof("Going unhealthy due to high replication lag: %v", lag) } @@ -772,5 +770,5 @@ func (sm *stateManager) IsServingString() string { } func (sm *stateManager) SetUnhealthyThreshold(v time.Duration) { - sm.unhealthyThreshold.Store(v) + sm.unhealthyThreshold.Set(v) } From 78ba1b4f308b43b68ba553bb486cd5f5283473da Mon Sep 17 00:00:00 2001 From: Jacques Grove Date: Tue, 6 Apr 2021 15:13:31 -0700 Subject: [PATCH 117/310] Actually remove the uber/atomic dep. Signed-off-by: Jacques Grove --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index a9af8dcd48a..3f78eaf5157 100644 --- a/go.mod +++ b/go.mod @@ -96,7 +96,6 @@ require ( github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible // indirect github.com/z-division/go-zookeeper v0.0.0-20190128072838-6d7457066b9b - go.uber.org/atomic v1.4.0 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/lint v0.0.0-20190930215403-16217165b5de golang.org/x/net v0.0.0-20201021035429-f5854403a974 From ea4419cd598e3ec661b8cada780ba576cb982bf2 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 2 May 2021 09:14:47 +0300 Subject: [PATCH 118/310] Online DDL: track progress and ETA in VReplication based migrations Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/executor.go | 47 ++++++++++++++++++++++++++-- go/vt/vttablet/onlineddl/schema.go | 29 +++++++++++++++++ go/vt/vttablet/onlineddl/vrepl.go | 23 +++++++++++++- 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 146b1ee87c3..978517a6d81 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -695,6 +695,9 @@ func (e *Executor) ExecuteWithVReplication(ctx context.Context, onlineDDL *schem if err := v.analyze(ctx, conn); err != nil { return err } + if err := e.updateMigrationTableRows(ctx, onlineDDL.UUID, v.tableRows); err != nil { + return err + } if err := e.updateArtifacts(ctx, onlineDDL.UUID, v.targetTable); err != nil { return err } @@ -1992,6 +1995,7 @@ func (e *Executor) readVReplStream(ctx context.Context, uuid string, okIfMissing transactionTimestamp: row.AsInt64("transaction_timestamp", 0), state: row.AsString("state", ""), message: row.AsString("message", ""), + rowsCopied: row.AsInt64("rows_copied", 0), bls: &binlogdatapb.BinlogSource{}, } if err := proto.UnmarshalText(s.source, s.bls); err != nil { @@ -2107,6 +2111,10 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i // migrationMutex lock and it's now safe to ensure vreplMigrationRunning is 1 atomic.StoreInt64(&e.vreplMigrationRunning, 1) _ = e.updateMigrationTimestamp(ctx, "liveness_timestamp", uuid) + + _ = e.updateMigrationProgressByRowsCopied(ctx, uuid, s.rowsCopied) + _ = e.updateMigrationETASecondsByProgress(ctx, uuid) + isReady, err := e.isVReplMigrationReadyToCutOver(ctx, s) if err != nil { return countRunnning, cancellable, err @@ -2447,7 +2455,7 @@ func (e *Executor) updateMySQLTable(ctx context.Context, uuid string, tableName return err } -func (e *Executor) updateETASeconds(ctx context.Context, uuid string, etaSeconds int64) error { +func (e *Executor) updateMigrationETASeconds(ctx context.Context, uuid string, etaSeconds int64) error { query, err := sqlparser.ParseAndBind(sqlUpdateMigrationETASeconds, sqltypes.Int64BindVariable(etaSeconds), sqltypes.StringBindVariable(uuid), @@ -2477,6 +2485,41 @@ func (e *Executor) updateMigrationProgress(ctx context.Context, uuid string, pro return err } +func (e *Executor) updateMigrationProgressByRowsCopied(ctx context.Context, uuid string, rowsCopied int64) error { + query, err := sqlparser.ParseAndBind(sqlUpdateMigrationProgressByRowsCopied, + sqltypes.Int64BindVariable(rowsCopied), + sqltypes.StringBindVariable(uuid), + ) + if err != nil { + return err + } + _, err = e.execQuery(ctx, query) + return err +} + +func (e *Executor) updateMigrationETASecondsByProgress(ctx context.Context, uuid string) error { + query, err := sqlparser.ParseAndBind(sqlUpdateMigrationETASecondsByProgress, + sqltypes.StringBindVariable(uuid), + ) + if err != nil { + return err + } + _, err = e.execQuery(ctx, query) + return err +} + +func (e *Executor) updateMigrationTableRows(ctx context.Context, uuid string, tableRows int64) error { + query, err := sqlparser.ParseAndBind(sqlUpdateMigrationTableRows, + sqltypes.Int64BindVariable(tableRows), + sqltypes.StringBindVariable(uuid), + ) + if err != nil { + return err + } + _, err = e.execQuery(ctx, query) + return err +} + // retryMigrationWhere retries a migration based on a given WHERE clause func (e *Executor) retryMigrationWhere(ctx context.Context, whereExpr string) (result *sqltypes.Result, err error) { e.migrationMutex.Lock() @@ -2619,7 +2662,7 @@ func (e *Executor) onSchemaMigrationStatus(ctx context.Context, uuid string, sta if err = e.updateMigrationProgress(ctx, uuid, progressPct); err != nil { return err } - if err = e.updateETASeconds(ctx, uuid, etaSeconds); err != nil { + if err = e.updateMigrationETASeconds(ctx, uuid, etaSeconds); err != nil { return err } diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index 05717e10c94..06d6c09b2d1 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -56,6 +56,7 @@ const ( alterSchemaMigrationsTableMessage = "ALTER TABLE _vt.schema_migrations add column message TEXT NOT NULL" alterSchemaMigrationsTableTableCompleteIndex = "ALTER TABLE _vt.schema_migrations add KEY table_complete_idx (migration_status, keyspace(64), mysql_table(64), completed_timestamp)" alterSchemaMigrationsTableETASeconds = "ALTER TABLE _vt.schema_migrations add column eta_seconds bigint NOT NULL DEFAULT -1" + alterSchemaMigrationsTableTableRows = "ALTER TABLE _vt.schema_migrations add column table_rows bigint NOT NULL DEFAULT 0" sqlInsertMigration = `INSERT IGNORE INTO _vt.schema_migrations ( migration_uuid, @@ -145,6 +146,32 @@ const ( WHERE migration_uuid=%a ` + sqlUpdateMigrationTableRows = `UPDATE _vt.schema_migrations + SET table_rows=%a + WHERE + migration_uuid=%a + ` + sqlUpdateMigrationProgressByRowsCopied = `UPDATE _vt.schema_migrations + SET + progress=CASE + WHEN table_rows=0 THEN 100 + ELSE LEAST(100, 100*%a/table_rows) + END + WHERE + migration_uuid=%a + ` + sqlUpdateMigrationETASecondsByProgress = `UPDATE _vt.schema_migrations + SET + eta_seconds=CASE + WHEN progress=0 THEN -1 + WHEN table_rows=0 THEN 0 + ELSE GREATEST(0, + TIMESTAMPDIFF(SECOND, started_timestamp, NOW())*((100/progress)-1) + ) + END + WHERE + migration_uuid=%a + ` sqlRetryMigrationWhere = `UPDATE _vt.schema_migrations SET migration_status='queued', @@ -297,6 +324,7 @@ const ( sqlDropTable = "DROP TABLE `%a`" sqlAlterTableOptions = "ALTER TABLE `%a` %s" sqlShowColumnsFrom = "SHOW COLUMNS FROM `%a`" + sqlShowTableStatus = "SHOW TABLE STATUS LIKE '%a'" sqlStartVReplStream = "UPDATE _vt.vreplication set state='Running' where db_name=%a and workflow=%a" sqlStopVReplStream = "UPDATE _vt.vreplication set state='Stopped' where db_name=%a and workflow=%a" sqlDeleteVReplStream = "DELETE FROM _vt.vreplication where db_name=%a and workflow=%a" @@ -356,4 +384,5 @@ var applyDDL = []string{ alterSchemaMigrationsTableMessage, alterSchemaMigrationsTableTableCompleteIndex, alterSchemaMigrationsTableETASeconds, + alterSchemaMigrationsTableTableRows, } diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 4b300e61236..5dea8c816dd 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -51,6 +51,7 @@ type VReplStream struct { transactionTimestamp int64 state string message string + rowsCopied int64 bls *binlogdatapb.BinlogSource } @@ -64,6 +65,7 @@ type VRepl struct { targetTable string pos string alterOptions string + tableRows int64 sharedPKColumns *vrepl.ColumnList @@ -151,6 +153,21 @@ func (v *VRepl) readTableColumns(ctx context.Context, conn *dbconnpool.DBConnect return vrepl.NewColumnList(columnNames), vrepl.NewColumnList(virtualColumnNames), vrepl.NewColumnList(pkColumnNames), nil } +// readTableStatus reads table status information +func (v *VRepl) readTableStatus(ctx context.Context, conn *dbconnpool.DBConnection, tableName string) (tableRows int64, err error) { + parsed := sqlparser.BuildParsedQuery(sqlShowTableStatus, tableName) + rs, err := conn.ExecuteFetch(parsed.Query, math.MaxInt64, true) + if err != nil { + return 0, err + } + row := rs.Named().Row() + if row == nil { + return 0, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot SHOW TABLE STATUS LIKE '%s'", tableName) + } + tableRows, err = row.ToInt64("Rows") + return tableRows, err +} + // getSharedColumns returns the intersection of two lists of columns in same order as the first list func (v *VRepl) getSharedColumns(sourceColumns, targetColumns *vrepl.ColumnList, sourceVirtualColumns, targetVirtualColumns *vrepl.ColumnList, columnRenameMap map[string]string) ( sourceSharedColumns *vrepl.ColumnList, targetSharedColumns *vrepl.ColumnList, sharedColumnsMap map[string]string, @@ -252,7 +269,11 @@ func (v *VRepl) analyzeAlter(ctx context.Context) error { return nil } -func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection) error { +func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection) (err error) { + v.tableRows, err = v.readTableStatus(ctx, conn, v.sourceTable) + if err != nil { + return err + } // columns: sourceColumns, sourceVirtualColumns, sourcePKColumns, err := v.readTableColumns(ctx, conn, v.sourceTable) if err != nil { From b0deaeb3712c6b505561be7ee23e7e70239b94d0 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 2 May 2021 14:00:19 +0300 Subject: [PATCH 119/310] vcopier periodically updates _vt.vreplication rows_copied Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/binlog/binlogplayer/binlog_player.go | 5 +++++ go/vt/vttablet/onlineddl/schema.go | 3 ++- go/vt/vttablet/tabletmanager/vreplication/engine.go | 3 +++ go/vt/vttablet/tabletmanager/vreplication/vcopier.go | 6 ++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index eebaa736bfa..9df65be61ef 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -642,6 +642,11 @@ func GenerateUpdatePos(uid uint32, pos mysql.Position, timeUpdated int64, txTime encodeString(mysql.EncodePosition(pos)), timeUpdated, rowsCopied, uid) } +// GenerateUpdateRowsCopied returns a statement to update the rows_copied value in the _vt.vreplication table. +func GenerateUpdateRowsCopied(uid uint32, rowsCopied int64) string { + return fmt.Sprintf("update _vt.vreplication set rows_copied=%v where id=%v", rowsCopied, uid) +} + // GenerateUpdateTime returns a statement to update time_updated in the _vt.vreplication table. func GenerateUpdateTime(uid uint32, timeUpdated int64) (string, error) { if timeUpdated == 0 { diff --git a/go/vt/vttablet/onlineddl/schema.go b/go/vt/vttablet/onlineddl/schema.go index 06d6c09b2d1..cca7814e726 100644 --- a/go/vt/vttablet/onlineddl/schema.go +++ b/go/vt/vttablet/onlineddl/schema.go @@ -336,7 +336,8 @@ const ( time_updated, transaction_timestamp, state, - message + message, + rows_copied FROM _vt.vreplication WHERE workflow=%a diff --git a/go/vt/vttablet/tabletmanager/vreplication/engine.go b/go/vt/vttablet/tabletmanager/vreplication/engine.go index d4a137469a4..ddefcd87455 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/engine.go +++ b/go/vt/vttablet/tabletmanager/vreplication/engine.go @@ -92,6 +92,9 @@ var tabletTypesStr = flag.String("vreplication_tablet_type", "MASTER,REPLICA", " // stop replicating. var waitRetryTime = 1 * time.Second +// How frequently vcopier will update _vt.vreplication rows_copied +var rowsCopiedUpdateInterval = 30 * time.Second + // Engine is the engine for handling vreplication. type Engine struct { // mu synchronizes isOpen, cancelRetry, controllers and wg. diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index c19f80555d2..15142b89e64 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -223,6 +223,9 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma lastpkpb = sqltypes.ResultToProto3(lastpkqr) } + rowsCopiedTicker := time.NewTicker(rowsCopiedUpdateInterval) + defer rowsCopiedTicker.Stop() + var pkfields []*querypb.Field var updateCopyState *sqlparser.ParsedQuery var bv map[string]*querypb.BindVariable @@ -230,6 +233,9 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma err = vc.vr.sourceVStreamer.VStreamRows(ctx, initialPlan.SendRule.Filter, lastpkpb, func(rows *binlogdatapb.VStreamRowsResponse) error { for { select { + case <-rowsCopiedTicker.C: + update := binlogplayer.GenerateUpdateRowsCopied(vc.vr.id, vc.vr.stats.CopyRowCount.Get()) + _, _ = vc.vr.dbClient.Execute(update) case <-ctx.Done(): return io.EOF default: From b0635646eda72cca156912d40d5fd84eec7fac64 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Mon, 3 May 2021 10:27:08 +0300 Subject: [PATCH 120/310] Post GA update Signed-off-by: Alkin Tezuysal --- go/vt/servenv/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 41763314b8c..274a07d7fef 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,3 +1,3 @@ package servenv -const versionName = "10.0.0-RC1" +const versionName = "10.0.0" From 64b781e25fc9ff8934118eed873018bfb3da65bd Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 3 May 2021 11:27:36 +0200 Subject: [PATCH 121/310] make sure to show that this is not a release Signed-off-by: Andres Taylor --- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 274a07d7fef..d4db09f5d9d 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,3 +1,3 @@ package servenv -const versionName = "10.0.0" +const versionName = "10.0.1-SNAPSHOT" diff --git a/java/client/pom.xml b/java/client/pom.xml index f3315380391..1194bc4ea66 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0 + 10.0.1-SNAPSHOT vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index a0edaa1ab0d..d7af68208e8 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0 + 10.0.1-SNAPSHOT vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index c09f6a6cd7d..d2a39a4371a 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0 + 10.0.1-SNAPSHOT vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 3b228313b05..626b61bd073 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.0 + 10.0.1-SNAPSHOT vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index b9a42eddcf0..c3dd46eb2af 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 10.0.0 + 10.0.1-SNAPSHOT pom Vitess Java Client libraries [Parent] From 8b0eae44fc120161861df4e55fc8d0198e5e15a3 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Tue, 4 May 2021 15:13:10 +0530 Subject: [PATCH 122/310] Fixed encoding of sql strings and added a test for it Signed-off-by: GuptaManan100 --- go/sqltypes/value.go | 6 +++++- go/vt/sqlparser/parse_test.go | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/go/sqltypes/value.go b/go/sqltypes/value.go index 51b9e41e1db..8b8bf84ad5c 100644 --- a/go/sqltypes/value.go +++ b/go/sqltypes/value.go @@ -404,8 +404,12 @@ func encodeBytesSQL(val []byte, b BinWriter) { func BufEncodeStringSQL(buf *strings.Builder, val string) { buf.WriteByte('\'') for _, ch := range val { + if ch > 255 { + buf.WriteRune(ch) + continue + } if encodedChar := SQLEncodeMap[ch]; encodedChar == DontEscape { - buf.WriteByte(byte(ch)) + buf.WriteRune(ch) } else { buf.WriteByte('\\') buf.WriteByte(encodedChar) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index a7adc76887b..e4862c8b666 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1162,6 +1162,9 @@ var ( // The last value specified is used. input: "create table foo (f timestamp null not null , g timestamp not null null)", output: "create table foo (\n\tf timestamp not null,\n\tg timestamp null\n)", + }, { + // Tests unicode character § + input: "create table invalid_enum_value_name (\n\there_be_enum enum('$§!') default null\n)", }, { input: "alter vschema create vindex hash_vdx using hash", }, { From c54416291d54e7a0a49ee392930bc613b1e9a571 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 4 May 2021 11:57:01 +0200 Subject: [PATCH 123/310] Added release script to the makefile Signed-off-by: Andres Taylor --- Makefile | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Makefile b/Makefile index f84918bb2e1..fdd2d529652 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ # limitations under the License. MAKEFLAGS = -s +GIT_STATUS := $(shell git status --porcelain) export GOBIN=$(PWD)/bin export GO111MODULE=on @@ -302,6 +303,43 @@ release: docker_base echo "git push origin v$(VERSION)" echo "Also, don't forget the upload releases/v$(VERSION).tar.gz file to GitHub releases" +do_release: +ifndef RELEASE_VERSION + echo "Set the env var RELEASE_VERSION with the release version" + exit 1 +endif +ifndef DEV_VERSION + echo "Set the env var DEV_VERSION with the version the dev branch should have after release" + exit 1 +endif +ifeq ($(strip $(GIT_STATUS)),) + echo so much clean +else + echo cannot do release with dirty git state + exit 1 + echo so much win +endif +# Pre checks passed. Let's change the current version + cd java && mvn versions:set -DnewVersion=$(RELEASE_VERSION) + echo package servenv > go/vt/servenv/version.go + echo >> go/vt/servenv/version.go + echo const versionName = \"$(RELEASE_VERSION)\" >> go/vt/servenv/version.go + echo -n Pausing so relase notes can be added. Press enter to continue + read line + git add --all + git commit -n -s -m "Release commit for $(RELEASE_VERSION)" + git tag -m Version\ $(RELEASE_VERSION) v$(RELEASE_VERSION) + cd java && mvn versions:set -DnewVersion=$(DEV_VERSION) + echo package servenv > go/vt/servenv/version.go + echo >> go/vt/servenv/version.go + echo const versionName = \"$(DEV_VERSION)\" >> go/vt/servenv/version.go + git add --all + git commit -n -s -m "Back to dev mode" + echo "Release preparations successful" + echo "A git tag was created, you can push it with:" + echo " git push upstream v$(RELEASE_VERSION)" + echo "The git branch has also been updated. You need to push it and get it merged" + tools: echo $$(date): Installing dependencies ./bootstrap.sh From f7304cd1893accfefee0525910098a8e0e68deec Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 4 May 2021 14:55:42 +0300 Subject: [PATCH 124/310] Release commit for 10.0.1 Signed-off-by: Alkin Tezuysal --- doc/releasenotes/10_0_0_release_notes.md | 3 +++ doc/releasenotes/10_0_1_release_notes.md | 2 ++ go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 8 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 doc/releasenotes/10_0_1_release_notes.md diff --git a/doc/releasenotes/10_0_0_release_notes.md b/doc/releasenotes/10_0_0_release_notes.md index 3deee7f380c..ebfb3ed7201 100644 --- a/doc/releasenotes/10_0_0_release_notes.md +++ b/doc/releasenotes/10_0_0_release_notes.md @@ -1,5 +1,8 @@ This release complies with VEP-3 which removes the upgrade order requirement. Components can be upgraded in any order. It is recommended that the upgrade order should still be followed if possible, except to canary test the new version of VTGate before upgrading the rest of the components. +## Known Issues +* Running binaries with `--version` or calling @@version from a MySQL client still shows `10.0.0-RC1` (Note: fixed in v10.0.1) +* Online DDL [cannot be used](https://github.com/vitessio/vitess/pull/7873#issuecomment-822798180) if you are using the keyspace filtering feature of VTGate The following PRs made changes to behaviors that clients might rely on. They should be reviewed carefully so that client code can be changed in concert with a Vitess release deployment. diff --git a/doc/releasenotes/10_0_1_release_notes.md b/doc/releasenotes/10_0_1_release_notes.md new file mode 100644 index 00000000000..6c37ad54f2d --- /dev/null +++ b/doc/releasenotes/10_0_1_release_notes.md @@ -0,0 +1,2 @@ +## Bugs Fixed +* Running binaries with `--version` or calling @@version from a MySQL client still shows `10.0.0-RC1` diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index d4db09f5d9d..1538ba80e99 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,3 +1,3 @@ package servenv -const versionName = "10.0.1-SNAPSHOT" +const versionName = "10.0.1" diff --git a/java/client/pom.xml b/java/client/pom.xml index 1194bc4ea66..8ccb9f19d11 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1-SNAPSHOT + 10.0.1 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index d7af68208e8..946af96b6c0 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1-SNAPSHOT + 10.0.1 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index d2a39a4371a..6dde1123bca 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1-SNAPSHOT + 10.0.1 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 626b61bd073..52a0775da9d 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1-SNAPSHOT + 10.0.1 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index c3dd46eb2af..4a906ac27dd 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 10.0.1-SNAPSHOT + 10.0.1 pom Vitess Java Client libraries [Parent] From 431eb99676adf33b16e54bd239beb4b9f537ca3a Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 4 May 2021 14:55:44 +0300 Subject: [PATCH 125/310] Back to dev mode Signed-off-by: Alkin Tezuysal --- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 1538ba80e99..1aaeed280b4 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,3 +1,3 @@ package servenv -const versionName = "10.0.1" +const versionName = "10.0.2-SNAPSHOT" diff --git a/java/client/pom.xml b/java/client/pom.xml index 8ccb9f19d11..6290f8f4376 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1 + 10.0.2-SNAPSHOT vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index 946af96b6c0..ff8403af132 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1 + 10.0.2-SNAPSHOT vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 6dde1123bca..912d5637671 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1 + 10.0.2-SNAPSHOT vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 52a0775da9d..85bff36a1d8 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.1 + 10.0.2-SNAPSHOT vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 4a906ac27dd..074bf254e60 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 10.0.1 + 10.0.2-SNAPSHOT pom Vitess Java Client libraries [Parent] From 2e35451769ae4f00d9aeb0f08278a3e63ed16648 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Sat, 1 May 2021 12:23:18 +0530 Subject: [PATCH 126/310] ddl bypass planner Signed-off-by: Harshit Gangal Signed-off-by: Rafael Chacon --- go/vt/vtgate/planbuilder/ddl.go | 15 +++++++++++++++ .../planbuilder/testdata/bypass_cases.txt | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index 77873b3abbe..d61a8997ced 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -25,6 +25,9 @@ const ( // and which chooses which of the two to invoke at runtime. func buildGeneralDDLPlan(sql string, ddlStatement sqlparser.DDLStatement, vschema ContextVSchema) (engine.Primitive, error) { normalDDLPlan, onlineDDLPlan, err := buildDDLPlans(sql, ddlStatement, vschema) + if vschema.Destination() != nil { + return buildByPassDDLPlan(sql, vschema) + } if err != nil { return nil, err } @@ -38,6 +41,18 @@ func buildGeneralDDLPlan(sql string, ddlStatement sqlparser.DDLStatement, vschem }, nil } +func buildByPassDDLPlan(sql string, vschema ContextVSchema) (engine.Primitive, error) { + keyspace, err := vschema.DefaultKeyspace() + if err != nil { + return nil, err + } + return &engine.Send{ + Keyspace: keyspace, + TargetDestination: vschema.Destination(), + Query: sql, + }, nil +} + func buildDDLPlans(sql string, ddlStatement sqlparser.DDLStatement, vschema ContextVSchema) (*engine.Send, *engine.OnlineDDL, error) { var destination key.Destination var keyspace *vindexes.Keyspace diff --git a/go/vt/vtgate/planbuilder/testdata/bypass_cases.txt b/go/vt/vtgate/planbuilder/testdata/bypass_cases.txt index daafda9d360..7bb0fc36af5 100644 --- a/go/vt/vtgate/planbuilder/testdata/bypass_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/bypass_cases.txt @@ -156,3 +156,21 @@ "SingleShardOnly": true } } + +# create table +"create /* test */ table t1(id bigint, primary key(id)) /* comments */" +{ + "QueryType": "DDL", + "Original": "create /* test */ table t1(id bigint, primary key(id)) /* comments */", + "Instructions": { + "OperatorType": "Send", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "TargetDestination": "Shard(-80)", + "IsDML": false, + "Query": "create /* test */ table t1(id bigint, primary key(id)) /* comments */", + "SingleShardOnly": false + } +} From 5501139822e1a166a889765f89ae5cfa9cf261d2 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Tue, 4 May 2021 22:40:26 -0700 Subject: [PATCH 127/310] Fixes bad conflict resolution Signed-off-by: Rafael Chacon --- go/vt/vtgate/planbuilder/ddl.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/vt/vtgate/planbuilder/ddl.go b/go/vt/vtgate/planbuilder/ddl.go index d61a8997ced..f0627c8723c 100644 --- a/go/vt/vtgate/planbuilder/ddl.go +++ b/go/vt/vtgate/planbuilder/ddl.go @@ -24,10 +24,11 @@ const ( // This is why we return a compound primitive (DDL) which contains fully populated primitives (Send & OnlineDDL), // and which chooses which of the two to invoke at runtime. func buildGeneralDDLPlan(sql string, ddlStatement sqlparser.DDLStatement, vschema ContextVSchema) (engine.Primitive, error) { - normalDDLPlan, onlineDDLPlan, err := buildDDLPlans(sql, ddlStatement, vschema) if vschema.Destination() != nil { return buildByPassDDLPlan(sql, vschema) } + + normalDDLPlan, onlineDDLPlan, err := buildDDLPlans(sql, ddlStatement, vschema) if err != nil { return nil, err } From be3ce273d465d0023d4cb50d76c3ba48971849de Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 5 May 2021 11:15:53 +0530 Subject: [PATCH 128/310] merge sort stream fix Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/merge_sort.go | 5 ++-- go/vt/vtgate/executor_select_test.go | 36 +++++++++++++++++++++++ go/vt/vttablet/sandboxconn/sandboxconn.go | 18 ++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/go/vt/vtgate/engine/merge_sort.go b/go/vt/vtgate/engine/merge_sort.go index 6aa01e4d4d4..59d3c1ab3bb 100644 --- a/go/vt/vtgate/engine/merge_sort.go +++ b/go/vt/vtgate/engine/merge_sort.go @@ -81,7 +81,7 @@ func (ms *MergeSort) StreamExecute(vcursor VCursor, bindVars map[string]*querypb handles := make([]*streamHandle, len(ms.Primitives)) for i, input := range ms.Primitives { - handles[i] = runOneStream(vcursor, input, bindVars, wantfields) + handles[i] = runOneStream(ctx, vcursor, input, bindVars, wantfields) // Need fields only from first handle, if wantfields was true. wantfields = false } @@ -183,12 +183,11 @@ type streamHandle struct { } // runOnestream starts a streaming query on one shard, and returns a streamHandle for it. -func runOneStream(vcursor VCursor, input StreamExecutor, bindVars map[string]*querypb.BindVariable, wantfields bool) *streamHandle { +func runOneStream(ctx context.Context, vcursor VCursor, input StreamExecutor, bindVars map[string]*querypb.BindVariable, wantfields bool) *streamHandle { handle := &streamHandle{ fields: make(chan []*querypb.Field, 1), row: make(chan []sqltypes.Value, 10), } - ctx := vcursor.Context() go func() { defer close(handle.fields) diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index d5783b070ce..50eab386464 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -19,8 +19,10 @@ package vtgate import ( "fmt" "reflect" + "runtime" "strings" "testing" + "time" "vitess.io/vitess/go/test/utils" @@ -2420,3 +2422,37 @@ func TestSelectFromInformationSchema(t *testing.T) { require.NoError(t, err) assert.Equal(t, sbc1.StringQueries(), []string{"select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname"}) } + +func TestStreamOrderByLimitWithMultipleResults(t *testing.T) { + // Special setup: Don't use createLegacyExecutorEnv. + cell := "aa" + hc := discovery.NewFakeHealthCheck() + s := createSandbox("TestExecutor") + s.VSchema = executorVSchema + getSandbox(KsTestUnsharded).VSchema = unshardedVSchema + serv := new(sandboxTopo) + resolver := newTestResolver(hc, serv, cell) + shards := []string{"-20", "20-40", "40-60", "60-80", "80-a0", "a0-c0", "c0-e0", "e0-"} + count := 1 + for _, shard := range shards { + sbc := hc.AddTestTablet(cell, shard, 1, "TestExecutor", shard, topodatapb.TabletType_MASTER, true, 1, nil) + sbc.SetResults([]*sqltypes.Result{ + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col", "int32|int32"), fmt.Sprintf("%d|%d", count, count)), + sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col", "int32|int32"), fmt.Sprintf("%d|%d", count+10, count)), + }) + count++ + } + executor := NewExecutor(context.Background(), serv, cell, resolver, false, testBufferSize, testCacheSize) + before := runtime.NumGoroutine() + + query := "select id, col from user order by id limit 2" + gotResult, err := executorStream(executor, query) + require.NoError(t, err) + + wantResult := sqltypes.MakeTestResult(sqltypes.MakeTestFields("id|col", "int32|int32"), "1|1", "2|2") + wantResult.RowsAffected = 0 + utils.MustMatch(t, wantResult, gotResult) + // some sleep to close all goroutines. + time.Sleep(100 * time.Millisecond) + assert.GreaterOrEqual(t, before, runtime.NumGoroutine(), "left open goroutines lingering") +} diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 823cb312de1..89bb04eaf1f 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -198,10 +198,24 @@ func (sbc *SandboxConn) StreamExecute(ctx context.Context, target *querypb.Targe sbc.sExecMu.Unlock() return err } - nextRs := sbc.getNextResult() + if sbc.results == nil { + nextRs := sbc.getNextResult() + sbc.sExecMu.Unlock() + return callback(nextRs) + } + + for len(sbc.results) > 0 { + nextRs := sbc.getNextResult() + sbc.sExecMu.Unlock() + err := callback(nextRs) + if err != nil { + return err + } + sbc.sExecMu.Lock() + } sbc.sExecMu.Unlock() - return callback(nextRs) + return nil } // Begin is part of the QueryService interface. From cde403a65dfae01da6d1211744c4314ad81857f4 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 22 Apr 2021 23:20:21 +0530 Subject: [PATCH 129/310] squashed backport of PR 7879 Signed-off-by: Harshit Gangal --- .../endtoend/vtgate/reservedconn/main_test.go | 6 +- .../reservedconn/reconnect1/main_test.go | 150 ++++++++++++++++++ .../reservedconn/reconnect2/main_test.go | 134 ++++++++++++++++ go/vt/discovery/fake_healthcheck.go | 19 ++- go/vt/discovery/healthcheck.go | 21 ++- go/vt/srvtopo/resilient_server_test.go | 6 +- go/vt/srvtopo/resolver.go | 2 +- go/vt/vterrors/constants.go | 34 ++++ go/vt/vtgate/discoverygateway.go | 2 +- go/vt/vtgate/gateway.go | 4 +- go/vt/vtgate/safe_session.go | 2 +- go/vt/vtgate/scatter_conn.go | 147 ++++++++++------- go/vt/vtgate/scatter_conn_test.go | 64 ++++++++ go/vt/vtgate/tabletgateway.go | 4 +- go/vt/vtgate/tx_conn.go | 2 +- go/vt/vttablet/sandboxconn/sandboxconn.go | 2 +- .../tabletconntest/fakequeryservice.go | 2 +- go/vt/vttablet/tabletserver/state_manager.go | 33 ++-- .../tabletserver/state_manager_test.go | 4 +- test/config.json | 18 +++ 20 files changed, 541 insertions(+), 115 deletions(-) create mode 100644 go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go create mode 100644 go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go create mode 100644 go/vt/vterrors/constants.go diff --git a/go/test/endtoend/vtgate/reservedconn/main_test.go b/go/test/endtoend/vtgate/reservedconn/main_test.go index 90d71e71753..9bac75fd1e3 100644 --- a/go/test/endtoend/vtgate/reservedconn/main_test.go +++ b/go/test/endtoend/vtgate/reservedconn/main_test.go @@ -126,10 +126,8 @@ func TestMain(m *testing.M) { } // Start vtgate - clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s"} - vtgateProcess := clusterInstance.NewVtgateInstance() - vtgateProcess.SysVarSetEnabled = true - if err := vtgateProcess.Setup(); err != nil { + clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s", "-enable_system_settings=true"} // enable reserved connection. + if err := clusterInstance.StartVtgate(); err != nil { return 1 } diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go new file mode 100644 index 00000000000..598d23345fe --- /dev/null +++ b/go/test/endtoend/vtgate/reservedconn/reconnect1/main_test.go @@ -0,0 +1,150 @@ +/* +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 reservedconn + +import ( + "context" + "flag" + "os" + "testing" + + "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 + vtParams mysql.ConnParams + keyspaceName = "ks" + cell = "zone1" + hostname = "localhost" + sqlSchema = `create table test(id bigint primary key)Engine=InnoDB;` + + vSchema = ` + { + "sharded":true, + "vindexes": { + "hash_index": { + "type": "hash" + } + }, + "tables": { + "test":{ + "column_vindexes": [ + { + "column": "id", + "name": "hash_index" + } + ] + } + } + } + ` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + 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: sqlSchema, + VSchema: vSchema, + } + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, true); err != nil { + return 1 + } + + // Start vtgate + clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s", "-enable_system_settings=true"} // enable reserved connection. + if err := clusterInstance.StartVtgate(); err != nil { + return 1 + } + + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + return m.Run() + }() + os.Exit(exitCode) +} + +func TestServingChange(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + checkedExec(t, conn, "use @rdonly") + checkedExec(t, conn, "set sql_mode = ''") + + // to see rdonly is available and + // also this will create reserved connection on rdonly on -80 and 80- shards. + _, err = exec(t, conn, "select * from test") + for err != nil { + _, err = exec(t, conn, "select * from test") + } + + // changing rdonly tablet to spare (non serving). + rdonlyTablet := clusterInstance.Keyspaces[0].Shards[0].Rdonly() + err = clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", rdonlyTablet.Alias, "spare") + require.NoError(t, err) + + // this should fail as there is no rdonly present + _, err = exec(t, conn, "select * from test") + require.Error(t, err) + + // changing replica tablet to rdonly to make rdonly available for serving. + replicaTablet := clusterInstance.Keyspaces[0].Shards[0].Replica() + err = clusterInstance.VtctlclientProcess.ExecuteCommand("ChangeTabletType", replicaTablet.Alias, "rdonly") + require.NoError(t, err) + + // to see/make the new rdonly available + err = clusterInstance.VtctlclientProcess.ExecuteCommand("Ping", replicaTablet.Alias) + require.NoError(t, err) + + // this should pass now as there is rdonly present + _, err = exec(t, conn, "select * from test") + assert.NoError(t, err) +} + +func exec(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { + t.Helper() + return conn.ExecuteFetch(query, 1000, true) +} + +func checkedExec(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 +} diff --git a/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go b/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go new file mode 100644 index 00000000000..627f203647e --- /dev/null +++ b/go/test/endtoend/vtgate/reservedconn/reconnect2/main_test.go @@ -0,0 +1,134 @@ +/* +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 reservedconn + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + + "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 + vtParams mysql.ConnParams + keyspaceName = "ks" + cell = "zone1" + hostname = "localhost" + sqlSchema = `create table test(id bigint primary key)Engine=InnoDB;` + + vSchema = ` + { + "sharded":true, + "vindexes": { + "hash_index": { + "type": "hash" + } + }, + "tables": { + "test":{ + "column_vindexes": [ + { + "column": "id", + "name": "hash_index" + } + ] + } + } + } + ` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + 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: sqlSchema, + VSchema: vSchema, + } + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-transaction-timeout", "5"} + if err := clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, true); err != nil { + return 1 + } + + // Start vtgate + clusterInstance.VtGateExtraArgs = []string{"-lock_heartbeat_time", "2s", "-enable_system_settings=true"} // enable reserved connection. + if err := clusterInstance.StartVtgate(); err != nil { + return 1 + } + + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + return m.Run() + }() + os.Exit(exitCode) +} + +func TestTabletChange(t *testing.T) { + conn, err := mysql.Connect(context.Background(), &vtParams) + require.NoError(t, err) + defer conn.Close() + + checkedExec(t, conn, "use @master") + checkedExec(t, conn, "set sql_mode = ''") + + // this will create reserved connection on master on -80 and 80- shards. + checkedExec(t, conn, "select * from test") + + // Change Master + err = clusterInstance.VtctlclientProcess.ExecuteCommand("PlannedReparentShard", "-keyspace_shard", fmt.Sprintf("%s/%s", keyspaceName, "-80")) + require.NoError(t, err) + + // this should pass as there is new master tablet and is serving. + _, err = exec(t, conn, "select * from test") + assert.NoError(t, err) +} + +func exec(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { + t.Helper() + return conn.ExecuteFetch(query, 1000, true) +} + +func checkedExec(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 +} diff --git a/go/vt/discovery/fake_healthcheck.go b/go/vt/discovery/fake_healthcheck.go index c762eb48bec..bbb1ec98baa 100644 --- a/go/vt/discovery/fake_healthcheck.go +++ b/go/vt/discovery/fake_healthcheck.go @@ -21,20 +21,18 @@ import ( "sort" "sync" - "vitess.io/vitess/go/sync2" - "github.com/golang/protobuf/proto" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" - + "vitess.io/vitess/go/sync2" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/queryservice" "vitess.io/vitess/go/vt/vttablet/sandboxconn" querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) var ( @@ -146,16 +144,23 @@ func (fhc *FakeHealthCheck) ReplaceTablet(old, new *topodatapb.Tablet) { } // TabletConnection returns the TabletConn of the given tablet. -func (fhc *FakeHealthCheck) TabletConnection(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (fhc *FakeHealthCheck) TabletConnection(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) { aliasStr := topoproto.TabletAliasString(alias) fhc.mu.RLock() defer fhc.mu.RUnlock() for _, item := range fhc.items { if proto.Equal(alias, item.ts.Tablet.Alias) { + if !item.ts.Serving { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) + } + if target != nil && !proto.Equal(item.ts.Target, target) { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, item.ts.Target, target) + } + return item.ts.Conn, nil } } - return nil, vterrors.Errorf(vtrpc.Code_NOT_FOUND, "tablet %v not found", aliasStr) + return nil, vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "tablet %v not found", aliasStr) } // CacheStatus returns the status for each tablet diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 4af9dfd7202..90a64a788aa 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -45,19 +45,18 @@ import ( "sync" "time" - "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/vterrors" - "vitess.io/vitess/go/vt/vttablet/queryservice" + "github.com/golang/protobuf/proto" "vitess.io/vitess/go/flagutil" - - "vitess.io/vitess/go/vt/topo" - "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/topodata" + "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/vt/vttablet/queryservice" ) var ( @@ -177,7 +176,7 @@ type HealthCheck interface { WaitForAllServingTablets(ctx context.Context, targets []*query.Target) error // TabletConnection returns the TabletConn of the given tablet. - TabletConnection(alias *topodata.TabletAlias) (queryservice.QueryService, error) + TabletConnection(alias *topodata.TabletAlias, target *query.Target) (queryservice.QueryService, error) // RegisterStats registers the connection counts stats RegisterStats() @@ -693,7 +692,7 @@ func (hc *HealthCheckImpl) waitForTablets(ctx context.Context, targets []*query. } // TabletConnection returns the Connection to a given tablet. -func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias) (queryservice.QueryService, error) { +func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias, target *query.Target) (queryservice.QueryService, error) { hc.mu.Lock() thc := hc.healthByAlias[tabletAliasString(topoproto.TabletAliasString(alias))] hc.mu.Unlock() @@ -701,6 +700,12 @@ func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias) (querys //TODO: test that throws this error return nil, vterrors.Errorf(vtrpc.Code_NOT_FOUND, "tablet: %v is either down or nonexistent", alias) } + if !thc.Serving { + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, vterrors.NotServing) + } + if target != nil && !proto.Equal(thc.Target, target) { + return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, thc.Target, target) + } return thc.Connection(), nil } diff --git a/go/vt/srvtopo/resilient_server_test.go b/go/vt/srvtopo/resilient_server_test.go index 40e50c200db..76f6d18dcbe 100644 --- a/go/vt/srvtopo/resilient_server_test.go +++ b/go/vt/srvtopo/resilient_server_test.go @@ -310,7 +310,8 @@ func TestGetSrvKeyspace(t *testing.T) { time.Sleep(*srvTopoCacheTTL) - timeoutCtx, _ := context.WithTimeout(context.Background(), *srvTopoCacheRefresh*2) //nolint + timeoutCtx, cancel := context.WithTimeout(context.Background(), *srvTopoCacheRefresh*2) //nolint + defer cancel() _, err = rs.GetSrvKeyspace(timeoutCtx, "test_cell", "test_ks") wantErr := "timed out waiting for keyspace" if err == nil || err.Error() != wantErr { @@ -614,7 +615,8 @@ func TestGetSrvKeyspaceNames(t *testing.T) { time.Sleep(*srvTopoCacheTTL) - timeoutCtx, _ := context.WithTimeout(context.Background(), *srvTopoCacheRefresh*2) //nolint + timeoutCtx, cancel := context.WithTimeout(context.Background(), *srvTopoCacheRefresh*2) //nolint + defer cancel() _, err = rs.GetSrvKeyspaceNames(timeoutCtx, "test_cell", false) wantErr := "timed out waiting for keyspace names" if err == nil || err.Error() != wantErr { diff --git a/go/vt/srvtopo/resolver.go b/go/vt/srvtopo/resolver.go index 7134b0b9852..e668e0e248c 100644 --- a/go/vt/srvtopo/resolver.go +++ b/go/vt/srvtopo/resolver.go @@ -40,7 +40,7 @@ type Gateway interface { queryservice.QueryService // QueryServiceByAlias returns a QueryService - QueryServiceByAlias(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) + QueryServiceByAlias(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) } // A Resolver can resolve keyspace ids and key ranges into ResolvedShard* diff --git a/go/vt/vterrors/constants.go b/go/vt/vterrors/constants.go new file mode 100644 index 00000000000..d66a97464d7 --- /dev/null +++ b/go/vt/vterrors/constants.go @@ -0,0 +1,34 @@ +/* +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 vterrors + +import "regexp" + +// Operation not allowed error +const ( + NotServing = "operation not allowed in state NOT_SERVING" + ShuttingDown = "operation not allowed in state SHUTTING_DOWN" +) + +// RxOp regex for operation not allowed error +var RxOp = regexp.MustCompile("operation not allowed in state (NOT_SERVING|SHUTTING_DOWN)") + +// WrongTablet for invalid tablet type error +const WrongTablet = "wrong tablet type" + +// RxWrongTablet regex for invalid tablet type error +var RxWrongTablet = regexp.MustCompile("(wrong|invalid) tablet type") diff --git a/go/vt/vtgate/discoverygateway.go b/go/vt/vtgate/discoverygateway.go index 6eac1575fa7..1d9b4dcc363 100644 --- a/go/vt/vtgate/discoverygateway.go +++ b/go/vt/vtgate/discoverygateway.go @@ -407,6 +407,6 @@ func (dg *DiscoveryGateway) getStatsAggregator(target *querypb.Target) *TabletSt } // QueryServiceByAlias satisfies the Gateway interface -func (dg *DiscoveryGateway) QueryServiceByAlias(_ *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (dg *DiscoveryGateway) QueryServiceByAlias(_ *topodatapb.TabletAlias, _ *querypb.Target) (queryservice.QueryService, error) { return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "DiscoveryGateway does not implement QueryServiceByAlias") } diff --git a/go/vt/vtgate/gateway.go b/go/vt/vtgate/gateway.go index 1398ad5419e..86a015ab77a 100644 --- a/go/vt/vtgate/gateway.go +++ b/go/vt/vtgate/gateway.go @@ -17,6 +17,8 @@ import ( "flag" "time" + querypb "vitess.io/vitess/go/vt/proto/query" + "context" "vitess.io/vitess/go/vt/log" @@ -68,7 +70,7 @@ type Gateway interface { TabletsCacheStatus() discovery.TabletsCacheStatusList // TabletByAlias returns a QueryService - QueryServiceByAlias(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) + QueryServiceByAlias(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) } // Creator is the factory method which can create the actual gateway object. diff --git a/go/vt/vtgate/safe_session.go b/go/vt/vtgate/safe_session.go index ead6619b4af..5a83abe1fce 100644 --- a/go/vt/vtgate/safe_session.go +++ b/go/vt/vtgate/safe_session.go @@ -519,7 +519,7 @@ func removeShard(tabletAlias *topodatapb.TabletAlias, sessions []*vtgatepb.Sessi } } if idx == -1 { - return sessions, nil + return nil, vterrors.New(vtrpcpb.Code_INTERNAL, "[BUG] tried to remove missing shard") } return append(sessions[:idx], sessions[idx+1:]...), nil } diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index e63f5499f80..e8d1da842e5 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -145,6 +145,14 @@ func (stc *ScatterConn) endAction(startTime time.Time, allErrors *concurrency.Al stc.timings.Record(statsKey, startTime) } +type reset int + +const ( + none reset = iota + shard + newQS +) + // ExecuteMultiShard is like Execute, // but each shard gets its own Sql Queries and BindVariables. // @@ -206,60 +214,82 @@ func (stc *ScatterConn) ExecuteMultiShard( if autocommit { // As this is auto-commit, the transactionID is supposed to be zero. - if info.transactionID != int64(0) { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "in autocommit mode, transactionID should be zero but was: %d", info.transactionID) + if transactionID != int64(0) { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "in autocommit mode, transactionID should be zero but was: %d", transactionID) } } qs, err = getQueryService(rs, info) if err != nil { - return nil, err + // an error here could mean that the tablet we were targeting earlier has changed type. + // if we have a transaction, we'll have to fail, but if we only had a reserved connection, + // we can create a new reserved connection to a new tablet that is on the right shard + // and has the right type + switch info.actionNeeded { + case nothing: + info.actionNeeded = reserve + case begin: + info.actionNeeded = reserveBegin + default: + return nil, err + } + retry := checkAndResetShardSession(info, err, session) + if retry != newQS { + return nil, err + } + qs = rs.Gateway + } + + retryRequest := func(exec func()) { + retry := checkAndResetShardSession(info, err, session) + switch retry { + case newQS: + // Current tablet is not available, try querying new tablet using gateway. + qs = rs.Gateway + fallthrough + case shard: + // if we need to reset a reserved connection, here is our chance to try executing again, + // against a new connection + exec() + } } switch info.actionNeeded { case nothing: innerqr, err = qs.Execute(ctx, rs.Target, queries[i].Sql, queries[i].BindVariables, info.transactionID, info.reservedID, opts) if err != nil { - shouldRetry := checkAndResetShardSession(info, err, session) - if shouldRetry { - // we seem to have lost our connection. if it was a reserved connection, let's try to recreate it + retryRequest(func() { + // we seem to have lost our connection. it was a reserved connection, let's try to recreate it info.actionNeeded = reserve innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, 0 /*transactionId*/, opts) - } - if err != nil { - return info.updateReservedID(reservedID, alias), err - } + }) } case begin: - innerqr, transactionID, alias, err = qs.BeginExecute(ctx, rs.Target, session.Savepoints, queries[i].Sql, queries[i].BindVariables, info.reservedID, opts) + innerqr, transactionID, alias, err = qs.BeginExecute(ctx, rs.Target, session.Savepoints, queries[i].Sql, queries[i].BindVariables, reservedID, opts) if err != nil { if transactionID != 0 { - return info.updateTransactionID(transactionID, alias), err + // if we had an open transaction, we can't repair anything and have to exit here. + // we still keep the transaction open - an error doesn't immediately close the transaction + break } - shouldRetry := checkAndResetShardSession(info, err, session) - if shouldRetry { - // we seem to have lost our connection. if it was a reserved connection, let's try to recreate it + retryRequest(func() { + // we seem to have lost our connection. it was a reserved connection, let's try to recreate it info.actionNeeded = reserveBegin innerqr, transactionID, reservedID, alias, err = qs.ReserveBeginExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, opts) - } - if err != nil { - return info.updateTransactionAndReservedID(transactionID, reservedID, alias), err - } - + }) } case reserve: - innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, info.transactionID, opts) - if err != nil { - return info.updateReservedID(reservedID, alias), err - } + innerqr, reservedID, alias, err = qs.ReserveExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, transactionID, opts) case reserveBegin: innerqr, transactionID, reservedID, alias, err = qs.ReserveBeginExecute(ctx, rs.Target, session.SetPreQueries(), queries[i].Sql, queries[i].BindVariables, opts) - if err != nil { - return info.updateTransactionAndReservedID(transactionID, reservedID, alias), err - } default: return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "BUG: unexpected actionNeeded on ScatterConn#ExecuteMultiShard %v", info.actionNeeded) } + // We need to new shard info irrespective of the error. + newInfo := info.updateTransactionAndReservedID(transactionID, reservedID, alias) + if err != nil { + return newInfo, err + } mu.Lock() defer mu.Unlock() @@ -267,7 +297,7 @@ func (stc *ScatterConn) ExecuteMultiShard( if ignoreMaxMemoryRows || len(qr.Rows) <= *maxMemoryRows { qr.AppendResult(innerqr) } - return info.updateTransactionAndReservedID(transactionID, reservedID, alias), nil + return newInfo, nil }, ) @@ -278,28 +308,32 @@ func (stc *ScatterConn) ExecuteMultiShard( return qr, allErrors.GetErrors() } -var errRegx = regexp.MustCompile("transaction ([a-z0-9:]+) (?:ended|not found)") - -func checkAndResetShardSession(info *shardActionInfo, err error, session *SafeSession) bool { - if info.reservedID != 0 && info.transactionID == 0 && wasConnectionClosed(err) { - session.ResetShard(info.alias) - return true +func checkAndResetShardSession(info *shardActionInfo, err error, session *SafeSession) reset { + retry := none + if info.reservedID != 0 && info.transactionID == 0 { + if wasConnectionClosed(err) { + retry = shard + } + if requireNewQS(err) { + retry = newQS + } } - return false + if retry != none { + _ = session.ResetShard(info.alias) + } + return retry } func getQueryService(rs *srvtopo.ResolvedShard, info *shardActionInfo) (queryservice.QueryService, error) { _, usingLegacyGw := rs.Gateway.(*DiscoveryGateway) - if usingLegacyGw { - switch info.actionNeeded { - case reserve, reserveBegin: - return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "reserved connections are not supported on old gen gateway") - } + if usingLegacyGw && + (info.actionNeeded == reserve || info.actionNeeded == reserveBegin) { + return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "reserved connections are not supported on old gen gateway") } if usingLegacyGw || info.alias == nil { return rs.Gateway, nil } - return rs.Gateway.QueryServiceByAlias(info.alias) + return rs.Gateway.QueryServiceByAlias(info.alias, rs.Target) } func (stc *ScatterConn) processOneStreamingResult(mu *sync.Mutex, fieldSent *bool, qr *sqltypes.Result, callback func(*sqltypes.Result) error) error { @@ -675,12 +709,21 @@ func (stc *ScatterConn) ExecuteLock( return qr, err } +var txClosed = regexp.MustCompile("transaction ([a-z0-9:]+) (?:ended|not found)") + func wasConnectionClosed(err error) bool { sqlErr := mysql.NewSQLErrorFromError(err).(*mysql.SQLError) + message := sqlErr.Error() return sqlErr.Number() == mysql.CRServerGone || sqlErr.Number() == mysql.CRServerLost || - (sqlErr.Number() == mysql.ERQueryInterrupted && errRegx.MatchString(sqlErr.Error())) + (sqlErr.Number() == mysql.ERQueryInterrupted && txClosed.MatchString(message)) +} + +func requireNewQS(err error) bool { + code := vterrors.Code(err) + msg := err.Error() + return code == vtrpcpb.Code_FAILED_PRECONDITION && (vterrors.RxOp.MatchString(msg) || vterrors.RxWrongTablet.MatchString(msg)) } // actionInfo looks at the current session, and returns information about what needs to be done for this tablet @@ -738,25 +781,9 @@ type shardActionInfo struct { alias *topodatapb.TabletAlias } -func (sai *shardActionInfo) updateTransactionID(txID int64, alias *topodatapb.TabletAlias) *shardActionInfo { - if txID == 0 { - // As transaction id is ZERO, there is nothing to update in session shard sessions. - return nil - } - return sai.updateTransactionAndReservedID(txID, sai.reservedID, alias) -} - -func (sai *shardActionInfo) updateReservedID(rID int64, alias *topodatapb.TabletAlias) *shardActionInfo { - if rID == 0 { - // As reserved id is ZERO, there is nothing to update in session shard sessions. - return nil - } - return sai.updateTransactionAndReservedID(sai.transactionID, rID, alias) -} - func (sai *shardActionInfo) updateTransactionAndReservedID(txID int64, rID int64, alias *topodatapb.TabletAlias) *shardActionInfo { - if txID == 0 && rID == 0 { - // As transaction id and reserved id is ZERO, there is nothing to update in session shard sessions. + if txID == sai.transactionID && rID == sai.reservedID { + // As transaction id and reserved id have not changed, there is nothing to update in session shard sessions. return nil } newInfo := *sai diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index 49b85b1123a..a0797f89f23 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -19,6 +19,8 @@ package vtgate import ( "testing" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "github.com/stretchr/testify/assert" "vitess.io/vitess/go/mysql" @@ -321,6 +323,68 @@ func TestReservedConnFail(t *testing.T) { assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + + sbc0.Queries = nil + sbc0.EphemeralShardErr = vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "operation not allowed in state NOT_SERVING during query: query1") + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + + sbc0.Queries = nil + sbc0.EphemeralShardErr = vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: REPLICA, want: MASTER or MASTER") + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 2, len(sbc0.Queries), "one for the failed attempt, and one for the retry") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + oldRId = session.Session.ShardSessions[0].ReservedId + oldAlias := session.Session.ShardSessions[0].TabletAlias + + // Test Setup + tablet0 := sbc0.Tablet() + ths := hc.GetHealthyTabletStats(&querypb.Target{ + Keyspace: tablet0.GetKeyspace(), + Shard: tablet0.GetShard(), + TabletType: tablet0.GetType(), + }) + sbc0Th := ths[0] + sbc0Th.Serving = false + sbc0Rep := hc.AddTestTablet("aa", "0", 2, keyspace, "0", topodatapb.TabletType_REPLICA, true, 1, nil) + + sbc0.Queries = nil + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 0, len(sbc0.Queries), "no attempt should be made as the tablet is not serving") + assert.Equal(t, 1, len(sbc0Rep.Queries), "first attempt should pass as it is healthy") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") + oldRId = session.Session.ShardSessions[0].ReservedId + oldAlias = session.Session.ShardSessions[0].TabletAlias + + // Test Setup + tablet0Rep := sbc0Rep.Tablet() + newThs := hc.GetHealthyTabletStats(&querypb.Target{ + Keyspace: tablet0Rep.GetKeyspace(), + Shard: tablet0Rep.GetShard(), + TabletType: tablet0Rep.GetType(), + }) + sbc0RepTh := newThs[0] + sbc0RepTh.Target = &querypb.Target{ + Keyspace: tablet0Rep.GetKeyspace(), + Shard: tablet0Rep.GetShard(), + TabletType: topodatapb.TabletType_SPARE, + } + sbc0Th.Serving = true + + sbc0Rep.Queries = nil + _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) + assert.Equal(t, 1, len(sbc0.Queries), "first attempt should pass as it is healthy and matches the target") + assert.Equal(t, 0, len(sbc0Rep.Queries), " no attempt should be made as the tablet target is changed") + require.Equal(t, 1, len(session.ShardSessions)) + assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") + assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") } func TestIsConnClosed(t *testing.T) { diff --git a/go/vt/vtgate/tabletgateway.go b/go/vt/vtgate/tabletgateway.go index b7ddf31db6b..6e70058d241 100644 --- a/go/vt/vtgate/tabletgateway.go +++ b/go/vt/vtgate/tabletgateway.go @@ -134,8 +134,8 @@ func NewTabletGateway(ctx context.Context, hc discovery.HealthCheck, serv srvtop } // QueryServiceByAlias satisfies the Gateway interface -func (gw *TabletGateway) QueryServiceByAlias(alias *topodatapb.TabletAlias) (queryservice.QueryService, error) { - return gw.hc.TabletConnection(alias) +func (gw *TabletGateway) QueryServiceByAlias(alias *topodatapb.TabletAlias, target *querypb.Target) (queryservice.QueryService, error) { + return gw.hc.TabletConnection(alias, target) } // RegisterStats registers the stats to export the lag since the last refresh diff --git a/go/vt/vtgate/tx_conn.go b/go/vt/vtgate/tx_conn.go index 4747dcf2664..b056b8db508 100644 --- a/go/vt/vtgate/tx_conn.go +++ b/go/vt/vtgate/tx_conn.go @@ -87,7 +87,7 @@ func (txc *TxConn) queryService(alias *topodatapb.TabletAlias) (queryservice.Que if qs != nil { return qs, nil } - return txc.gateway.QueryServiceByAlias(alias) + return txc.gateway.QueryServiceByAlias(alias, nil) } func (txc *TxConn) commitShard(ctx context.Context, s *vtgatepb.Session_ShardSession) error { diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 823cb312de1..a352cd3ce56 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -430,7 +430,7 @@ func (sbc *SandboxConn) VStreamResults(ctx context.Context, target *querypb.Targ } // QueryServiceByAlias is part of the Gateway interface. -func (sbc *SandboxConn) QueryServiceByAlias(_ *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (sbc *SandboxConn) QueryServiceByAlias(_ *topodatapb.TabletAlias, _ *querypb.Target) (queryservice.QueryService, error) { return sbc, nil } diff --git a/go/vt/vttablet/tabletconntest/fakequeryservice.go b/go/vt/vttablet/tabletconntest/fakequeryservice.go index 2ef76a239b2..ec5cc103efd 100644 --- a/go/vt/vttablet/tabletconntest/fakequeryservice.go +++ b/go/vt/vttablet/tabletconntest/fakequeryservice.go @@ -720,7 +720,7 @@ func (f *FakeQueryService) VStreamResults(ctx context.Context, target *querypb.T } // QueryServiceByAlias satisfies the Gateway interface -func (f *FakeQueryService) QueryServiceByAlias(_ *topodatapb.TabletAlias) (queryservice.QueryService, error) { +func (f *FakeQueryService) QueryServiceByAlias(_ *topodatapb.TabletAlias, _ *querypb.Target) (queryservice.QueryService, error) { panic("not implemented") } diff --git a/go/vt/vttablet/tabletserver/state_manager.go b/go/vt/vttablet/tabletserver/state_manager.go index 7aef0bbd083..2ba19135a1e 100644 --- a/go/vt/vttablet/tabletserver/state_manager.go +++ b/go/vt/vttablet/tabletserver/state_manager.go @@ -348,36 +348,19 @@ func (sm *stateManager) StartRequest(ctx context.Context, target *querypb.Target if sm.state != StateServing || !sm.replHealthy { // This specific error string needs to be returned for vtgate buffering to work. - return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "operation not allowed in state NOT_SERVING") + return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) } shuttingDown := sm.wantState != StateServing if shuttingDown && !allowOnShutdown { // This specific error string needs to be returned for vtgate buffering to work. - return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, "operation not allowed in state SHUTTING_DOWN") + return vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.ShuttingDown) } - if target != nil { - switch { - case target.Keyspace != sm.target.Keyspace: - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid keyspace %v does not match expected %v", target.Keyspace, sm.target.Keyspace) - case target.Shard != sm.target.Shard: - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "invalid shard %v does not match expected %v", target.Shard, sm.target.Shard) - case target.TabletType != sm.target.TabletType: - for _, otherType := range sm.alsoAllow { - if target.TabletType == otherType { - goto ok - } - } - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: %v, want: %v or %v", target.TabletType, sm.target.TabletType, sm.alsoAllow) - } - } else { - if !tabletenv.IsLocalContext(ctx) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "No target") - } + err = sm.verifyTargetLocked(ctx, target) + if err != nil { + return err } - -ok: sm.requests.Add(1) return nil } @@ -392,6 +375,10 @@ func (sm *stateManager) EndRequest() { func (sm *stateManager) VerifyTarget(ctx context.Context, target *querypb.Target) error { sm.mu.Lock() defer sm.mu.Unlock() + return sm.verifyTargetLocked(ctx, target) +} + +func (sm *stateManager) verifyTargetLocked(ctx context.Context, target *querypb.Target) error { if target != nil { switch { case target.Keyspace != sm.target.Keyspace: @@ -404,7 +391,7 @@ func (sm *stateManager) VerifyTarget(ctx context.Context, target *querypb.Target return nil } } - return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "invalid tablet type: %v, want: %v or %v", target.TabletType, sm.target.TabletType, sm.alsoAllow) + return vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: %v, want: %v or %v", vterrors.WrongTablet, sm.target.TabletType, sm.target.TabletType, sm.alsoAllow) } } else { if !tabletenv.IsLocalContext(ctx) { diff --git a/go/vt/vttablet/tabletserver/state_manager_test.go b/go/vt/vttablet/tabletserver/state_manager_test.go index 4349212ffec..bc1ff4ca52e 100644 --- a/go/vt/vttablet/tabletserver/state_manager_test.go +++ b/go/vt/vttablet/tabletserver/state_manager_test.go @@ -531,9 +531,9 @@ func TestStateManagerValidations(t *testing.T) { target.Shard = "" target.TabletType = topodatapb.TabletType_REPLICA err = sm.StartRequest(ctx, target, false) - assert.Contains(t, err.Error(), "invalid tablet type") + assert.Contains(t, err.Error(), "wrong tablet type") err = sm.VerifyTarget(ctx, target) - assert.Contains(t, err.Error(), "invalid tablet type") + assert.Contains(t, err.Error(), "wrong tablet type") sm.alsoAllow = []topodatapb.TabletType{topodatapb.TabletType_REPLICA} err = sm.StartRequest(ctx, target, false) diff --git a/test/config.json b/test/config.json index 15b0fe79313..7e61da70002 100644 --- a/test/config.json +++ b/test/config.json @@ -515,6 +515,24 @@ "RetryMax": 0, "Tags": [] }, + "vtgate_reserved_conn1": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_reserved_conn2": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, "vtgate_transaction": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/transaction"], From 2266801a4dcb74b8626ec2b0a4b943a67cd94236 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 5 May 2021 11:39:29 +0530 Subject: [PATCH 130/310] fix test config Signed-off-by: Harshit Gangal --- test/config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/config.json b/test/config.json index 7e61da70002..db88399ce1d 100644 --- a/test/config.json +++ b/test/config.json @@ -520,7 +520,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": 17, "RetryMax": 0, "Tags": [] }, @@ -529,7 +529,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": 17, "RetryMax": 0, "Tags": [] }, From 43d5ee6126feb4ecb85e933c3464348e16741ed5 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Wed, 5 May 2021 15:01:39 +0300 Subject: [PATCH 131/310] Post v10.0.1 updates Signed-off-by: Alkin Tezuysal --- examples/operator/101_initial_cluster.yaml | 10 +++++----- examples/operator/201_customer_tablets.yaml | 10 +++++----- examples/operator/302_new_shards.yaml | 10 +++++----- examples/operator/306_down_shard_0.yaml | 10 +++++----- examples/operator/operator.yaml | 2 +- examples/operator/vtorc_example.yaml | 12 ++++++------ 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/examples/operator/101_initial_cluster.yaml b/examples/operator/101_initial_cluster.yaml index 8df5c19c8e1..93bae05a60b 100644 --- a/examples/operator/101_initial_cluster.yaml +++ b/examples/operator/101_initial_cluster.yaml @@ -8,12 +8,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v10.0.1 + vtgate: vitess/lite:v10.0.1 + vttablet: vitess/lite:v10.0.1 + vtbackup: vitess/lite:v10.0.1 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v10.0.1 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/201_customer_tablets.yaml b/examples/operator/201_customer_tablets.yaml index 44938131139..0e9d8f0d893 100644 --- a/examples/operator/201_customer_tablets.yaml +++ b/examples/operator/201_customer_tablets.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v10.0.1 + vtgate: vitess/lite:v10.0.1 + vttablet: vitess/lite:v10.0.1 + vtbackup: vitess/lite:v10.0.1 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v10.0.1 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/302_new_shards.yaml b/examples/operator/302_new_shards.yaml index 2ea942bfdb4..c600aa2edc7 100644 --- a/examples/operator/302_new_shards.yaml +++ b/examples/operator/302_new_shards.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v10.0.1 + vtgate: vitess/lite:v10.0.1 + vttablet: vitess/lite:v10.0.1 + vtbackup: vitess/lite:v10.0.1 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v10.0.1 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/306_down_shard_0.yaml b/examples/operator/306_down_shard_0.yaml index bcf56db7699..c4d4b1c4dbe 100644 --- a/examples/operator/306_down_shard_0.yaml +++ b/examples/operator/306_down_shard_0.yaml @@ -4,12 +4,12 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v10.0.1 + vtgate: vitess/lite:v10.0.1 + vttablet: vitess/lite:v10.0.1 + vtbackup: vitess/lite:v10.0.1 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v10.0.1 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 diff --git a/examples/operator/operator.yaml b/examples/operator/operator.yaml index 0549856ee01..9bbadc8221e 100644 --- a/examples/operator/operator.yaml +++ b/examples/operator/operator.yaml @@ -5773,7 +5773,7 @@ spec: fieldPath: metadata.name - name: OPERATOR_NAME value: vitess-operator - image: planetscale/vitess-operator:latest + image: planetscale/vitess-operator:v2.4.1 imagePullPolicy: IfNotPresent name: vitess-operator resources: diff --git a/examples/operator/vtorc_example.yaml b/examples/operator/vtorc_example.yaml index ccaa74bc295..ac62a7a296d 100644 --- a/examples/operator/vtorc_example.yaml +++ b/examples/operator/vtorc_example.yaml @@ -8,13 +8,13 @@ metadata: name: example spec: images: - vtctld: vitess/lite:latest - vtorc: vitess/lite:latest - vtgate: vitess/lite:latest - vttablet: vitess/lite:latest - vtbackup: vitess/lite:latest + vtctld: vitess/lite:v10.0.1 + vtorc: vitess/lite:v10.0.1 + vtgate: vitess/lite:v10.0.1 + vttablet: vitess/lite:v10.0.1 + vtbackup: vitess/lite:v10.0.1 mysqld: - mysql56Compatible: vitess/lite:latest + mysql56Compatible: vitess/lite:v10.0.1 mysqldExporter: prom/mysqld-exporter:v0.11.0 cells: - name: zone1 From 684b9f0ea65027001c1ed41fea57c900afb45390 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 11 Feb 2021 18:13:15 +0530 Subject: [PATCH 132/310] added e2e test for query serving even when topo server is down Signed-off-by: Harshit Gangal --- .../endtoend/vtgate/unsharded/main_test.go | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/go/test/endtoend/vtgate/unsharded/main_test.go b/go/test/endtoend/vtgate/unsharded/main_test.go index 4dc3fd70287..013dbe6b60b 100644 --- a/go/test/endtoend/vtgate/unsharded/main_test.go +++ b/go/test/endtoend/vtgate/unsharded/main_test.go @@ -181,6 +181,26 @@ func TestEmptyStatement(t *testing.T) { 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, "consul") + 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() From 017703ed44c855133beee35ce08aec2273cb22f9 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 11 Feb 2021 18:13:47 +0530 Subject: [PATCH 133/310] do not evict cache if unable to connect to topo server Signed-off-by: Harshit Gangal --- go/vt/srvtopo/resilient_server.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/go/vt/srvtopo/resilient_server.go b/go/vt/srvtopo/resilient_server.go index f47f3f9be11..97c2fd1c311 100644 --- a/go/vt/srvtopo/resilient_server.go +++ b/go/vt/srvtopo/resilient_server.go @@ -20,6 +20,7 @@ import ( "flag" "fmt" "html/template" + "net/url" "sort" "sync" "time" @@ -466,7 +467,9 @@ func (server *ResilientServer) watchSrvKeyspace(callerCtx context.Context, entry server.counts.Add(errorCategory, 1) log.Errorf("Initial WatchSrvKeyspace failed for %v/%v: %v", cell, keyspace, current.Err) - if time.Since(entry.lastValueTime) > server.cacheTTL { + // This watcher will able to continue to return the last value till it is not able to connect to the topo server even if the cache TTL is reached. + _, netErr := current.Err.(*url.Error) + if !netErr && time.Since(entry.lastValueTime) > server.cacheTTL { log.Errorf("WatchSrvKeyspace clearing cached entry for %v/%v", cell, keyspace) entry.value = nil } From bf018aa89cb6b19616afb4f82b37f0d809e0ada5 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Mon, 15 Feb 2021 07:06:21 +0100 Subject: [PATCH 134/310] make sure to keep data even when topo server is deleted Signed-off-by: Andres Taylor --- go/test/endtoend/cluster/topo_process.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/endtoend/cluster/topo_process.go b/go/test/endtoend/cluster/topo_process.go index c78d251768f..01c90906482 100644 --- a/go/test/endtoend/cluster/topo_process.go +++ b/go/test/endtoend/cluster/topo_process.go @@ -230,7 +230,7 @@ func (topo *TopoProcess) TearDown(Cell string, originalVtRoot string, currentRoo // Attempt graceful shutdown with SIGTERM first _ = topo.proc.Process.Signal(syscall.SIGTERM) - if !*keepData { + if !(*keepData || keepdata) { _ = os.RemoveAll(topo.DataDirectory) _ = os.RemoveAll(currentRoot) } From 25d02dd171039198dc19376c325626f36cadae26 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 15 Feb 2021 13:16:45 +0530 Subject: [PATCH 135/310] added toposerver down testing for zk, consul and etcd Signed-off-by: Harshit Gangal --- go/test/endtoend/cluster/cluster_process.go | 13 +- go/test/endtoend/topotest/consul/main_test.go | 148 ++++++++++++++++++ go/test/endtoend/topotest/etcd2/main_test.go | 147 +++++++++++++++++ go/test/endtoend/topotest/zk2/main_test.go | 148 ++++++++++++++++++ .../endtoend/vtgate/unsharded/main_test.go | 2 +- 5 files changed, 454 insertions(+), 4 deletions(-) create mode 100644 go/test/endtoend/topotest/consul/main_test.go create mode 100644 go/test/endtoend/topotest/etcd2/main_test.go create mode 100644 go/test/endtoend/topotest/zk2/main_test.go diff --git a/go/test/endtoend/cluster/cluster_process.go b/go/test/endtoend/cluster/cluster_process.go index 879b2ef8a0e..c92de019d90 100644 --- a/go/test/endtoend/cluster/cluster_process.go +++ b/go/test/endtoend/cluster/cluster_process.go @@ -56,6 +56,7 @@ type LocalProcessCluster struct { Cell string BaseTabletUID int Hostname string + TopoFlavor string TopoPort int TmpDirectory string OriginalVTDATAROOT string @@ -173,6 +174,8 @@ func (cluster *LocalProcessCluster) StartTopo() (err error) { if cluster.Cell == "" { cluster.Cell = DefaultCell } + + topoFlavor = cluster.TopoFlavorString() cluster.TopoPort = cluster.GetAndReservePort() cluster.TmpDirectory = path.Join(os.Getenv("VTDATAROOT"), fmt.Sprintf("/tmp_%d", cluster.GetAndReservePort())) cluster.TopoProcess = *TopoProcessInstance(cluster.TopoPort, cluster.GetAndReservePort(), cluster.Hostname, *topoFlavor, "global") @@ -758,9 +761,13 @@ func (cluster *LocalProcessCluster) StartVttablet(tablet *Vttablet, servingStatu return tablet.VttabletProcess.Setup() } -//func (cluster *LocalProcessCluster) NewOrcInstance() OrchestratorProcess { -// -//} +// TopoFlavorString returns the topo flavor +func (cluster *LocalProcessCluster) TopoFlavorString() *string { + if cluster.TopoFlavor != "" { + return &cluster.TopoFlavor + } + return topoFlavor +} func getCoveragePath(fileName string) string { covDir := os.Getenv("COV_DIR") diff --git a/go/test/endtoend/topotest/consul/main_test.go b/go/test/endtoend/topotest/consul/main_test.go new file mode 100644 index 00000000000..f805c7c00b0 --- /dev/null +++ b/go/test/endtoend/topotest/consul/main_test.go @@ -0,0 +1,148 @@ +/* +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 consul + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "vitess.io/vitess/go/vt/log" + + "github.com/google/go-cmp/cmp" + "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;` + VSchema = ` +{ + "sharded": false, + "tables": { + "t1": {} + } +} +` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitCode := func() int { + clusterInstance = cluster.NewCluster(cell, hostname) + defer clusterInstance.Teardown() + + // Start topo server + clusterInstance.TopoFlavor = "consul" + 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 + } + + return m.Run() + }() + os.Exit(exitCode) +} + +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 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 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/test/endtoend/topotest/etcd2/main_test.go b/go/test/endtoend/topotest/etcd2/main_test.go new file mode 100644 index 00000000000..67ffb32ee6e --- /dev/null +++ b/go/test/endtoend/topotest/etcd2/main_test.go @@ -0,0 +1,147 @@ +/* +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 ectd2 + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "vitess.io/vitess/go/vt/log" + + "github.com/google/go-cmp/cmp" + "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;` + VSchema = ` +{ + "sharded": false, + "tables": { + "t1": {} + } +} +` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + 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 + } + + return m.Run() + }() + os.Exit(exitCode) +} + +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 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 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/test/endtoend/topotest/zk2/main_test.go b/go/test/endtoend/topotest/zk2/main_test.go new file mode 100644 index 00000000000..611bee7d180 --- /dev/null +++ b/go/test/endtoend/topotest/zk2/main_test.go @@ -0,0 +1,148 @@ +/* +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 zk2 + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "vitess.io/vitess/go/vt/log" + + "github.com/google/go-cmp/cmp" + "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;` + VSchema = ` +{ + "sharded": false, + "tables": { + "t1": {} + } +} +` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitCode := func() int { + clusterInstance = cluster.NewCluster(cell, hostname) + defer clusterInstance.Teardown() + + // Start topo server + clusterInstance.TopoFlavor = "zk2" + 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 + } + + return m.Run() + }() + os.Exit(exitCode) +} + +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 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 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/test/endtoend/vtgate/unsharded/main_test.go b/go/test/endtoend/vtgate/unsharded/main_test.go index 013dbe6b60b..09089e00e05 100644 --- a/go/test/endtoend/vtgate/unsharded/main_test.go +++ b/go/test/endtoend/vtgate/unsharded/main_test.go @@ -196,7 +196,7 @@ func TestTopoDownServingQuery(t *testing.T) { 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, "consul") + 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)]]`) } From bff68910aa17348ffd81c211a89f87814e30fcc1 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 15 Feb 2021 13:18:14 +0530 Subject: [PATCH 136/310] added to ci tests Signed-off-by: Harshit Gangal --- test/config.json | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/config.json b/test/config.json index db88399ce1d..8f84e89021e 100644 --- a/test/config.json +++ b/test/config.json @@ -569,6 +569,33 @@ "RetryMax": 0, "Tags": [] }, + "topo_zk2": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "topo_consul": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "topo_etcd2": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/etcd2"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, "web_test": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtctldweb"], From d32e22b2dfe7625439aef879b52db30e77abee43 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 15 Feb 2021 16:02:30 +0530 Subject: [PATCH 137/310] fixed e2e test config for zk and consul Signed-off-by: Harshit Gangal --- test.go | 2 +- test/config.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test.go b/test.go index bf355e39a72..1e324a97d92 100755 --- a/test.go +++ b/test.go @@ -69,7 +69,7 @@ To pass extra args to Python tests (test/*.py), terminate the list of test names with -- and then add them at the end. For example: - go run test.go test1 test2 -- --topo-server-flavor=etcd2 + go run test.go test1 test2 -- --topo-flavor=etcd2 ` // Flags diff --git a/test/config.json b/test/config.json index 8f84e89021e..50757077a04 100644 --- a/test/config.json +++ b/test/config.json @@ -571,7 +571,7 @@ }, "topo_zk2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2"], + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "-topo-flavor", "zk2"], "Command": [], "Manual": false, "Shard": "17", @@ -580,7 +580,7 @@ }, "topo_consul": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul"], + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul", "-topo-flavor", "consul"], "Command": [], "Manual": false, "Shard": "17", From f7ce46dbb4ca31cd53f8d33fd6e3b71ad595e88f Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 16 Feb 2021 19:24:53 +0530 Subject: [PATCH 138/310] test in right shard Signed-off-by: Harshit Gangal --- test/config.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/config.json b/test/config.json index 50757077a04..98ab90c34f4 100644 --- a/test/config.json +++ b/test/config.json @@ -571,19 +571,19 @@ }, "topo_zk2": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "-topo-flavor", "zk2"], + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "--topo-flavor=zk2"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "25", "RetryMax": 0, "Tags": [] }, "topo_consul": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul", "-topo-flavor", "consul"], + "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul", "--topo-flavor=consul"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "18", "RetryMax": 0, "Tags": [] }, From d088c608f14033d89a7ce71708ab68b68b6da96a Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 5 May 2021 18:27:41 +0530 Subject: [PATCH 139/310] fix test config Signed-off-by: Harshit Gangal --- test/config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/config.json b/test/config.json index 98ab90c34f4..95fba07112b 100644 --- a/test/config.json +++ b/test/config.json @@ -574,7 +574,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "--topo-flavor=zk2"], "Command": [], "Manual": false, - "Shard": "25", + "Shard": 25, "RetryMax": 0, "Tags": [] }, @@ -583,7 +583,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/topotest/consul", "--topo-flavor=consul"], "Command": [], "Manual": false, - "Shard": "18", + "Shard": 18, "RetryMax": 0, "Tags": [] }, @@ -592,7 +592,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/topotest/etcd2"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": 17, "RetryMax": 0, "Tags": [] }, From 3529118bf8efb03ec9ac3f6b892d39a4f9f4ba78 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Wed, 17 Feb 2021 10:51:24 +0100 Subject: [PATCH 140/310] Rebuild SrvVSchema after deleting routing rules on MoveTables completion/cancellation This is a combination of 4 commits. This is the commit message #2: Check that routing rules are deleted in unit test This is the commit message #3: Fix typo This is the commit message #4: Refresh all tablets in a shard when updating blacklisted tables Signed-off-by: Rohit Nayak Signed-off-by: Andres Taylor --- go/vt/wrangler/traffic_switcher.go | 13 ++++++++++--- go/vt/wrangler/traffic_switcher_test.go | 20 +++++++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/go/vt/wrangler/traffic_switcher.go b/go/vt/wrangler/traffic_switcher.go index d380fd78835..6e2960a17bd 100644 --- a/go/vt/wrangler/traffic_switcher.go +++ b/go/vt/wrangler/traffic_switcher.go @@ -676,6 +676,9 @@ func (wr *Wrangler) DropTargets(ctx context.Context, targetKeyspace, workflow st if err := wr.dropArtifacts(ctx, sw); err != nil { return nil, err } + if err := ts.wr.ts.RebuildSrvVSchema(ctx, nil); err != nil { + return nil, err + } return sw.logs(), nil } @@ -750,6 +753,10 @@ func (wr *Wrangler) DropSources(ctx context.Context, targetKeyspace, workflow st if err := wr.dropArtifacts(ctx, sw); err != nil { return nil, err } + if err := ts.wr.ts.RebuildSrvVSchema(ctx, nil); err != nil { + return nil, err + } + return sw.logs(), nil } @@ -1102,7 +1109,7 @@ func (ts *trafficSwitcher) changeTableSourceWrites(ctx context.Context, access a }); err != nil { return err } - return ts.wr.tmc.RefreshState(ctx, source.master.Tablet) + return ts.wr.RefreshTabletsByShard(ctx, source.si, nil, nil) }) } @@ -1337,7 +1344,7 @@ func (ts *trafficSwitcher) allowTableTargetWrites(ctx context.Context) error { }); err != nil { return err } - return ts.wr.tmc.RefreshState(ctx, target.master.Tablet) + return ts.wr.RefreshTabletsByShard(ctx, target.si, nil, nil) }) } @@ -1481,7 +1488,7 @@ func (ts *trafficSwitcher) dropSourceBlacklistedTables(ctx context.Context) erro }); err != nil { return err } - return ts.wr.tmc.RefreshState(ctx, source.master.Tablet) + return ts.wr.RefreshTabletsByShard(ctx, source.si, nil, nil) }) } diff --git a/go/vt/wrangler/traffic_switcher_test.go b/go/vt/wrangler/traffic_switcher_test.go index 092ce43fd18..8a8658c2dfa 100644 --- a/go/vt/wrangler/traffic_switcher_test.go +++ b/go/vt/wrangler/traffic_switcher_test.go @@ -915,10 +915,28 @@ func TestTableMigrateOneToMany(t *testing.T) { } dropSources() + checkRouting(t, tme.wr, map[string][]string{ + "t1": {"ks2.t1"}, + "ks1.t1": {"ks2.t1"}, + "t2": {"ks2.t2"}, + "ks1.t2": {"ks2.t2"}, + "t1@replica": {"ks2.t1"}, + "ks2.t1@replica": {"ks2.t1"}, + "ks1.t1@replica": {"ks2.t1"}, + "t2@replica": {"ks2.t2"}, + "ks2.t2@replica": {"ks2.t2"}, + "ks1.t2@replica": {"ks2.t2"}, + "t1@rdonly": {"ks2.t1"}, + "ks2.t1@rdonly": {"ks2.t1"}, + "ks1.t1@rdonly": {"ks2.t1"}, + "t2@rdonly": {"ks2.t2"}, + "ks2.t2@rdonly": {"ks2.t2"}, + "ks1.t2@rdonly": {"ks2.t2"}, + }) _, err = tme.wr.DropSources(ctx, tme.targetKeyspace, "test", RenameTable, false, false, false) require.NoError(t, err) checkBlacklist(t, tme.ts, fmt.Sprintf("%s:%s", "ks1", "0"), nil) - + checkRouting(t, tme.wr, map[string][]string{}) verifyQueries(t, tme.allDBClients) } From af9eadb3257a9a035211cedc102747364124eaa6 Mon Sep 17 00:00:00 2001 From: Dylan Visher Date: Mon, 3 May 2021 07:02:38 -0700 Subject: [PATCH 141/310] vreplication: fix vreplication timing metrics Several of the vreplication metrics were recently updated to no longer be correct. Specifically time.Now() is no longer executed when the function starts and is instead executed when the defer statement is called after the end of the function. This updates the metrics to properly execute time.Now() at the start of the functions. Signed-off-by: Dylan Visher --- .../vttablet/tabletmanager/vreplication/vcopier.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index 43272b83cb2..352f941c8e8 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -140,9 +140,7 @@ func (vc *vcopier) copyNext(ctx context.Context, settings binlogplayer.VRSetting func (vc *vcopier) catchup(ctx context.Context, copyState map[string]*sqltypes.Result) error { ctx, cancel := context.WithCancel(ctx) defer cancel() - defer func() { - vc.vr.stats.PhaseTimings.Record("catchup", time.Now()) - }() + defer vc.vr.stats.PhaseTimings.Record("catchup", time.Now()) settings, err := binlogplayer.ReadVRSettings(vc.vr.dbClient, vc.vr.id) if err != nil { @@ -192,10 +190,8 @@ func (vc *vcopier) catchup(ctx context.Context, copyState map[string]*sqltypes.R // committed with the lastpk. This allows for consistent resumability. func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState map[string]*sqltypes.Result) error { defer vc.vr.dbClient.Rollback() - defer func() { - vc.vr.stats.PhaseTimings.Record("copy", time.Now()) - vc.vr.stats.CopyLoopCount.Add(1) - }() + defer vc.vr.stats.PhaseTimings.Record("copy", time.Now()) + defer vc.vr.stats.CopyLoopCount.Add(1) log.Infof("Copying table %s, lastpk: %v", tableName, copyState[tableName]) @@ -321,9 +317,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma } func (vc *vcopier) fastForward(ctx context.Context, copyState map[string]*sqltypes.Result, gtid string) error { - defer func() { - vc.vr.stats.PhaseTimings.Record("fastforward", time.Now()) - }() + defer vc.vr.stats.PhaseTimings.Record("fastforward", time.Now()) pos, err := mysql.DecodePosition(gtid) if err != nil { return err From 5043c0f562b5261df46b5c73ad6b012975982026 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 27 Apr 2021 19:42:30 +0200 Subject: [PATCH 142/310] VReplication: Pad binlog values for binary() columns to match the value returned by mysql selects Backport of #7969 * Pad binlog values for binary() columns to match the value returned by a select query. This also ensures that if such columns are used as sharding keys we get the same keyspace_id * Pad binary() values in the binlog reader directly so that all consumers see the padded value instead of doing it later in vstreamer or doint it just for keyspace id computation Signed-off-by: Rohit Nayak Signed-off-by: Andres Taylor --- go/mysql/binlog_event_rbr.go | 12 ++++++++++ go/test/endtoend/vreplication/config.go | 22 ++++++++++++++----- go/test/endtoend/vreplication/helper.go | 3 +++ .../vreplication/unsharded_init_data.sql | 4 ++++ .../vreplication/vreplication_test.go | 6 ++++- .../vreplication/vreplication_test_env.go | 16 ++++++++------ .../vreplication/framework_test.go | 5 ++++- .../vreplication/table_plan_builder.go | 14 ++---------- .../vreplication/vcopier_test.go | 2 +- .../vreplication/vplayer_flaky_test.go | 18 +++++++-------- .../tabletserver/vstreamer/planbuilder.go | 6 ++--- .../tabletserver/vstreamer/vstreamer.go | 1 + .../tabletserver/vstreamer/vstreamer_test.go | 22 +++++++++---------- 13 files changed, 81 insertions(+), 50 deletions(-) diff --git a/go/mysql/binlog_event_rbr.go b/go/mysql/binlog_event_rbr.go index 7c2341a322a..906ccba5c39 100644 --- a/go/mysql/binlog_event_rbr.go +++ b/go/mysql/binlog_event_rbr.go @@ -895,6 +895,18 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, styp querypb.Typ l := int(data[pos]) mdata := data[pos+1 : pos+1+l] if sqltypes.IsBinary(styp) { + // For binary(n) column types, mysql pads the data on the right with nulls. However the binlog event contains + // the data without this padding. This causes several issues: + // * if a binary(n) column is part of the sharding key, the keyspace_id() returned during the copy phase + // (where the value is the result of a mysql query) is different from the one during replication + // (where the value is the one from the binlogs) + // * mysql where clause comparisons do not do the right thing without padding + // So for fixed length binary() columns we right-pad it with nulls if necessary + if l < max { + paddedData := make([]byte, max) + copy(paddedData[:l], mdata) + mdata = paddedData + } return sqltypes.MakeTrusted(querypb.Type_BINARY, mdata), l + 1, nil } return sqltypes.MakeTrusted(querypb.Type_VARCHAR, mdata), l + 1, nil diff --git a/go/test/endtoend/vreplication/config.go b/go/test/endtoend/vreplication/config.go index d937b7a4948..fc8a08e0958 100644 --- a/go/test/endtoend/vreplication/config.go +++ b/go/test/endtoend/vreplication/config.go @@ -10,6 +10,7 @@ create table orders(oid int, cid int, pid int, mname varchar(128), price int, pr create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; create table customer2(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), sport set('football','cricket','baseball'),ts timestamp not null default current_timestamp, primary key(cid)); create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; +create table tenant(tenant_id binary(16), name varbinary(16), primary key (tenant_id)); ` initialProductVSchema = ` @@ -28,7 +29,8 @@ create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id) }, "order_seq": { "type": "sequence" - } + }, + "tenant": {} } } ` @@ -39,9 +41,12 @@ create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id) "vindexes": { "reverse_bits": { "type": "reverse_bits" - } + }, + "binary_md5": { + "type": "binary_md5" + } }, - "tables": { + "tables": { "customer": { "column_vindexes": [ { @@ -65,9 +70,16 @@ create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id) "column": "cid", "sequence": "customer_seq2" } - } + }, + "tenant": { + "column_vindexes": [ + { + "column": "tenant_id", + "name": "binary_md5" + } + ] + } } - } ` merchantVSchema = ` diff --git a/go/test/endtoend/vreplication/helper.go b/go/test/endtoend/vreplication/helper.go index c2d69d1afea..6c9a8bdbb13 100644 --- a/go/test/endtoend/vreplication/helper.go +++ b/go/test/endtoend/vreplication/helper.go @@ -24,6 +24,9 @@ import ( func execMultipleQueries(t *testing.T, conn *mysql.Conn, database string, lines string) { queries := strings.Split(lines, "\n") for _, query := range queries { + if strings.HasPrefix(query, "--") { + continue + } execVtgateQuery(t, conn, database, string(query)) } } diff --git a/go/test/endtoend/vreplication/unsharded_init_data.sql b/go/test/endtoend/vreplication/unsharded_init_data.sql index f8e0cc5d86f..06eb2e18628 100644 --- a/go/test/endtoend/vreplication/unsharded_init_data.sql +++ b/go/test/endtoend/vreplication/unsharded_init_data.sql @@ -11,3 +11,7 @@ insert into orders(oid, cid, mname, pid, price) values(3, 2, 'monoprice', 2, 20) insert into customer2(cid, name, typ, sport) values(1, 'john',1,'football,baseball'); insert into customer2(cid, name, typ, sport) values(2, 'paul','soho','cricket'); insert into customer2(cid, name, typ, sport) values(3, 'ringo','enterprise',''); +-- for testing edge case where inserted binary value is 15 bytes, field is 16, mysql adds a null while storing but binlog returns 15 bytes +insert into tenant(tenant_id, name) values (x'02BD00987932461E8820C908E84BAE', 'abc'); + + diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index dde5228f238..c4ea174354a 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -72,6 +72,9 @@ func TestBasicVreplicationWorkflow(t *testing.T) { materializeRollup(t) shardCustomer(t, true, []*Cell{defaultCell}, defaultCellName) + // the tenant table was to test a specific case with binary sharding keys. Drop it now so that we don't + // have to update the rest of the tests + execVtgateQuery(t, vtgateConn, "customer", "drop table tenant") validateRollupReplicates(t) shardOrders(t) shardMerchant(t) @@ -198,7 +201,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl if err := vtgate.WaitForStatusOfTabletInShard(fmt.Sprintf("%s.%s.master", "customer", "80-"), 1); err != nil { t.Fatal(err) } - tables := "customer" + tables := "customer,tenant" moveTables(t, sourceCellOrAlias, workflow, sourceKs, targetKs, tables) // Assume we are operating on first cell @@ -216,6 +219,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl insertQuery1 := "insert into customer(cid, name) values(1001, 'tempCustomer1')" matchInsertQuery1 := "insert into customer(cid, `name`) values (:vtg1, :vtg2)" require.True(t, validateThatQueryExecutesOnTablet(t, vtgateConn, productTab, "product", insertQuery1, matchInsertQuery1)) + execVtgateQuery(t, vtgateConn, "product", "update tenant set name='xyz'") vdiff(t, ksWorkflow) switchReadsDryRun(t, allCellNames, ksWorkflow, dryRunResultsReadCustomerShard) switchReads(t, allCellNames, ksWorkflow) diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index e618432a7ef..4c53f5104b8 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -19,14 +19,14 @@ package vreplication var dryRunResultsSwitchWritesCustomerShard = []string{ "Lock keyspace product", "Lock keyspace customer", - "Stop writes on keyspace product, tables [customer]:", + "Stop writes on keyspace product, tables [customer,tenant]:", "/ Keyspace product, Shard 0 at Position", "Wait for VReplication on stopped streams to catchup for upto 30s", "Create reverse replication workflow p2c_reverse", "Create journal entries on source databases", - "Enable writes on keyspace customer tables [customer]", + "Enable writes on keyspace customer tables [customer,tenant]", "Switch routing from keyspace product to keyspace customer", - "Routing rules for tables [customer] will be updated", + "Routing rules for tables [customer,tenant] will be updated", "SwitchWrites completed, freeze and delete vreplication streams on:", " tablet 200 ", " tablet 300 ", @@ -41,8 +41,8 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ var dryRunResultsReadCustomerShard = []string{ "Lock keyspace product", - "Switch reads for tables [customer] to keyspace customer for tablet types [REPLICA,RDONLY]", - "Routing rules for tables [customer] will be updated", + "Switch reads for tables [customer,tenant] to keyspace customer for tablet types [REPLICA,RDONLY]", + "Routing rules for tables [customer,tenant] will be updated", "Unlock keyspace product", } @@ -91,7 +91,8 @@ var dryRunResultsDropSourcesDropCustomerShard = []string{ "Lock keyspace customer", "Dropping these tables from the database and removing them from the vschema for keyspace product:", " Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer", - "Blacklisted tables [customer] will be removed from:", + " Keyspace product Shard 0 DbName vt_product Tablet 100 Table tenant", + "Blacklisted tables [customer,tenant] will be removed from:", " Keyspace product Shard 0 Tablet 100", "Delete reverse vreplication streams on source:", " Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100", @@ -108,7 +109,8 @@ var dryRunResultsDropSourcesRenameCustomerShard = []string{ "Lock keyspace customer", "Renaming these tables from the database and removing them from the vschema for keyspace product:", " Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer", - "Blacklisted tables [customer] will be removed from:", + " Keyspace product Shard 0 DbName vt_product Tablet 100 Table tenant", + "Blacklisted tables [customer,tenant] will be removed from:", " Keyspace product Shard 0 Tablet 100", "Delete reverse vreplication streams on source:", " Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100", diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index d66f3a4c13d..ed3260c57ff 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -121,12 +121,15 @@ func TestMain(m *testing.M) { playerEngine = NewTestEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory, vrepldb, externalConfig) playerEngine.Open(context.Background()) defer playerEngine.Close() - if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), binlogplayer.CreateVReplicationTable()); err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 } + for _, query := range binlogplayer.AlterVReplicationTable { + env.Mysqld.ExecuteSuperQuery(context.Background(), query) + } + if err := env.Mysqld.ExecuteSuperQuery(context.Background(), createCopyState); err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index d02c372469a..98c30acde97 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -674,16 +674,6 @@ func (tpb *tablePlanBuilder) generateDeleteStatement() *sqlparser.ParsedQuery { return buf.ParsedQuery() } -// For binary(n) column types, the value in the where clause needs to be padded with nulls upto the length of the column -// for MySQL comparison to work properly. This is achieved by casting it to the column type -func castIfNecessary(buf *sqlparser.TrackedBuffer, cexpr *colExpr) { - if cexpr.dataType == "binary" { - buf.Myprintf("cast(%v as %s)", cexpr.expr, cexpr.columnType) - return - } - buf.Myprintf("%v", cexpr.expr) -} - func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bindvarFormatter) { buf.WriteString(" where ") bvf.mode = bvBefore @@ -691,11 +681,11 @@ func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bi for _, cexpr := range tpb.pkCols { if _, ok := cexpr.expr.(*sqlparser.ColName); ok { buf.Myprintf("%s%v=", separator, cexpr.colName) - castIfNecessary(buf, cexpr) + buf.Myprintf("%v", cexpr.expr) } else { // Parenthesize non-trivial expressions. buf.Myprintf("%s%v=(", separator, cexpr.colName) - castIfNecessary(buf, cexpr) + buf.Myprintf("%v", cexpr.expr) buf.Myprintf(")") } separator = " and " diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index 1ebdcad540a..6d372b83540 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -121,7 +121,7 @@ func TestPlayerCopyCharPK(t *testing.T) { "/update _vt.vreplication set state='Copying'", "insert into dst(idc,val) values ('a\\0',1)", `/update _vt.copy_state set lastpk='fields: rows: ' where vrepl_id=.*`, - `update dst set val=3 where idc=cast('a' as binary(2)) and ('a') <= ('a\0')`, + `update dst set val=3 where idc='a\0' and ('a\0') <= ('a\0')`, "insert into dst(idc,val) values ('c\\0',2)", `/update _vt.copy_state set lastpk='fields: rows: ' where vrepl_id=.*`, "/delete from _vt.copy_state.*dst", diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index adf55a3f80f..374e2acbe0c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -148,14 +148,14 @@ func TestCharPK(t *testing.T) { data [][]string }{{ //binary(2) input: "insert into t1 values(1, 'a')", - output: "insert into t1(id,val) values (1,'a')", + output: "insert into t1(id,val) values (1,'a\\0')", table: "t1", data: [][]string{ {"1", "a\000"}, }, }, { input: "update t1 set id = 2 where val = 'a\000'", - output: "update t1 set id=2 where val=cast('a' as binary(2))", + output: "update t1 set id=2 where val='a\\0'", table: "t1", data: [][]string{ {"2", "a\000"}, @@ -1278,8 +1278,8 @@ func TestPlayerTypes(t *testing.T) { fmt.Sprintf("create table %s.vitess_ints(tiny tinyint, tinyu tinyint unsigned, small smallint, smallu smallint unsigned, medium mediumint, mediumu mediumint unsigned, normal int, normalu int unsigned, big bigint, bigu bigint unsigned, y year, primary key(tiny))", vrepldb), "create table vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", fmt.Sprintf("create table %s.vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", vrepldb), - "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", - fmt.Sprintf("create table %s.vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", vrepldb), + "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(5), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", + fmt.Sprintf("create table %s.vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(5), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", vrepldb), "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", fmt.Sprintf("create table %s.vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", vrepldb), "create table vitess_null(id int, val varbinary(128), primary key(id))", @@ -1351,10 +1351,10 @@ func TestPlayerTypes(t *testing.T) { }, }, { input: "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", - output: "insert into vitess_strings(vb,c,vc,b,tb,bl,ttx,tx,en,s) values ('a','b','c','d','e','f','g','h','1','3')", + output: "insert into vitess_strings(vb,c,vc,b,tb,bl,ttx,tx,en,s) values ('a','b','c','d\\0\\0\\0\\0','e','f','g','h','1','3')", table: "vitess_strings", data: [][]string{ - {"a", "b", "c", "d\000\000\000", "e", "f", "g", "h", "a", "a,b"}, + {"a", "b", "c", "d\000\000\000\000", "e", "f", "g", "h", "a", "a,b"}, }, }, { input: "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", @@ -1372,7 +1372,7 @@ func TestPlayerTypes(t *testing.T) { }, }, { input: "insert into binary_pk values('a', 'aaa')", - output: "insert into binary_pk(b,val) values ('a','aaa')", + output: "insert into binary_pk(b,val) values ('a\\0\\0\\0','aaa')", table: "binary_pk", data: [][]string{ {"a\000\000\000", "aaa"}, @@ -1380,10 +1380,10 @@ func TestPlayerTypes(t *testing.T) { }, { // Binary pk is a special case: https://github.com/vitessio/vitess/issues/3984 input: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", - output: "update binary_pk set val='bbb' where b=cast('a' as binary(4))", + output: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", table: "binary_pk", data: [][]string{ - {"a\x00\x00\x00", "bbb"}, + {"a\000\000\000", "bbb"}, }, }} diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 3454183b069..35ce57eb6f3 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -122,7 +122,7 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error return false, nil, nil } case VindexMatch: - ksid, err := getKeyspaceID(values, filter.Vindex, filter.VindexColumns) + ksid, err := getKeyspaceID(values, filter.Vindex, filter.VindexColumns, plan.Table.Fields) if err != nil { return false, nil, err } @@ -144,7 +144,7 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error if colExpr.Vindex == nil { result[i] = values[colExpr.ColNum] } else { - ksid, err := getKeyspaceID(values, colExpr.Vindex, colExpr.VindexColumns) + ksid, err := getKeyspaceID(values, colExpr.Vindex, colExpr.VindexColumns, plan.Table.Fields) if err != nil { return false, nil, err } @@ -154,7 +154,7 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error return true, result, nil } -func getKeyspaceID(values []sqltypes.Value, vindex vindexes.Vindex, vindexColumns []int) (key.DestinationKeyspaceID, error) { +func getKeyspaceID(values []sqltypes.Value, vindex vindexes.Vindex, vindexColumns []int, fields []*querypb.Field) (key.DestinationKeyspaceID, error) { vindexValues := make([]sqltypes.Value, 0, len(vindexColumns)) for _, col := range vindexColumns { vindexValues = append(vindexValues, values[col]) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index b9eb23f7ef7..fb0333da33d 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -862,6 +862,7 @@ func (vs *vstreamer) extractRowAndFilter(plan *streamerPlan, data []byte, dataCo return false, nil, err } pos += l + values[colNum] = value valueIndex++ } diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 4851b685b2f..b1e4aa23651 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -110,9 +110,9 @@ func TestSetAndEnum(t *testing.T) { output: [][]string{{ `begin`, fe.String(), - `type:ROW row_event: > > `, - `type:ROW row_event: > > `, - `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, `gtid`, `commit`, }}, @@ -133,8 +133,8 @@ func TestCellValuePadding(t *testing.T) { engine.se.Reload(context.Background()) queries := []string{ "begin", - "insert into t1 values (1, 'aaa')", - "insert into t1 values (2, 'bbb')", + "insert into t1 values (1, 'aaa\000')", + "insert into t1 values (2, 'bbb\000')", "update t1 set id = 11 where val = 'aaa\000'", "insert into t2 values (1, 'aaa')", "insert into t2 values (2, 'bbb')", @@ -147,9 +147,9 @@ func TestCellValuePadding(t *testing.T) { output: [][]string{{ `begin`, `type:FIELD field_event: fields: > `, - `type:ROW row_event: > > `, - `type:ROW row_event: > > `, - `type:ROW row_event: after: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: after: > > `, `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: > > `, @@ -1561,13 +1561,13 @@ func TestTypes(t *testing.T) { }, { // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. input: []string{ - "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", + "insert into vitess_strings values('a', 'b', 'c', 'd\000\000\000', 'e', 'f', 'g', 'h', 'a', 'a,b')", }, output: [][]string{{ `begin`, `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, + `type:ROW row_event: > > `, `gtid`, `commit`, }}, From 3c192cb11b5bd770de0e5bb6056fdb248fe6023d Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 30 Apr 2021 13:15:17 +0530 Subject: [PATCH 143/310] ignore the error and log as warn if not able to validate the current system settings value Signed-off-by: Harshit Gangal --- go/vt/vtgate/engine/set.go | 6 +++++- go/vt/vtgate/engine/set_test.go | 26 ++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/go/vt/vtgate/engine/set.go b/go/vt/vtgate/engine/set.go index 43401cb8a25..dc317e52a23 100644 --- a/go/vt/vtgate/engine/set.go +++ b/go/vt/vtgate/engine/set.go @@ -247,7 +247,11 @@ func (svci *SysVarCheckAndIgnore) Execute(vcursor VCursor, env evalengine.Expres checkSysVarQuery := fmt.Sprintf("select 1 from dual where @@%s = %s", svci.Name, svci.Expr) result, err := execShard(vcursor, checkSysVarQuery, env.BindVars, rss[0], false /* rollbackOnError */, false /* canAutocommit */) if err != nil { - return err + // Rather than returning the error, we will just log the error + // as the intention for executing the query it to validate the current setting and eventually ignore it anyways. + // There is no benefit of returning the error back to client. + log.Warningf("unable to validate the current settings for '%s': %s", svci.Name, err.Error()) + return nil } if result.RowsAffected == 0 { log.Infof("Ignored inapplicable SET %v = %v", svci.Name, svci.Expr) diff --git a/go/vt/vtgate/engine/set_test.go b/go/vt/vtgate/engine/set_test.go index ce2c0bae504..e6a3b0f45ad 100644 --- a/go/vt/vtgate/engine/set_test.go +++ b/go/vt/vtgate/engine/set_test.go @@ -17,6 +17,7 @@ limitations under the License. package engine import ( + "errors" "fmt" "testing" @@ -74,6 +75,7 @@ func TestSetTable(t *testing.T) { expectedWarning []*querypb.QueryWarning expectedError string input Primitive + execErr error } tests := []testCase{ @@ -193,6 +195,25 @@ func TestSetTable(t *testing.T) { }, expectedError: "Unexpected error, DestinationKeyspaceID mapping to multiple shards: DestinationAllShards()", }, + { + testName: "sysvar checkAndIgnore execute error", + setOps: []SetOp{ + &SysVarCheckAndIgnore{ + Name: "x", + Keyspace: &vindexes.Keyspace{ + Name: "ks", + Sharded: true, + }, + TargetDestination: key.DestinationAnyShard{}, + Expr: "dummy_expr", + }, + }, + expectedQueryLog: []string{ + `ResolveDestinations ks [] Destinations:DestinationAnyShard()`, + `ExecuteMultiShard ks.-20: select 1 from dual where @@x = dummy_expr {} false false`, + }, + execErr: errors.New("some random error"), + }, { testName: "udv ignore checkAndIgnore ", setOps: []SetOp{ @@ -299,8 +320,9 @@ func TestSetTable(t *testing.T) { Input: tc.input, } vc := &loggingVCursor{ - shards: []string{"-20", "20-"}, - results: tc.qr, + shards: []string{"-20", "20-"}, + results: tc.qr, + multiShardErrs: []error{tc.execErr}, } _, err := set.Execute(vc, map[string]*querypb.BindVariable{}, false) if tc.expectedError == "" { From 036f4efb8ccd0d52f739237f0c5490022ddc969b Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 26 Feb 2021 16:17:22 -0800 Subject: [PATCH 144/310] restore: do not restart replication if disable_active_reparents is set. Also, Begin and End Maintenance on orchestrator backup: do not restart replication if disable_active_reparents is set. Also, Begin and End Maintenance on orchestrator Signed-off-by: deepthi Signed-off-by: Florent Poinsard --- go/vt/mysqlctl/builtinbackupengine.go | 2 +- go/vt/vttablet/tabletmanager/restore.go | 30 +++- go/vt/vttablet/tabletmanager/rpc_backup.go | 20 +++ go/vt/vttablet/tabletmanager/tm_init.go | 5 +- go/vt/wrangler/testlib/backup_test.go | 151 +++++++++++++++++++++ 5 files changed, 201 insertions(+), 7 deletions(-) diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index b064ad2d677..1e727f5afcf 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -152,7 +152,7 @@ func (be *BuiltinBackupEngine) ExecuteBackup(ctx context.Context, params BackupP replicaStatus, err := params.Mysqld.ReplicationStatus() switch err { case nil: - replicaStartRequired = replicaStatus.ReplicationRunning() + replicaStartRequired = replicaStatus.ReplicationRunning() && !*DisableActiveReparents case mysql.ErrNotReplica: // keep going if we're the master, might be a degenerate case sourceIsMaster = true diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 63408eb62ba..790b41fed65 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -78,7 +78,28 @@ func (tm *TabletManager) RestoreData(ctx context.Context, logger logutil.Logger, if tm.Cnf == nil { return fmt.Errorf("cannot perform restore without my.cnf, please restart vttablet with a my.cnf file specified") } - return tm.restoreDataLocked(ctx, logger, waitForBackupInterval, deleteBeforeRestore) + // Tell Orchestrator we're stopped on purpose for some Vitess task. + // Do this in the background, as it's best-effort. + go func() { + if tm.orc == nil { + return + } + if err := tm.orc.BeginMaintenance(tm.Tablet(), "vttablet has been told to Restore"); err != nil { + log.Warningf("Orchestrator BeginMaintenance failed: %v", err) + } + }() + err := tm.restoreDataLocked(ctx, logger, waitForBackupInterval, deleteBeforeRestore) + // Tell Orchestrator we're no longer stopped on purpose. + // Do this in the background, as it's best-effort. + go func() { + if tm.orc == nil { + return + } + if err := tm.orc.EndMaintenance(tm.Tablet()); err != nil { + log.Warningf("Orchestrator EndMaintenance failed: %v", err) + } + }() + return err } func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.Logger, waitForBackupInterval time.Duration, deleteBeforeRestore bool) error { @@ -470,10 +491,15 @@ func (tm *TabletManager) startReplication(ctx context.Context, pos mysql.Positio } // Set master and start replication. - if err := tm.MysqlDaemon.SetMaster(ctx, ti.Tablet.MysqlHostname, int(ti.Tablet.MysqlPort), false /* stopReplicationBefore */, true /* startReplicationAfter */); err != nil { + if err := tm.MysqlDaemon.SetMaster(ctx, ti.Tablet.MysqlHostname, int(ti.Tablet.MysqlPort), false /* stopReplicationBefore */, !*mysqlctl.DisableActiveReparents /* startReplicationAfter */); err != nil { return vterrors.Wrap(err, "MysqlDaemon.SetMaster failed") } + // If active reparents are disabled, we don't restart replication. So it makes no sense to wait for an update on the replica. + // Return immediately. + if !*mysqlctl.DisableActiveReparents { + return nil + } // wait for reliable seconds behind master // we have pos where we want to resume from // if MasterPosition is the same, that means no writes diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index f4b65834197..683d69b2064 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -88,6 +88,16 @@ func (tm *TabletManager) Backup(ctx context.Context, concurrency int, logger log if err := tm.changeTypeLocked(ctx, topodatapb.TabletType_BACKUP, DBActionNone); err != nil { return err } + // Tell Orchestrator we're stopped on purpose for some Vitess task. + // Do this in the background, as it's best-effort. + go func() { + if tm.orc == nil { + return + } + if err := tm.orc.BeginMaintenance(tm.Tablet(), "vttablet has been told to run an offline backup"); err != nil { + logger.Warningf("Orchestrator BeginMaintenance failed: %v", err) + } + }() } // create the loggers: tee to console and source l := logutil.NewTeeLogger(logutil.NewConsoleLogger(), logger) @@ -124,6 +134,16 @@ func (tm *TabletManager) Backup(ctx context.Context, concurrency int, logger log } returnErr = err } + // Tell Orchestrator we're no longer stopped on purpose. + // Do this in the background, as it's best-effort. + go func() { + if tm.orc == nil { + return + } + if err := tm.orc.EndMaintenance(tm.Tablet()); err != nil { + logger.Warningf("Orchestrator EndMaintenance failed: %v", err) + } + }() } return returnErr diff --git a/go/vt/vttablet/tabletmanager/tm_init.go b/go/vt/vttablet/tabletmanager/tm_init.go index 6c9734b3ffb..e1d7d6757d2 100644 --- a/go/vt/vttablet/tabletmanager/tm_init.go +++ b/go/vt/vttablet/tabletmanager/tm_init.go @@ -597,10 +597,7 @@ func (tm *TabletManager) handleRestore(ctx context.Context) (bool, error) { return false, fmt.Errorf("you cannot enable -restore_from_backup without a my.cnf file") } - // two cases then: - // - restoreFromBackup is set: we restore, then initHealthCheck, all - // in the background - // - restoreFromBackup is not set: we initHealthCheck right away + // Restore in the background if *restoreFromBackup { go func() { // Open the state manager after restore is done. diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index 3d997d92ce0..c33437a4c1d 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -394,3 +394,154 @@ func TestRestoreUnreachableMaster(t *testing.T) { assert.True(t, destTablet.FakeMysqlDaemon.Replicating) assert.True(t, destTablet.FakeMysqlDaemon.Running) } + +func TestDisableActiveReparents(t *testing.T) { + *mysqlctl.DisableActiveReparents = true + delay := discovery.GetTabletPickerRetryDelay() + defer func() { + // When you mess with globals you must remember to reset them + *mysqlctl.DisableActiveReparents = false + discovery.SetTabletPickerRetryDelay(delay) + }() + discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) + + // Initialize our environment + ctx := context.Background() + db := fakesqldb.New(t) + defer db.Close() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + vp := NewVtctlPipe(t, ts) + defer vp.Close() + + // Set up mock query results. + db.AddQuery("CREATE DATABASE IF NOT EXISTS _vt", &sqltypes.Result{}) + db.AddQuery("BEGIN", &sqltypes.Result{}) + db.AddQuery("COMMIT", &sqltypes.Result{}) + db.AddQueryPattern(`SET @@session\.sql_log_bin = .*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.shard_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.local_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`ALTER TABLE _vt\.local_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`ALTER TABLE _vt\.shard_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`UPDATE _vt\.local_metadata SET db_name=.*`, &sqltypes.Result{}) + db.AddQueryPattern(`UPDATE _vt\.shard_metadata SET db_name=.*`, &sqltypes.Result{}) + db.AddQueryPattern(`INSERT INTO _vt\.local_metadata .*`, &sqltypes.Result{}) + + // Initialize our temp dirs + root, err := ioutil.TempDir("", "backuptest") + require.NoError(t, err) + defer os.RemoveAll(root) + + // Initialize BackupStorage + fbsRoot := path.Join(root, "fbs") + *filebackupstorage.FileBackupStorageRoot = fbsRoot + *backupstorage.BackupStorageImplementation = "file" + + // Initialize the fake mysql root directories + sourceInnodbDataDir := path.Join(root, "source_innodb_data") + sourceInnodbLogDir := path.Join(root, "source_innodb_log") + sourceDataDir := path.Join(root, "source_data") + sourceDataDbDir := path.Join(sourceDataDir, "vt_db") + for _, s := range []string{sourceInnodbDataDir, sourceInnodbLogDir, sourceDataDbDir} { + require.NoError(t, os.MkdirAll(s, os.ModePerm)) + } + require.NoError(t, ioutil.WriteFile(path.Join(sourceInnodbDataDir, "innodb_data_1"), []byte("innodb data 1 contents"), os.ModePerm)) + require.NoError(t, ioutil.WriteFile(path.Join(sourceInnodbLogDir, "innodb_log_1"), []byte("innodb log 1 contents"), os.ModePerm)) + require.NoError(t, ioutil.WriteFile(path.Join(sourceDataDbDir, "db.opt"), []byte("db opt file"), os.ModePerm)) + + // create a master tablet, set its master position + master := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, db) + master.FakeMysqlDaemon.ReadOnly = false + master.FakeMysqlDaemon.Replicating = false + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + + // start master so that replica can fetch master position from it + master.StartActionLoop(t, wr) + defer master.StopActionLoop(t) + + // create a single tablet, set it up so we can do backups + // set its position same as that of master so that backup doesn't wait for catchup + sourceTablet := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, db) + sourceTablet.FakeMysqlDaemon.ReadOnly = true + sourceTablet.FakeMysqlDaemon.Replicating = true + sourceTablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + sourceTablet.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + } + sourceTablet.StartActionLoop(t, wr) + defer sourceTablet.StopActionLoop(t) + + sourceTablet.TM.Cnf = &mysqlctl.Mycnf{ + DataDir: sourceDataDir, + InnodbDataHomeDir: sourceInnodbDataDir, + InnodbLogGroupHomeDir: sourceInnodbLogDir, + } + + // run the backup + require.NoError(t, vp.Run([]string{"Backup", topoproto.TabletAliasString(sourceTablet.Tablet.Alias)})) + + // verify the full status + require.NoError(t, sourceTablet.FakeMysqlDaemon.CheckSuperQueryList()) + assert.False(t, sourceTablet.FakeMysqlDaemon.Replicating) + assert.True(t, sourceTablet.FakeMysqlDaemon.Running) + + // create a destination tablet, set it up so we can do restores + destTablet := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, db) + destTablet.FakeMysqlDaemon.ReadOnly = true + destTablet.FakeMysqlDaemon.Replicating = true + destTablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + destTablet.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "RESET SLAVE ALL", + "FAKE SET SLAVE POSITION", + "FAKE SET MASTER", + } + destTablet.FakeMysqlDaemon.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SHOW DATABASES": {}, + } + destTablet.FakeMysqlDaemon.SetReplicationPositionPos = sourceTablet.FakeMysqlDaemon.CurrentMasterPosition + destTablet.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(master.Tablet) + + destTablet.StartActionLoop(t, wr) + defer destTablet.StopActionLoop(t) + + destTablet.TM.Cnf = &mysqlctl.Mycnf{ + DataDir: sourceDataDir, + InnodbDataHomeDir: sourceInnodbDataDir, + InnodbLogGroupHomeDir: sourceInnodbLogDir, + BinLogPath: path.Join(root, "bin-logs/filename_prefix"), + RelayLogPath: path.Join(root, "relay-logs/filename_prefix"), + RelayLogIndexPath: path.Join(root, "relay-log.index"), + RelayLogInfoPath: path.Join(root, "relay-log.info"), + } + + require.NoError(t, destTablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */)) + // verify the full status + require.NoError(t, destTablet.FakeMysqlDaemon.CheckSuperQueryList(), "destTablet.FakeMysqlDaemon.CheckSuperQueryList failed") + assert.False(t, destTablet.FakeMysqlDaemon.Replicating) + assert.True(t, destTablet.FakeMysqlDaemon.Running) +} From 42c38e56e4ae29012a5d603d8bc8c22c35b78b52 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 6 May 2021 16:55:49 +0200 Subject: [PATCH 145/310] Release commit for 9.0.1 Signed-off-by: Andres Taylor --- doc/releasenotes/9_0_1_release_notes.md | 38 +++++++++++++++++++++++++ java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 doc/releasenotes/9_0_1_release_notes.md diff --git a/doc/releasenotes/9_0_1_release_notes.md b/doc/releasenotes/9_0_1_release_notes.md new file mode 100644 index 00000000000..b60f59042a5 --- /dev/null +++ b/doc/releasenotes/9_0_1_release_notes.md @@ -0,0 +1,38 @@ +This release complies with VEP-3 which removes the upgrade order requirement. Components can be upgraded in any order. It is recommended that the upgrade order should still be followed if possible, except to canary test the new version of VTGate before upgrading the rest of the components. + +## Bug fixes +### Cluster management + * Backport: Respect -disable_active_reparents in backup/restore #8063 +### Other + * [9.0] fix regression - should be able to plan subquery on top of subquery #7683 +### Query Serving + * [9.0] Fix for reserved connection usage with transaction #7666 + * [9.0] Fix MySQL Workbench failure on login with `select current_user()` #7706 + * [9.0] make sure to handle subqueries on top of subqueries #7776 + * [9.0] make sure to not log sensitive information #7778 + * [9.0] ddl bypass planner #8035 + * [9.0] Memory Sort to close the goroutines when callback returns error #8040 + * [9.0] Fix bug with reserved connections to stale tablets #8041 + * [9.0] Fix for Query Serving when Toposerver is Down #8046 + * ignore the error and log as warn if not able to validate the current system settings value #8062 +### VReplication + * VReplication: fix vreplication timing metrics #8060 + * VReplication: Pad binlog values for binary() columns to match the value returned by mysql selects #8061 +## Documentation +### Other + * 9.0.0 Release Notes #7384 +## Other +### Build/CI + * Fix Dockerfiles for vtexplain and vtctlclient #7418 +### Query Serving + * Fix table parsing on VSchema generation #7511 + * [9.0] Show anywhere plan fix to consider default keyspace #7530 + * [9.0] Reset Session for Reserved Connection when the connection id is not found #7544 + * Healthcheck: update healthy tablets correctly when a stream returns an error or times out #7732 +### VReplication + * MoveTables: Refresh SrvVSchema and source tablets on completion #8059 + + +The release includes 43 commits (excluding merges) +Thanks to all our contributors: @askdba, @deepthi, @dyv, @harshit-gangal, @rafael, @rohit-nayak-ps, @shlomi-noach, @systay + diff --git a/java/client/pom.xml b/java/client/pom.xml index ca4cac809b7..6a3d498b4c9 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0 + 9.0.1 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index d691745622e..df241e866e1 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0 + 9.0.1 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 9209c9f480b..3e597229119 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0 + 9.0.1 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 8fbede6e6b4..ec1756cdfac 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.0 + 9.0.1 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 4b469b9efbf..53ab1696082 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 9.0.0 + 9.0.1 pom Vitess Java Client libraries [Parent] From 83f1e34d273a04838f78fecdbfa3448f2a2e09e7 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 6 May 2021 16:59:40 +0200 Subject: [PATCH 146/310] Back to dev mode Signed-off-by: Andres Taylor --- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/client/pom.xml b/java/client/pom.xml index 6a3d498b4c9..188cea73f35 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.1 + 9.0.2-SNAPSHOT vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index df241e866e1..ceef8a55a18 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.1 + 9.0.2-SNAPSHOT vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 3e597229119..f53519e6e28 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.1 + 9.0.2-SNAPSHOT vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index ec1756cdfac..c6c2a629c91 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.1 + 9.0.2-SNAPSHOT vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 53ab1696082..16c1a4b4915 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 9.0.1 + 9.0.2-SNAPSHOT pom Vitess Java Client libraries [Parent] From c84427de4ccea1c6de8ea95cdcea2f34e5519293 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 7 May 2021 15:26:34 -0700 Subject: [PATCH 147/310] 10.0.0: update release notes with known issue #8080 Signed-off-by: deepthi --- doc/releasenotes/10_0_0_release_notes.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/releasenotes/10_0_0_release_notes.md b/doc/releasenotes/10_0_0_release_notes.md index ebfb3ed7201..ace6e57d215 100644 --- a/doc/releasenotes/10_0_0_release_notes.md +++ b/doc/releasenotes/10_0_0_release_notes.md @@ -3,8 +3,7 @@ This release complies with VEP-3 which removes the upgrade order requirement. Co ## Known Issues * Running binaries with `--version` or calling @@version from a MySQL client still shows `10.0.0-RC1` (Note: fixed in v10.0.1) * Online DDL [cannot be used](https://github.com/vitessio/vitess/pull/7873#issuecomment-822798180) if you are using the keyspace filtering feature of VTGate - -The following PRs made changes to behaviors that clients might rely on. They should be reviewed carefully so that client code can be changed in concert with a Vitess release deployment. +* VReplication errors when a fixed-length binary column is used as the sharding key #8080 ## Bugs Fixed From 09a29561d631c4bf1324c0a78d3df2a888522367 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 7 May 2021 15:29:15 -0700 Subject: [PATCH 148/310] 9.0.0: update release notes with known issue #8080 Signed-off-by: deepthi --- doc/releasenotes/9_0_0_release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releasenotes/9_0_0_release_notes.md b/doc/releasenotes/9_0_0_release_notes.md index 7d8b5f99e24..20c18b0a32f 100644 --- a/doc/releasenotes/9_0_0_release_notes.md +++ b/doc/releasenotes/9_0_0_release_notes.md @@ -7,6 +7,9 @@ The following PRs made changes to behaviors that clients might rely on. They sho Vitess 9.0 is not compatible with the previous release of the Vitess Kubernetes Operator (2.2.0). A new version of the Operator (2.3.0) is available that is compatible. +## Known Issue(s) +* VReplication errors when a fixed-length binary column is used as the sharding key #8080 + ## Bugs Fixed ### VTGate / MySQL compatibility From c1b75474448fbd745f2aa81e7ef6097eb5cb37d9 Mon Sep 17 00:00:00 2001 From: deepthi Date: Fri, 7 May 2021 15:31:44 -0700 Subject: [PATCH 149/310] 8.0.0: update release notes with known issue #8080 Signed-off-by: deepthi --- doc/releasenotes/8_0_0_release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/releasenotes/8_0_0_release_notes.md b/doc/releasenotes/8_0_0_release_notes.md index 26d50aab3dd..dfe82326c7c 100644 --- a/doc/releasenotes/8_0_0_release_notes.md +++ b/doc/releasenotes/8_0_0_release_notes.md @@ -11,6 +11,9 @@ If a scatter query is attempting to collect and process too many rows in memory * Zero auto-increment mode: This enables inserting a 0 value (and not just NULL) into an auto-increment column to generate sequence values. This matches the default behavior of MySQL. #6749 * Turn off schema tracker by default #6712 +## Known Issue(s) +* VReplication errors when a fixed-length binary column is used as the sharding key #8080 + ## Bugs Fixed ### VTGate / MySQL compatibility From 5174796970daac0b59964d92503ed4702729d57e Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Tue, 2 Feb 2021 14:22:07 +0530 Subject: [PATCH 150/310] Fix information_schema query with system schema in table_schema filter Backport of #7430 This is a combination of 6 commits. * added system schema in where clause plan test * added executor unit test * added logic to check table_schema of where clause and redirect to default route if it is a system schema * added e2e test * set the bindvars for the normalized predicates and remove schema name from bv if tablet will replace it * added e2e test having table_schema and table_name in where clause Signed-off-by: Harshit Gangal Signed-off-by: Andres Taylor --- go/test/endtoend/vtgate/system_schema_test.go | 12 +- go/vt/vtgate/engine/route.go | 69 +++-- go/vt/vtgate/executor_select_test.go | 275 +++++------------- .../planbuilder/testdata/from_cases.txt | 18 ++ 4 files changed, 145 insertions(+), 229 deletions(-) diff --git a/go/test/endtoend/vtgate/system_schema_test.go b/go/test/endtoend/vtgate/system_schema_test.go index e5a100bd935..5954ee5af76 100644 --- a/go/test/endtoend/vtgate/system_schema_test.go +++ b/go/test/endtoend/vtgate/system_schema_test.go @@ -71,9 +71,13 @@ func TestInformationSchemaQuery(t *testing.T) { require.NoError(t, err) defer conn.Close() - assertSingleRowIsReturned(t, conn, "table_schema = 'ks'") - assertSingleRowIsReturned(t, conn, "table_schema = 'vt_ks'") + assertSingleRowIsReturned(t, conn, "table_schema = 'ks'", "vt_ks") + assertSingleRowIsReturned(t, conn, "table_schema = 'vt_ks'", "vt_ks") assertResultIsEmpty(t, conn, "table_schema = 'NONE'") + assertSingleRowIsReturned(t, conn, "table_schema = 'performance_schema'", "performance_schema") + assertResultIsEmpty(t, conn, "table_schema = 'PERFORMANCE_SCHEMA'") + assertSingleRowIsReturned(t, conn, "table_schema = 'performance_schema' and table_name = 'users'", "performance_schema") + assertResultIsEmpty(t, conn, "table_schema = 'performance_schema' and table_name = 'foo'") } func assertResultIsEmpty(t *testing.T, conn *mysql.Conn, pre string) { @@ -84,12 +88,12 @@ func assertResultIsEmpty(t *testing.T, conn *mysql.Conn, pre string) { }) } -func assertSingleRowIsReturned(t *testing.T, conn *mysql.Conn, predicate string) { +func assertSingleRowIsReturned(t *testing.T, conn *mysql.Conn, predicate string, expectedKs string) { t.Run(predicate, func(t *testing.T) { qr, err := conn.ExecuteFetch("SELECT distinct table_schema FROM information_schema.tables WHERE "+predicate, 1000, true) require.NoError(t, err) assert.Equal(t, 1, len(qr.Rows), "did not get enough rows back") - assert.Equal(t, "vt_ks", qr.Rows[0][0].ToString()) + assert.Equal(t, expectedKs, qr.Rows[0][0].ToString()) }) } diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 71067fa51a9..61407b556f2 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -417,53 +417,59 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q Row: []sqltypes.Value{}, } + var specifiedKS string + if route.SysTableTableSchema != nil { + result, err := route.SysTableTableSchema.Evaluate(env) + if err != nil { + return nil, err + } + specifiedKS = result.Value().ToString() + bindVars[sqltypes.BvSchemaName] = sqltypes.StringBindVariable(specifiedKS) + } + + var tableName string if route.SysTableTableName != nil { - // the use has specified a table_name - let's check if it's a routed table - rss, err := route.paramsRoutedTable(vcursor, env, bindVars) + val, err := route.SysTableTableName.Evaluate(env) + if err != nil { + return nil, err + } + tableName = val.Value().ToString() + bindVars[BvTableName] = sqltypes.StringBindVariable(tableName) + } + + // if the table_schema is system system, route to default keyspace. + if sqlparser.SystemSchema(specifiedKS) { + return defaultRoute() + } + + // the use has specified a table_name - let's check if it's a routed table + if tableName != "" { + rss, err := route.paramsRoutedTable(vcursor, bindVars, specifiedKS, tableName) if err != nil { return nil, err } if rss != nil { return rss, nil } - // it was not a routed table, and we dont have a schema name to look up. give up - if route.SysTableTableSchema == nil { - return defaultRoute() - } } - // we only have table_schema to work with - result, err := route.SysTableTableSchema.Evaluate(env) - if err != nil { - return nil, err + // it was not a routed table, and we dont have a schema name to look up. give up + if specifiedKS == "" { + return defaultRoute() } - specifiedKS := result.Value().ToString() + + // we only have table_schema to work with destinations, _, err := vcursor.ResolveDestinations(specifiedKS, nil, []key.Destination{key.DestinationAnyShard{}}) if err != nil { log.Errorf("failed to route information_schema query to keyspace [%s]", specifiedKS) bindVars[sqltypes.BvSchemaName] = sqltypes.StringBindVariable(specifiedKS) return defaultRoute() } - bindVars[sqltypes.BvReplaceSchemaName] = sqltypes.Int64BindVariable(1) + setReplaceSchemaName(bindVars) return destinations, nil } -func (route *Route) paramsRoutedTable(vcursor VCursor, env evalengine.ExpressionEnv, bindVars map[string]*querypb.BindVariable) ([]*srvtopo.ResolvedShard, error) { - val, err := route.SysTableTableName.Evaluate(env) - if err != nil { - return nil, err - } - tableName := val.Value().ToString() - - var tableSchema string - if route.SysTableTableSchema != nil { - val, err := route.SysTableTableSchema.Evaluate(env) - if err != nil { - return nil, err - } - tableSchema = val.Value().ToString() - } - +func (route *Route) paramsRoutedTable(vcursor VCursor, bindVars map[string]*querypb.BindVariable, tableSchema string, tableName string) ([]*srvtopo.ResolvedShard, error) { tbl := sqlparser.TableName{ Name: sqlparser.NewTableIdent(tableName), Qualifier: sqlparser.NewTableIdent(tableSchema), @@ -478,7 +484,7 @@ func (route *Route) paramsRoutedTable(vcursor VCursor, env evalengine.Expression shards, _, err := vcursor.ResolveDestinations(destination.Keyspace.Name, nil, []key.Destination{key.DestinationAnyShard{}}) bindVars[BvTableName] = sqltypes.StringBindVariable(destination.Name.String()) if tableSchema != "" { - bindVars[sqltypes.BvReplaceSchemaName] = sqltypes.Int64BindVariable(1) + setReplaceSchemaName(bindVars) } return shards, err } @@ -488,6 +494,11 @@ func (route *Route) paramsRoutedTable(vcursor VCursor, env evalengine.Expression return nil, nil } +func setReplaceSchemaName(bindVars map[string]*querypb.BindVariable) { + delete(bindVars, sqltypes.BvSchemaName) + bindVars[sqltypes.BvReplaceSchemaName] = sqltypes.Int64BindVariable(1) +} + func (route *Route) paramsAnyShard(vcursor VCursor, bindVars map[string]*querypb.BindVariable) ([]*srvtopo.ResolvedShard, []map[string]*querypb.BindVariable, error) { rss, _, err := vcursor.ResolveDestinations(route.Keyspace.Name, nil, []key.Destination{key.DestinationAnyShard{}}) if err != nil { diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 50eab386464..7ea60e1ac2f 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -18,7 +18,6 @@ package vtgate import ( "fmt" - "reflect" "runtime" "strings" "testing" @@ -56,30 +55,35 @@ func TestSelectNext(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{"n": sqltypes.Int64BindVariable(2)}, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries:\n%v, want\n%v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) } func TestSelectDBA(t *testing.T) { executor, sbc1, _, _ := createLegacyExecutorEnv() query := "select * from INFORMATION_SCHEMA.foo" - _, err := executor.Execute( - context.Background(), - "TestSelectDBA", + _, err := executor.Execute(context.Background(), "TestSelectDBA", NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), - query, - map[string]*querypb.BindVariable{}, + query, map[string]*querypb.BindVariable{}, ) require.NoError(t, err) - wantQueries := []*querypb.BoundQuery{{ - Sql: query, - BindVariables: map[string]*querypb.BindVariable{}, - }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + wantQueries := []*querypb.BoundQuery{{Sql: query, BindVariables: map[string]*querypb.BindVariable{}}} + utils.MustMatch(t, wantQueries, sbc1.Queries) + sbc1.Queries = nil + + query = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'performance_schema' AND table_name = 'foo'" + _, err = executor.Execute(context.Background(), "TestSelectDBA", + NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), + query, map[string]*querypb.BindVariable{}, + ) + require.NoError(t, err) + wantQueries = []*querypb.BoundQuery{{Sql: "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where table_schema = :__vtschemaname and table_name = :__vttablename", + BindVariables: map[string]*querypb.BindVariable{ + "__vtschemaname": sqltypes.StringBindVariable("performance_schema"), + "__vttablename": sqltypes.StringBindVariable("foo"), + }}} + utils.MustMatch(t, wantQueries, sbc1.Queries) + } func TestUnsharded(t *testing.T) { @@ -91,9 +95,7 @@ func TestUnsharded(t *testing.T) { Sql: "select id from music_user_map where id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) } func TestUnshardedComments(t *testing.T) { @@ -105,9 +107,7 @@ func TestUnshardedComments(t *testing.T) { Sql: "/* leading */ select id from music_user_map where id = 1 /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) _, err = executorExec(executor, "update music_user_map set id = 1 /* trailing */", nil) require.NoError(t, err) @@ -118,9 +118,7 @@ func TestUnshardedComments(t *testing.T) { Sql: "update music_user_map set id = 1 /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) sbclookup.Queries = nil _, err = executorExec(executor, "delete from music_user_map /* trailing */", nil) @@ -129,9 +127,7 @@ func TestUnshardedComments(t *testing.T) { Sql: "delete from music_user_map /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) sbclookup.Queries = nil _, err = executorExec(executor, "insert into music_user_map values (1) /* trailing */", nil) @@ -140,9 +136,7 @@ func TestUnshardedComments(t *testing.T) { Sql: "insert into music_user_map values (1) /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) } func TestStreamUnsharded(t *testing.T) { @@ -216,12 +210,7 @@ func TestStreamBuffering(t *testing.T) { for r := range results { gotResults = append(gotResults, r) } - if !reflect.DeepEqual(gotResults, wantResults) { - t.Logf("len: %d", len(gotResults)) - for i := range gotResults { - t.Errorf("Buffered streaming:\n%v, want\n%v", gotResults[i], wantResults[i]) - } - } + utils.MustMatch(t, wantResults, gotResults) } func TestStreamLimitOffset(t *testing.T) { @@ -681,9 +670,7 @@ func TestSelectEqual(t *testing.T) { Sql: "select id from user where id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -695,9 +682,7 @@ func TestSelectEqual(t *testing.T) { Sql: "select id from user where id = 3", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) if execCount := sbc1.ExecCount.Get(); execCount != 1 { t.Errorf("sbc1.ExecCount: %v, want 1\n", execCount) } @@ -712,9 +697,7 @@ func TestSelectEqual(t *testing.T) { Sql: "select id from user where id = '3'", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) if execCount := sbc1.ExecCount.Get(); execCount != 1 { t.Errorf("sbc1.ExecCount: %v, want 1\n", execCount) } @@ -733,9 +716,7 @@ func TestSelectEqual(t *testing.T) { Sql: "select id from user where `name` = 'foo'", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) vars, err := sqltypes.BuildBindVariable([]interface{}{sqltypes.NewVarBinary("foo")}) require.NoError(t, err) wantQueries = []*querypb.BoundQuery{{ @@ -744,9 +725,7 @@ func TestSelectEqual(t *testing.T) { "name": vars, }, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) } func TestSelectDual(t *testing.T) { @@ -758,15 +737,11 @@ func TestSelectDual(t *testing.T) { Sql: "select @@aa.bb from dual", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) _, err = executorExec(executor, "select @@aa.bb from TestUnsharded.dual", nil) require.NoError(t, err) - if !reflect.DeepEqual(lookup.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, lookup.Queries) } func TestSelectComments(t *testing.T) { @@ -778,9 +753,7 @@ func TestSelectComments(t *testing.T) { Sql: "/* leading */ select id from user where id = 1 /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -799,9 +772,7 @@ func TestSelectNormalize(t *testing.T) { "vtg1": sqltypes.TestBindVariable(int64(1)), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -832,9 +803,7 @@ func TestSelectCaseSensitivity(t *testing.T) { Sql: "select Id from user where iD = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -862,9 +831,7 @@ func TestSelectKeyRange(t *testing.T) { Sql: "select krcol_unique, krcol from keyrange_table where krcol = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -880,9 +847,7 @@ func TestSelectKeyRangeUnique(t *testing.T) { Sql: "select krcol_unique, krcol from keyrange_table where krcol_unique = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -901,9 +866,7 @@ func TestSelectIN(t *testing.T) { "__vals": sqltypes.TestBindVariable([]interface{}{int64(1)}), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } @@ -920,18 +883,14 @@ func TestSelectIN(t *testing.T) { "__vals": sqltypes.TestBindVariable([]interface{}{int64(1)}), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantQueries = []*querypb.BoundQuery{{ Sql: "select id from user where id in ::__vals", BindVariables: map[string]*querypb.BindVariable{ "__vals": sqltypes.TestBindVariable([]interface{}{int64(3)}), }, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) // In is a bind variable list, that will end up on two shards. // This is using an []interface{} for the bind variable list. @@ -948,9 +907,7 @@ func TestSelectIN(t *testing.T) { "vals": sqltypes.TestBindVariable([]interface{}{int64(1), int64(3)}), }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantQueries = []*querypb.BoundQuery{{ Sql: "select id from user where id in ::__vals", BindVariables: map[string]*querypb.BindVariable{ @@ -958,9 +915,7 @@ func TestSelectIN(t *testing.T) { "vals": sqltypes.TestBindVariable([]interface{}{int64(1), int64(3)}), }, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) // Convert a non-list bind variable. sbc1.Queries = nil @@ -975,9 +930,7 @@ func TestSelectIN(t *testing.T) { Sql: "select id from user where `name` = 'foo'", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) vars, err := sqltypes.BuildBindVariable([]interface{}{sqltypes.NewVarBinary("foo")}) require.NoError(t, err) wantQueries = []*querypb.BoundQuery{{ @@ -986,9 +939,7 @@ func TestSelectIN(t *testing.T) { "name": vars, }, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) } func TestStreamSelectIN(t *testing.T) { @@ -1033,9 +984,7 @@ func TestStreamSelectIN(t *testing.T) { "name": vars, }, }} - if !reflect.DeepEqual(sbclookup.Queries, wantQueries) { - t.Errorf("sbclookup.Queries: %+v, want %+v\n", sbclookup.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbclookup.Queries) } func TestSelectScatter(t *testing.T) { @@ -1064,9 +1013,7 @@ func TestSelectScatter(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } testQueryLog(t, logChan, "TestExecute", "SELECT", wantQueries[0].Sql, 8) } @@ -1209,9 +1156,7 @@ func TestSelectScatterOrderBy(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1232,9 +1177,7 @@ func TestSelectScatterOrderBy(t *testing.T) { wantResult.Rows = append(wantResult.Rows, row) } } - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } // TestSelectScatterOrderByVarChar will run an ORDER BY query that will scatter out to 8 shards and return the 8 rows (one per shard) sorted. @@ -1280,9 +1223,7 @@ func TestSelectScatterOrderByVarChar(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1303,9 +1244,7 @@ func TestSelectScatterOrderByVarChar(t *testing.T) { wantResult.Rows = append(wantResult.Rows, row) } } - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } func TestStreamSelectScatterOrderBy(t *testing.T) { @@ -1346,9 +1285,7 @@ func TestStreamSelectScatterOrderBy(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1364,9 +1301,7 @@ func TestStreamSelectScatterOrderBy(t *testing.T) { } wantResult.Rows = append(wantResult.Rows, row, row) } - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } func TestStreamSelectScatterOrderByVarChar(t *testing.T) { @@ -1408,9 +1343,7 @@ func TestStreamSelectScatterOrderByVarChar(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1426,9 +1359,7 @@ func TestStreamSelectScatterOrderByVarChar(t *testing.T) { } wantResult.Rows = append(wantResult.Rows, row, row) } - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } // TestSelectScatterAggregate will run an aggregate query that will scatter out to 8 shards and return 4 aggregated rows. @@ -1470,9 +1401,7 @@ func TestSelectScatterAggregate(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1490,9 +1419,7 @@ func TestSelectScatterAggregate(t *testing.T) { } wantResult.Rows = append(wantResult.Rows, row) } - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } func TestStreamSelectScatterAggregate(t *testing.T) { @@ -1533,9 +1460,7 @@ func TestStreamSelectScatterAggregate(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("conn.Queries = %#v, want %#v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1551,9 +1476,7 @@ func TestStreamSelectScatterAggregate(t *testing.T) { } wantResult.Rows = append(wantResult.Rows, row) } - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } // TestSelectScatterLimit will run a limit query (ordered for consistency) against @@ -1596,9 +1519,7 @@ func TestSelectScatterLimit(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("got: conn.Queries = %v, want: %v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1623,9 +1544,7 @@ func TestSelectScatterLimit(t *testing.T) { sqltypes.NewInt32(2), }) - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } // TestStreamSelectScatterLimit will run a streaming limit query (ordered for consistency) against @@ -1668,9 +1587,7 @@ func TestStreamSelectScatterLimit(t *testing.T) { BindVariables: map[string]*querypb.BindVariable{"__upper_limit": sqltypes.Int64BindVariable(3)}, }} for _, conn := range conns { - if !reflect.DeepEqual(conn.Queries, wantQueries) { - t.Errorf("got: conn.Queries = %v, want: %v", conn.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, conn.Queries) } wantResult := &sqltypes.Result{ @@ -1693,9 +1610,7 @@ func TestStreamSelectScatterLimit(t *testing.T) { sqltypes.NewInt32(2), }) - if !reflect.DeepEqual(gotResult, wantResult) { - t.Errorf("scatter order by:\n%v, want\n%v", gotResult, wantResult) - } + utils.MustMatch(t, wantResult, gotResult) } // TODO(sougou): stream and non-stream testing are very similar. @@ -1712,16 +1627,12 @@ func TestSimpleJoin(t *testing.T) { Sql: "select u1.id from user as u1 where u1.id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantQueries = []*querypb.BoundQuery{{ Sql: "select u2.id from user as u2 where u2.id = 3", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ sandboxconn.SingleRowResult.Fields[0], @@ -1754,16 +1665,12 @@ func TestJoinComments(t *testing.T) { Sql: "select u1.id from user as u1 where u1.id = 1 /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantQueries = []*querypb.BoundQuery{{ Sql: "select u2.id from user as u2 where u2.id = 3 /* trailing */", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) testQueryLog(t, logChan, "TestExecute", "SELECT", sql, 2) } @@ -1780,16 +1687,12 @@ func TestSimpleJoinStream(t *testing.T) { Sql: "select u1.id from user as u1 where u1.id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantQueries = []*querypb.BoundQuery{{ Sql: "select u2.id from user as u2 where u2.id = 3", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc2.Queries, wantQueries) { - t.Errorf("sbc2.Queries: %+v, want %+v\n", sbc2.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc2.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ sandboxconn.SingleRowResult.Fields[0], @@ -1835,9 +1738,7 @@ func TestVarJoin(t *testing.T) { Sql: "select u1.id, u1.col from user as u1 where u1.id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) // We have to use string representation because bindvars type is too complex. got := fmt.Sprintf("%+v", sbc2.Queries) want := `[sql:"select u2.id from user as u2 where u2.id = :u1_col" bind_variables: > ]` @@ -1873,9 +1774,7 @@ func TestVarJoinStream(t *testing.T) { Sql: "select u1.id, u1.col from user as u1 where u1.id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) // We have to use string representation because bindvars type is too complex. got := fmt.Sprintf("%+v", sbc2.Queries) want := `[sql:"select u2.id from user as u2 where u2.id = :u1_col" bind_variables: > ]` @@ -1998,9 +1897,7 @@ func TestEmptyJoin(t *testing.T) { "u1_col": sqltypes.NullBindVariable, }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries:\n%v, want\n%v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ {Name: "id", Type: sqltypes.Int32}, @@ -2036,9 +1933,7 @@ func TestEmptyJoinStream(t *testing.T) { "u1_col": sqltypes.NullBindVariable, }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ {Name: "id", Type: sqltypes.Int32}, @@ -2081,9 +1976,7 @@ func TestEmptyJoinRecursive(t *testing.T) { "u2_col": sqltypes.NullBindVariable, }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries:\n%+v, want\n%+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ {Name: "id", Type: sqltypes.Int32}, @@ -2127,9 +2020,7 @@ func TestEmptyJoinRecursiveStream(t *testing.T) { "u2_col": sqltypes.NullBindVariable, }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ {Name: "id", Type: sqltypes.Int32}, @@ -2163,9 +2054,7 @@ func TestCrossShardSubquery(t *testing.T) { Sql: "select u1.id as id1, u1.col from user as u1 where u1.id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) // We have to use string representation because bindvars type is too complex. got := fmt.Sprintf("%+v", sbc2.Queries) want := `[sql:"select u2.id from user as u2 where u2.id = :u1_col" bind_variables: > ]` @@ -2208,9 +2097,7 @@ func TestCrossShardSubqueryStream(t *testing.T) { Sql: "select u1.id as id1, u1.col from user as u1 where u1.id = 1", BindVariables: map[string]*querypb.BindVariable{}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries:\n%+v, want\n%+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) // We have to use string representation because bindvars type is too complex. got := fmt.Sprintf("%+v", sbc2.Queries) want := `[sql:"select u2.id from user as u2 where u2.id = :u1_col" bind_variables: > ]` @@ -2256,9 +2143,7 @@ func TestCrossShardSubqueryGetFields(t *testing.T) { "u1_col": sqltypes.NullBindVariable, }, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries:\n%+v, want\n%+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) wantResult := &sqltypes.Result{ Fields: []*querypb.Field{ @@ -2286,9 +2171,7 @@ func TestSelectBindvarswithPrepare(t *testing.T) { Sql: "select id from user where 1 != 1", BindVariables: map[string]*querypb.BindVariable{"id": sqltypes.Int64BindVariable(1)}, }} - if !reflect.DeepEqual(sbc1.Queries, wantQueries) { - t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries) - } + utils.MustMatch(t, wantQueries, sbc1.Queries) if sbc2.Queries != nil { t.Errorf("sbc2.Queries: %+v, want nil\n", sbc2.Queries) } diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.txt b/go/vt/vtgate/planbuilder/testdata/from_cases.txt index 441085535ad..e918b9d902f 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.txt @@ -2447,3 +2447,21 @@ } } +# system schema in where clause of information_schema query +"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'performance_schema' AND table_name = 'foo'" +{ + "QueryType": "SELECT", + "Original": "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'performance_schema' AND table_name = 'foo'", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where 1 != 1", + "Query": "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where table_schema = :__vtschemaname and table_name = :__vttablename", + "SysTableTableName": "VARBINARY(\"foo\")", + "SysTableTableSchema": "VARBINARY(\"performance_schema\")" + } +} From faeef9724158ea0708ba590bb8f1b02907abcb0b Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Tue, 13 Apr 2021 11:33:56 +0530 Subject: [PATCH 151/310] Routing of Information Schema Queries Backport of #7841 * made sysTableTableSchema a slice and fixed merging for SelectDBA queries * updated tests * added tests * changed error message Signed-off-by: GuptaManan100 Signed-off-by: Andres Taylor --- go/test/endtoend/vtgate/system_schema_test.go | 26 ++++ go/vt/vtgate/engine/route.go | 60 ++++++-- go/vt/vtgate/engine/route_test.go | 48 ++++-- go/vt/vtgate/evalengine/expressions.go | 12 -- go/vt/vtgate/executor_select_test.go | 2 +- go/vt/vtgate/planbuilder/route.go | 10 +- go/vt/vtgate/planbuilder/system_tables.go | 12 +- .../planbuilder/testdata/filter_cases.txt | 24 ++- .../planbuilder/testdata/from_cases.txt | 142 ++++++------------ .../planbuilder/testdata/select_cases.txt | 94 ++++++++++++ .../testdata/unsupported_cases.txt | 17 ++- 11 files changed, 279 insertions(+), 168 deletions(-) diff --git a/go/test/endtoend/vtgate/system_schema_test.go b/go/test/endtoend/vtgate/system_schema_test.go index 5954ee5af76..71bb809142f 100644 --- a/go/test/endtoend/vtgate/system_schema_test.go +++ b/go/test/endtoend/vtgate/system_schema_test.go @@ -187,3 +187,29 @@ func TestSystemSchemaQueryWithoutQualifier(t *testing.T) { qr3 := exec(t, conn2, queryWithoutQualifier) require.Equal(t, qr2, qr3) } + +func TestMultipleSchemaPredicates(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + query := fmt.Sprintf("select t.table_schema,t.table_name,c.column_name,c.column_type "+ + "from information_schema.tables t "+ + "join information_schema.columns c "+ + "on c.table_schema = t.table_schema and c.table_name = t.table_name "+ + "where t.table_schema = '%s' and c.table_schema = '%s' and c.table_schema = '%s' and c.table_schema = '%s'", KeyspaceName, KeyspaceName, KeyspaceName, KeyspaceName) + qr1 := exec(t, conn, query) + require.EqualValues(t, 4, len(qr1.Fields)) + + // test a query with two keyspace names + query = fmt.Sprintf("select t.table_schema,t.table_name,c.column_name,c.column_type "+ + "from information_schema.tables t "+ + "join information_schema.columns c "+ + "on c.table_schema = t.table_schema and c.table_name = t.table_name "+ + "where t.table_schema = '%s' and c.table_schema = '%s' and c.table_schema = '%s'", KeyspaceName, KeyspaceName, "a") + _, err = conn.ExecuteFetch(query, 1000, true) + require.Error(t, err) + require.Contains(t, err.Error(), "specifying two different database in the query is not supported") +} diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 61407b556f2..362bbd15c25 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -94,8 +94,8 @@ type Route struct { ScatterErrorsAsWarnings bool // The following two fields are used when routing information_schema queries - SysTableTableSchema evalengine.Expr - SysTableTableName evalengine.Expr + SysTableTableSchema []evalengine.Expr + SysTableTableName []evalengine.Expr // Route does not take inputs noInputs @@ -408,7 +408,7 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q return destinations, vterrors.Wrapf(err, "failed to find information about keyspace `%s`", ks) } - if route.SysTableTableName == nil && route.SysTableTableSchema == nil { + if len(route.SysTableTableName) == 0 && len(route.SysTableTableSchema) == 0 { return defaultRoute() } @@ -418,22 +418,38 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q } var specifiedKS string - if route.SysTableTableSchema != nil { - result, err := route.SysTableTableSchema.Evaluate(env) + for _, tableSchema := range route.SysTableTableSchema { + result, err := tableSchema.Evaluate(env) if err != nil { return nil, err } - specifiedKS = result.Value().ToString() + ks := result.Value().ToString() + if specifiedKS == "" { + specifiedKS = ks + } + if specifiedKS != ks { + return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "specifying two different database in the query is not supported") + } + } + if specifiedKS != "" { bindVars[sqltypes.BvSchemaName] = sqltypes.StringBindVariable(specifiedKS) } var tableName string - if route.SysTableTableName != nil { - val, err := route.SysTableTableName.Evaluate(env) + for _, sysTableName := range route.SysTableTableName { + val, err := sysTableName.Evaluate(env) if err != nil { return nil, err } - tableName = val.Value().ToString() + tabName := val.Value().ToString() + if tableName == "" { + tableName = tabName + } + if tableName != tabName { + return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "two predicates for table_name not supported") + } + } + if tableName != "" { bindVars[BvTableName] = sqltypes.StringBindVariable(tableName) } @@ -723,11 +739,27 @@ func (route *Route) description() PrimitiveDescription { if len(route.Values) > 0 { other["Values"] = route.Values } - if route.SysTableTableSchema != nil { - other["SysTableTableSchema"] = route.SysTableTableSchema.String() - } - if route.SysTableTableName != nil { - other["SysTableTableName"] = route.SysTableTableName.String() + if len(route.SysTableTableSchema) != 0 { + sysTabSchema := "[" + for idx, tableSchema := range route.SysTableTableSchema { + if idx != 0 { + sysTabSchema += ", " + } + sysTabSchema += tableSchema.String() + } + sysTabSchema += "]" + other["SysTableTableSchema"] = sysTabSchema + } + if len(route.SysTableTableName) != 0 { + sysTableName := "[" + for idx, tableName := range route.SysTableTableName { + if idx != 0 { + sysTableName += ", " + } + sysTableName += tableName.String() + } + sysTableName += "]" + other["SysTableTableName"] = sysTableName } orderBy := GenericJoin(route.OrderBy, orderByToString) if orderBy != "" { diff --git a/go/vt/vtgate/engine/route_test.go b/go/vt/vtgate/engine/route_test.go index bb8bad02339..93deb22a727 100644 --- a/go/vt/vtgate/engine/route_test.go +++ b/go/vt/vtgate/engine/route_test.go @@ -78,23 +78,24 @@ func TestSelectUnsharded(t *testing.T) { } func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) { - stringToExpr := func(in string) evalengine.Expr { - var schema evalengine.Expr - if in != "" { - schema = evalengine.NewLiteralString([]byte(in)) + stringListToExprList := func(in []string) []evalengine.Expr { + var schema []evalengine.Expr + for _, s := range in { + schema = append(schema, evalengine.NewLiteralString([]byte(s))) } return schema } type testCase struct { - tableSchema, tableName, testName string - expectedLog []string - routed bool + tableSchema, tableName []string + testName string + expectedLog []string + routed bool } tests := []testCase{{ testName: "both schema and table predicates - routed table", - tableSchema: "schema", - tableName: "table", + tableSchema: []string{"schema"}, + tableName: []string{"table"}, routed: true, expectedLog: []string{ "FindTable(`schema`.`table`)", @@ -102,8 +103,17 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard routedKeyspace.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" __vttablename: type:VARBINARY value:\"routedTable\" } false false"}, }, { testName: "both schema and table predicates - not routed", - tableSchema: "schema", - tableName: "table", + tableSchema: []string{"schema"}, + tableName: []string{"table"}, + routed: false, + expectedLog: []string{ + "FindTable(`schema`.`table`)", + "ResolveDestinations schema [] Destinations:DestinationAnyShard()", + "ExecuteMultiShard schema.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" __vttablename: type:VARBINARY value:\"table\" } false false"}, + }, { + testName: "multiple schema and table predicates", + tableSchema: []string{"schema", "schema", "schema"}, + tableName: []string{"table", "table", "table"}, routed: false, expectedLog: []string{ "FindTable(`schema`.`table`)", @@ -111,7 +121,7 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard schema.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" __vttablename: type:VARBINARY value:\"table\" } false false"}, }, { testName: "table name predicate - routed table", - tableName: "tableName", + tableName: []string{"tableName"}, routed: true, expectedLog: []string{ "FindTable(tableName)", @@ -119,7 +129,7 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard routedKeyspace.1: dummy_select {__vttablename: type:VARBINARY value:\"routedTable\" } false false"}, }, { testName: "table name predicate - not routed", - tableName: "tableName", + tableName: []string{"tableName"}, routed: false, expectedLog: []string{ "FindTable(tableName)", @@ -127,7 +137,13 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) "ExecuteMultiShard ks.1: dummy_select {__vttablename: type:VARBINARY value:\"tableName\" } false false"}, }, { testName: "schema predicate", - tableSchema: "myKeyspace", + tableSchema: []string{"myKeyspace"}, + expectedLog: []string{ + "ResolveDestinations myKeyspace [] Destinations:DestinationAnyShard()", + "ExecuteMultiShard myKeyspace.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" } false false"}, + }, { + testName: "multiple schema predicates", + tableSchema: []string{"myKeyspace", "myKeyspace", "myKeyspace", "myKeyspace"}, expectedLog: []string{ "ResolveDestinations myKeyspace [] Destinations:DestinationAnyShard()", "ExecuteMultiShard myKeyspace.1: dummy_select {__replacevtschemaname: type:INT64 value:\"1\" } false false"}, @@ -148,8 +164,8 @@ func TestSelectInformationSchemaWithTableAndSchemaWithRoutedTables(t *testing.T) }, Query: "dummy_select", FieldQuery: "dummy_select_field", - SysTableTableSchema: stringToExpr(tc.tableSchema), - SysTableTableName: stringToExpr(tc.tableName), + SysTableTableSchema: stringListToExprList(tc.tableSchema), + SysTableTableName: stringListToExprList(tc.tableName), } vc := &loggingVCursor{ shards: []string{"1"}, diff --git a/go/vt/vtgate/evalengine/expressions.go b/go/vt/vtgate/evalengine/expressions.go index baafbe8a0c2..a32badee480 100644 --- a/go/vt/vtgate/evalengine/expressions.go +++ b/go/vt/vtgate/evalengine/expressions.go @@ -327,15 +327,3 @@ func evaluateByType(val *querypb.BindVariable) (EvalResult, error) { func (e *EvalResult) debugString() string { return fmt.Sprintf("(%s) %d %d %f %s", querypb.Type_name[int32(e.typ)], e.ival, e.uval, e.fval, string(e.bytes)) } - -// AreExprEqual checks if the provided Expr are the same or not -func AreExprEqual(expr1 Expr, expr2 Expr) bool { - // Check the types of the two expressions, if they don't match then the two are not equal - if fmt.Sprintf("%T", expr1) != fmt.Sprintf("%T", expr2) { - return false - } - if expr1.String() == expr2.String() { - return true - } - return false -} diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 7ea60e1ac2f..2eb31930b34 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -2290,7 +2290,7 @@ func TestSelectFromInformationSchema(t *testing.T) { // check failure when trying to query two keyspaces _, err := exec(executor, session, "SELECT B.TABLE_NAME FROM INFORMATION_SCHEMA.TABLES AS A, INFORMATION_SCHEMA.COLUMNS AS B WHERE A.TABLE_SCHEMA = 'TestExecutor' AND A.TABLE_SCHEMA = 'TestXBadSharding'") require.Error(t, err) - require.Contains(t, err.Error(), "two predicates for specifying the database are not supported") + require.Contains(t, err.Error(), "specifying two different database in the query is not supported") // we pick a keyspace and query for table_schema = database(). should be routed to the picked keyspace session.TargetString = "TestExecutor" diff --git a/go/vt/vtgate/planbuilder/route.go b/go/vt/vtgate/planbuilder/route.go index ea6baaa24c7..5e921e0abec 100644 --- a/go/vt/vtgate/planbuilder/route.go +++ b/go/vt/vtgate/planbuilder/route.go @@ -392,15 +392,7 @@ func (rb *route) JoinCanMerge(pb *primitiveBuilder, rrb *route, ajoin *sqlparser if where == nil { return true } - hasRuntimeRoutingPredicates := false - sqlparser.Walk(func(node sqlparser.SQLNode) (kontinue bool, err error) { - col, ok := node.(*sqlparser.ColName) - if ok { - hasRuntimeRoutingPredicates = hasRuntimeRoutingPredicates || isTableNameCol(col) || isDbNameCol(col) - } - return !hasRuntimeRoutingPredicates, nil - }, where) - return !hasRuntimeRoutingPredicates + return ajoin != nil } if ajoin == nil { return false diff --git a/go/vt/vtgate/planbuilder/system_tables.go b/go/vt/vtgate/planbuilder/system_tables.go index 84ee0d323d7..3d073d63a65 100644 --- a/go/vt/vtgate/planbuilder/system_tables.go +++ b/go/vt/vtgate/planbuilder/system_tables.go @@ -18,9 +18,7 @@ package planbuilder import ( "vitess.io/vitess/go/sqltypes" - 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" "vitess.io/vitess/go/vt/vtgate/evalengine" ) @@ -36,15 +34,9 @@ func (pb *primitiveBuilder) findSysInfoRoutingPredicates(expr sqlparser.Expr, ru } if isTableSchema { - if rut.eroute.SysTableTableSchema != nil && !evalengine.AreExprEqual(rut.eroute.SysTableTableSchema, out) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "two predicates for specifying the database are not supported") - } - rut.eroute.SysTableTableSchema = out + rut.eroute.SysTableTableSchema = append(rut.eroute.SysTableTableSchema, out) } else { - if rut.eroute.SysTableTableName != nil && !evalengine.AreExprEqual(rut.eroute.SysTableTableName, out) { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "two predicates for table_name not supported") - } - rut.eroute.SysTableTableName = out + rut.eroute.SysTableTableName = append(rut.eroute.SysTableTableName, out) } return nil diff --git a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt index a2ba4862a31..308c97f6afb 100644 --- a/go/vt/vtgate/planbuilder/testdata/filter_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/filter_cases.txt @@ -1683,7 +1683,21 @@ # query trying to query two different keyspaces at the same time "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'" -"two predicates for specifying the database are not supported" +{ + "QueryType": "SELECT", + "Original": "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'user' AND TABLE_SCHEMA = 'main'", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", + "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and TABLE_SCHEMA = :__vtschemaname", + "SysTableTableSchema": "[VARBINARY(\"user\"), VARBINARY(\"main\")]" + } +} # information_schema query using database() func "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = database()" @@ -1716,7 +1730,7 @@ }, "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"ks\")" + "SysTableTableSchema": "[VARBINARY(\"ks\")]" } } @@ -1751,8 +1765,8 @@ }, "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and TABLE_NAME = :__vttablename", - "SysTableTableName": "VARBINARY(\"route1\")", - "SysTableTableSchema": "VARBINARY(\"ks\")" + "SysTableTableName": "[VARBINARY(\"route1\")]", + "SysTableTableSchema": "[VARBINARY(\"ks\")]" } } @@ -1770,7 +1784,7 @@ }, "FieldQuery": "select * from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select * from INFORMATION_SCHEMA.`TABLES` where TABLE_SCHEMA = :__vtschemaname and other_column = 42", - "SysTableTableSchema": "VARBINARY(\"ks\")" + "SysTableTableSchema": "[VARBINARY(\"ks\")]" } } diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.txt b/go/vt/vtgate/planbuilder/testdata/from_cases.txt index e918b9d902f..a50a63fcee0 100644 --- a/go/vt/vtgate/planbuilder/testdata/from_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/from_cases.txt @@ -2192,34 +2192,15 @@ "QueryType": "SELECT", "Original": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as name, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk using (constraint_schema, constraint_name) where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = ':vtg1' and rc.constraint_schema = database() and rc.table_name = ':vtg1'", "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1,2,3,4,-1,-2", - "TableName": "_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where 1 != 1", - "Query": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where rc.constraint_schema = database() and rc.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\":vtg1\")" - }, - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where fk.constraint_schema = :rc_constraint_schema and fk.constraint_name = :rc_constraint_name and fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\":vtg1\")" - } - ] + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where 1 != 1", + "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where fk.referenced_column_name is not null and fk.table_schema = database() and fk.table_name = :__vttablename and rc.constraint_schema = database() and rc.table_name = :__vttablename", + "SysTableTableName": "[VARBINARY(\":vtg1\"), VARBINARY(\":vtg1\")]" } } @@ -2237,7 +2218,7 @@ }, "FieldQuery": "select * from information_schema.schemata where 1 != 1", "Query": "select * from information_schema.schemata where schema_name = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"user\")" + "SysTableTableSchema": "[VARBINARY(\"user\")]" } } @@ -2255,8 +2236,8 @@ }, "FieldQuery": "select table_comment from information_schema.`tables` where 1 != 1", "Query": "select table_comment from information_schema.`tables` where table_schema = :__vtschemaname and table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"schema_name\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"schema_name\")]" } } @@ -2266,36 +2247,16 @@ "QueryType": "SELECT", "Original": "SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key',fk.column_name AS 'column',fk.constraint_name AS 'name',rc.update_rule AS 'on_update',rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'table_schema' AND fk.table_name = 'table_name' AND rc.constraint_schema = 'table_schema' AND rc.table_name = 'table_name'", "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "1,2,3,4,-1,-2", - "TableName": "_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where 1 != 1", - "Query": "select rc.update_rule as on_update, rc.delete_rule as on_delete, rc.constraint_schema, rc.constraint_name from information_schema.referential_constraints as rc where rc.constraint_schema = :__vtschemaname and rc.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" - }, - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where 1 != 1", - "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name` from information_schema.key_column_usage as fk where fk.constraint_schema = :rc_constraint_schema and fk.constraint_name = :rc_constraint_name and fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname and fk.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" - } - ] + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where 1 != 1", + "Query": "select fk.referenced_table_name as to_table, fk.referenced_column_name as primary_key, fk.column_name as `column`, fk.constraint_name as `name`, rc.update_rule as on_update, rc.delete_rule as on_delete from information_schema.referential_constraints as rc join information_schema.key_column_usage as fk on rc.constraint_schema = fk.constraint_schema and rc.constraint_name = fk.constraint_name where fk.referenced_column_name is not null and fk.table_schema = :__vtschemaname and fk.table_name = :__vttablename and rc.constraint_schema = :__vtschemaname and rc.table_name = :__vttablename", + "SysTableTableName": "[VARBINARY(\"table_name\"), VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\"), VARBINARY(\"table_schema\")]" } } @@ -2305,35 +2266,16 @@ "QueryType": "SELECT", "Original": "SELECT cc.constraint_name AS 'name', cc.check_clause AS 'expression' FROM information_schema.check_constraints cc JOIN information_schema.table_constraints tc USING (constraint_schema, constraint_name) WHERE tc.table_schema = 'table_schema' AND tc.table_name = 'table_name' AND cc.constraint_schema = 'constraint_schema'", "Instructions": { - "OperatorType": "Join", - "Variant": "Join", - "JoinColumnIndexes": "-1,-2", - "TableName": "_", - "Inputs": [ - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select cc.constraint_name as `name`, cc.check_clause as expression, cc.constraint_schema from information_schema.check_constraints as cc where 1 != 1", - "Query": "select cc.constraint_name as `name`, cc.check_clause as expression, cc.constraint_schema from information_schema.check_constraints as cc where cc.constraint_schema = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"constraint_schema\")" - }, - { - "OperatorType": "Route", - "Variant": "SelectDBA", - "Keyspace": { - "Name": "main", - "Sharded": false - }, - "FieldQuery": "select 1 from information_schema.table_constraints as tc where 1 != 1", - "Query": "select 1 from information_schema.table_constraints as tc where tc.constraint_schema = :cc_constraint_schema and tc.constraint_name = :cc_constraint_name and tc.table_schema = :__vtschemaname and tc.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" - } - ] + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select cc.constraint_name as `name`, cc.check_clause as expression from information_schema.check_constraints as cc join information_schema.table_constraints as tc on cc.constraint_schema = tc.constraint_schema and cc.constraint_name = tc.constraint_name where 1 != 1", + "Query": "select cc.constraint_name as `name`, cc.check_clause as expression from information_schema.check_constraints as cc join information_schema.table_constraints as tc on cc.constraint_schema = tc.constraint_schema and cc.constraint_name = tc.constraint_name where tc.table_schema = :__vtschemaname and tc.table_name = :__vttablename and cc.constraint_schema = :__vtschemaname", + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\"), VARBINARY(\"constraint_schema\")]" } } @@ -2351,8 +2293,8 @@ }, "FieldQuery": "select column_name from information_schema.statistics where 1 != 1", "Query": "select column_name from information_schema.statistics where index_name = 'PRIMARY' and table_schema = :__vtschemaname and table_name = :__vttablename order by seq_in_index asc", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2370,8 +2312,8 @@ }, "FieldQuery": "select generation_expression from information_schema.`columns` where 1 != 1", "Query": "select generation_expression from information_schema.`columns` where table_schema = :__vtschemaname and table_name = :__vttablename and column_name = 'column_name'", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2406,7 +2348,7 @@ }, "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname) as _subquery", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2424,8 +2366,8 @@ }, "FieldQuery": "select table_name from (select * from information_schema.`tables` where 1 != 1) as _subquery where 1 != 1", "Query": "select table_name from (select * from information_schema.`tables` where table_schema = :__vtschemaname) as _subquery where _subquery.table_type = 'table_type' and _subquery.table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"table_name\")", - "SysTableTableSchema": "VARBINARY(\"table_schema\")" + "SysTableTableName": "[VARBINARY(\"table_name\")]", + "SysTableTableSchema": "[VARBINARY(\"table_schema\")]" } } @@ -2443,7 +2385,7 @@ }, "FieldQuery": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where 1 != 1", "Query": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where cc.constraint_schema = :__vtschemaname and cc.table_schema = :__vtschemaname", - "SysTableTableSchema": "VARBINARY(\"a\")" + "SysTableTableSchema": "[VARBINARY(\"a\"), VARBINARY(\"a\")]" } } @@ -2461,7 +2403,7 @@ }, "FieldQuery": "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where 1 != 1", "Query": "select COUNT(*) from INFORMATION_SCHEMA.`TABLES` where table_schema = :__vtschemaname and table_name = :__vttablename", - "SysTableTableName": "VARBINARY(\"foo\")", - "SysTableTableSchema": "VARBINARY(\"performance_schema\")" + "SysTableTableName": "[VARBINARY(\"foo\")]", + "SysTableTableSchema": "[VARBINARY(\"performance_schema\")]" } } diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt index e80cb524aef..b94fd79accd 100644 --- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt @@ -1661,3 +1661,97 @@ ] } } + +# Select from information schema query with two tables that route should be merged +"SELECT DELETE_RULE, UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME" +{ + "QueryType": "SELECT", + "Original": "SELECT DELETE_RULE, UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.COLUMN_NAME = 'id' AND KCU.REFERENCED_TABLE_SCHEMA = 'test' AND KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select DELETE_RULE, UPDATE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", + "Query": "select DELETE_RULE, UPDATE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname and KCU.TABLE_NAME = :__vttablename and KCU.COLUMN_NAME = 'id' and KCU.REFERENCED_TABLE_SCHEMA = 'test' and KCU.CONSTRAINT_NAME = 'data_type_table_id_fkey' order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", + "SysTableTableName": "[VARBINARY(\"data_type_table\")]", + "SysTableTableSchema": "[VARBINARY(\"test\")]" + } +} + +# Select from information schema query with three tables such that route for 2 should be merged but not for the last. +"SELECT KCU.DELETE_RULE, S.UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.K AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME" +{ + "QueryType": "SELECT", + "Original": "SELECT KCU.DELETE_RULE, S.UPDATE_RULE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC ON KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME, INFORMATION_SCHEMA.K AS S WHERE KCU.TABLE_SCHEMA = 'test' AND KCU.TABLE_NAME = 'data_type_table' AND KCU.TABLE_NAME = 'data_type_table' AND S.TABLE_SCHEMA = 'test' AND S.TABLE_NAME = 'sc' ORDER BY KCU.CONSTRAINT_NAME, KCU.COLUMN_NAME", + "Instructions": { + "OperatorType": "Join", + "Variant": "Join", + "JoinColumnIndexes": "-1,1", + "TableName": "_", + "Inputs": [ + { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select KCU.DELETE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where 1 != 1", + "Query": "select KCU.DELETE_RULE from INFORMATION_SCHEMA.KEY_COLUMN_USAGE as KCU join INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS as RC on KCU.CONSTRAINT_NAME = RC.CONSTRAINT_NAME where KCU.TABLE_SCHEMA = :__vtschemaname and KCU.TABLE_NAME = :__vttablename and KCU.TABLE_NAME = :__vttablename order by KCU.CONSTRAINT_NAME asc, KCU.COLUMN_NAME asc", + "SysTableTableName": "[VARBINARY(\"data_type_table\"), VARBINARY(\"data_type_table\")]", + "SysTableTableSchema": "[VARBINARY(\"test\")]" + }, + { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select S.UPDATE_RULE from INFORMATION_SCHEMA.K as S where 1 != 1", + "Query": "select S.UPDATE_RULE from INFORMATION_SCHEMA.K as S where S.TABLE_SCHEMA = :__vtschemaname and S.TABLE_NAME = :__vttablename", + "SysTableTableName": "[VARBINARY(\"sc\")]", + "SysTableTableSchema": "[VARBINARY(\"test\")]" + } + ] + } +} + +#information_schema table sizes +"SELECT SUM(data_length + index_length) as size FROM information_schema.TABLES WHERE table_schema = ?" +{ + "QueryType": "SELECT", + "Original": "SELECT SUM(data_length + index_length) as size FROM information_schema.TABLES WHERE table_schema = ?", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select SUM(data_length + index_length) as size from information_schema.`TABLES` where 1 != 1", + "Query": "select SUM(data_length + index_length) as size from information_schema.`TABLES` where table_schema = :__vtschemaname", + "SysTableTableSchema": "[:v1]" + } +} + +#information_schema referential contraints +"SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position" +{ + "QueryType": "SELECT", + "Original": "SELECT kcu.constraint_name constraint_name, kcu.column_name column_name, kcu.referenced_table_name referenced_table_name, kcu.referenced_column_name referenced_column_name, kcu.ordinal_position ordinal_position, kcu.table_name table_name, rc.delete_rule delete_rule, rc.update_rule update_rule FROM information_schema.key_column_usage AS kcu INNER JOIN information_schema.referential_constraints AS rc ON kcu.constraint_name = rc.constraint_name WHERE kcu.table_schema = ? AND rc.constraint_schema = ? AND kcu.referenced_column_name IS NOT NULL ORDER BY ordinal_position", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where 1 != 1", + "Query": "select kcu.constraint_name as constraint_name, kcu.column_name as column_name, kcu.referenced_table_name as referenced_table_name, kcu.referenced_column_name as referenced_column_name, kcu.ordinal_position as ordinal_position, kcu.table_name as table_name, rc.delete_rule as delete_rule, rc.update_rule as update_rule from information_schema.key_column_usage as kcu join information_schema.referential_constraints as rc on kcu.constraint_name = rc.constraint_name where kcu.table_schema = :__vtschemaname and rc.constraint_schema = :__vtschemaname and kcu.referenced_column_name is not null order by ordinal_position asc", + "SysTableTableSchema": "[:v1, :v2]" + } +} diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt index 4bb18995a80..99970fe9d1a 100644 --- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt +++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt @@ -379,8 +379,23 @@ "unsupported: this construct is not supported on sharded keyspace" # unsupported two predicates specifying the database for the same table if they are different +# will fail on run time but will pass on the planbuilder "SELECT cc.constraint_name AS 'name' FROM information_schema.check_constraints cc WHERE cc.constraint_schema = 'constraint_schema' AND cc.table_schema = 'a'" -"two predicates for specifying the database are not supported" +{ + "QueryType": "SELECT", + "Original": "SELECT cc.constraint_name AS 'name' FROM information_schema.check_constraints cc WHERE cc.constraint_schema = 'constraint_schema' AND cc.table_schema = 'a'", + "Instructions": { + "OperatorType": "Route", + "Variant": "SelectDBA", + "Keyspace": { + "Name": "main", + "Sharded": false + }, + "FieldQuery": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where 1 != 1", + "Query": "select cc.constraint_name as `name` from information_schema.check_constraints as cc where cc.constraint_schema = :__vtschemaname and cc.table_schema = :__vtschemaname", + "SysTableTableSchema": "[VARBINARY(\"constraint_schema\"), VARBINARY(\"a\")]" + } +} # create view with Cannot auto-resolve for cross-shard joins "create view user.view_a as select col from user join user_extra" From d3ff88b07182f4363f58834361716fe33ba23587 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Sun, 9 May 2021 21:44:16 +0530 Subject: [PATCH 152/310] System schema query predicate fix Backport of #8087 This is a combination of 4 commits. * add e2e test for system schema * add unit test for system schema issue * redirect to default route if not able to resolve the keyspace in case of information_schema query * update test with new error message Signed-off-by: Harshit Gangal Signed-off-by: Andres Taylor --- go/test/endtoend/vtgate/system_schema_test.go | 2 + go/vt/vtgate/engine/route.go | 5 +++ go/vt/vtgate/executor_select_test.go | 29 +++++++++++- go/vt/vtgate/vindexes/vschema.go | 7 ++- go/vt/vtgate/vindexes/vschema_test.go | 45 +++++++------------ go/vt/vtgate/vtgate_test.go | 6 +-- 6 files changed, 58 insertions(+), 36 deletions(-) diff --git a/go/test/endtoend/vtgate/system_schema_test.go b/go/test/endtoend/vtgate/system_schema_test.go index 71bb809142f..8e5c29f3b5f 100644 --- a/go/test/endtoend/vtgate/system_schema_test.go +++ b/go/test/endtoend/vtgate/system_schema_test.go @@ -78,6 +78,8 @@ func TestInformationSchemaQuery(t *testing.T) { assertResultIsEmpty(t, conn, "table_schema = 'PERFORMANCE_SCHEMA'") assertSingleRowIsReturned(t, conn, "table_schema = 'performance_schema' and table_name = 'users'", "performance_schema") assertResultIsEmpty(t, conn, "table_schema = 'performance_schema' and table_name = 'foo'") + assertSingleRowIsReturned(t, conn, "table_schema = 'vt_ks' and table_name = 't1'", "vt_ks") + assertSingleRowIsReturned(t, conn, "table_schema = 'ks' and table_name = 't1'", "vt_ks") } func assertResultIsEmpty(t *testing.T, conn *mysql.Conn, pre string) { diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go index 362bbd15c25..598d3e3af47 100644 --- a/go/vt/vtgate/engine/route.go +++ b/go/vt/vtgate/engine/route.go @@ -462,6 +462,11 @@ func (route *Route) routeInfoSchemaQuery(vcursor VCursor, bindVars map[string]*q if tableName != "" { rss, err := route.paramsRoutedTable(vcursor, bindVars, specifiedKS, tableName) if err != nil { + // Only if keyspace is not found in vschema, we try with default keyspace. + // As the in the table_schema predicates for a keyspace 'ks' it can contain 'vt_ks'. + if vterrors.Code(err) == vtrpcpb.Code_NOT_FOUND { + return defaultRoute() + } return nil, err } if rss != nil { diff --git a/go/vt/vtgate/executor_select_test.go b/go/vt/vtgate/executor_select_test.go index 2eb31930b34..99cb73273f4 100644 --- a/go/vt/vtgate/executor_select_test.go +++ b/go/vt/vtgate/executor_select_test.go @@ -69,8 +69,8 @@ func TestSelectDBA(t *testing.T) { require.NoError(t, err) wantQueries := []*querypb.BoundQuery{{Sql: query, BindVariables: map[string]*querypb.BindVariable{}}} utils.MustMatch(t, wantQueries, sbc1.Queries) - sbc1.Queries = nil + sbc1.Queries = nil query = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = 'performance_schema' AND table_name = 'foo'" _, err = executor.Execute(context.Background(), "TestSelectDBA", NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), @@ -84,6 +84,33 @@ func TestSelectDBA(t *testing.T) { }}} utils.MustMatch(t, wantQueries, sbc1.Queries) + sbc1.Queries = nil + query = "select 1 from information_schema.table_constraints where constraint_schema = 'vt_ks' and table_name = 'user'" + _, err = executor.Execute(context.Background(), "TestSelectDBA", + NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), + query, map[string]*querypb.BindVariable{}, + ) + require.NoError(t, err) + wantQueries = []*querypb.BoundQuery{{Sql: "select 1 from information_schema.table_constraints where constraint_schema = :__vtschemaname and table_name = :__vttablename", + BindVariables: map[string]*querypb.BindVariable{ + "__vtschemaname": sqltypes.StringBindVariable("vt_ks"), + "__vttablename": sqltypes.StringBindVariable("user"), + }}} + utils.MustMatch(t, wantQueries, sbc1.Queries) + + sbc1.Queries = nil + query = "select 1 from information_schema.table_constraints where constraint_schema = 'vt_ks'" + _, err = executor.Execute(context.Background(), "TestSelectDBA", + NewSafeSession(&vtgatepb.Session{TargetString: "TestExecutor"}), + query, map[string]*querypb.BindVariable{}, + ) + require.NoError(t, err) + wantQueries = []*querypb.BoundQuery{{Sql: "select 1 from information_schema.table_constraints where constraint_schema = :__vtschemaname", + BindVariables: map[string]*querypb.BindVariable{ + "__vtschemaname": sqltypes.StringBindVariable("vt_ks"), + }}} + utils.MustMatch(t, wantQueries, sbc1.Queries) + } func TestUnsharded(t *testing.T) { diff --git a/go/vt/vtgate/vindexes/vschema.go b/go/vt/vtgate/vindexes/vschema.go index 3054b611dde..7e5c4d70623 100644 --- a/go/vt/vtgate/vindexes/vschema.go +++ b/go/vt/vtgate/vindexes/vschema.go @@ -23,6 +23,9 @@ import ( "io/ioutil" "sort" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/vterrors" + "vitess.io/vitess/go/json2" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" @@ -481,7 +484,7 @@ func (vschema *VSchema) findTable(keyspace, tablename string) (*Table, error) { } ks, ok := vschema.Keyspaces[keyspace] if !ok { - return nil, fmt.Errorf("keyspace %s not found in vschema", keyspace) + return nil, vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "keyspace %s not found in vschema", keyspace) } table := ks.Tables[tablename] if table == nil { @@ -559,7 +562,7 @@ func (vschema *VSchema) FindVindex(keyspace, name string) (Vindex, error) { } ks, ok := vschema.Keyspaces[keyspace] if !ok { - return nil, fmt.Errorf("keyspace %s not found in vschema", keyspace) + return nil, vterrors.Errorf(vtrpcpb.Code_NOT_FOUND, "keyspace %s not found in vschema", keyspace) } return ks.Vindexes[name], nil } diff --git a/go/vt/vtgate/vindexes/vschema_test.go b/go/vt/vtgate/vindexes/vschema_test.go index 823b46f4e8c..0dc1782d47b 100644 --- a/go/vt/vtgate/vindexes/vschema_test.go +++ b/go/vt/vtgate/vindexes/vschema_test.go @@ -2156,33 +2156,24 @@ func TestFindTable(t *testing.T) { } vschema, _ := BuildVSchema(&input) _, err := vschema.FindTable("", "t1") - wantErr := "ambiguous table reference: t1" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } + require.EqualError(t, err, "ambiguous table reference: t1") + _, err = vschema.FindTable("", "none") - wantErr = "table none not found" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } - got, err := vschema.FindTable("", "ta") - if err != nil { - t.Error(err) - return - } + require.EqualError(t, err, "table none not found") + ta := &Table{ Name: sqlparser.NewTableIdent("ta"), Keyspace: &Keyspace{ Name: "ksa", }, } - if !reflect.DeepEqual(got, ta) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, ta) - } + got, err := vschema.FindTable("", "ta") + require.NoError(t, err) + require.Equal(t, ta, got) + got, _ = vschema.FindTable("ksa", "ta") - if !reflect.DeepEqual(got, ta) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, ta) - } + require.Equal(t, ta, got) + none := &Table{ Name: sqlparser.NewTableIdent("none"), Keyspace: &Keyspace{ @@ -2190,19 +2181,13 @@ func TestFindTable(t *testing.T) { }, } got, _ = vschema.FindTable("ksa", "none") - if !reflect.DeepEqual(got, none) { - t.Errorf("FindTable(\"t1a\"): %+v, want %+v", got, none) - } + require.Equal(t, none, got) + _, err = vschema.FindTable("ksb", "none") - wantErr = "table none not found" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } + require.EqualError(t, err, "table none not found") + _, err = vschema.FindTable("none", "aa") - wantErr = "keyspace none not found in vschema" - if err == nil || err.Error() != wantErr { - t.Errorf("FindTable(\"\"): %v, want %s", err, wantErr) - } + require.EqualError(t, err, "keyspace none not found in vschema") } func TestFindTableOrVindex(t *testing.T) { diff --git a/go/vt/vtgate/vtgate_test.go b/go/vt/vtgate/vtgate_test.go index ff465ff4931..01ddb499c0a 100644 --- a/go/vt/vtgate/vtgate_test.go +++ b/go/vt/vtgate/vtgate_test.go @@ -21,6 +21,8 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" + "context" "github.com/golang/protobuf/proto" @@ -140,9 +142,7 @@ func TestVTGateExecuteWithKeyspaceShard(t *testing.T) { nil, ) want := "vtgate: : keyspace invalid_keyspace not found in vschema" - if err == nil || err.Error() != want { - t.Errorf("Execute: %v, want %s", err, want) - } + assert.EqualError(t, err, want) // Valid keyspace/shard. _, qr, err = rpcVTGate.Execute( From 7e448aa5515e1788d0fb717c8504d29cb8eed954 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 10 May 2021 17:09:51 +0530 Subject: [PATCH 153/310] Queryservice fix Backport of #8089 This is a combination of 3 commits. * remove precheck of tablet serving and target * remove the additional logic and return error if queryservice not found to serve query * fix test as per new change Signed-off-by: Harshit Gangal Signed-off-by: Andres Taylor --- go/vt/discovery/fake_healthcheck.go | 7 --- go/vt/discovery/healthcheck.go | 8 --- go/vt/vtgate/legacy_scatter_conn_test.go | 25 ++++---- go/vt/vtgate/scatter_conn.go | 18 +----- go/vt/vtgate/scatter_conn_test.go | 16 +++-- go/vt/vttablet/sandboxconn/sandboxconn.go | 71 ++++++++++++++++++++--- 6 files changed, 89 insertions(+), 56 deletions(-) diff --git a/go/vt/discovery/fake_healthcheck.go b/go/vt/discovery/fake_healthcheck.go index bbb1ec98baa..4407ae50ebc 100644 --- a/go/vt/discovery/fake_healthcheck.go +++ b/go/vt/discovery/fake_healthcheck.go @@ -150,13 +150,6 @@ func (fhc *FakeHealthCheck) TabletConnection(alias *topodatapb.TabletAlias, targ defer fhc.mu.RUnlock() for _, item := range fhc.items { if proto.Equal(alias, item.ts.Tablet.Alias) { - if !item.ts.Serving { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) - } - if target != nil && !proto.Equal(item.ts.Target, target) { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, item.ts.Target, target) - } - return item.ts.Conn, nil } } diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index 90a64a788aa..1a3670d88df 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -45,8 +45,6 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" - "vitess.io/vitess/go/flagutil" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/log" @@ -700,12 +698,6 @@ func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias, target //TODO: test that throws this error return nil, vterrors.Errorf(vtrpc.Code_NOT_FOUND, "tablet: %v is either down or nonexistent", alias) } - if !thc.Serving { - return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, vterrors.NotServing) - } - if target != nil && !proto.Equal(thc.Target, target) { - return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, thc.Target, target) - } return thc.Connection(), nil } diff --git a/go/vt/vtgate/legacy_scatter_conn_test.go b/go/vt/vtgate/legacy_scatter_conn_test.go index 9b3679ac3ae..aaac0c20e31 100644 --- a/go/vt/vtgate/legacy_scatter_conn_test.go +++ b/go/vt/vtgate/legacy_scatter_conn_test.go @@ -17,28 +17,26 @@ limitations under the License. package vtgate import ( + "context" "fmt" "reflect" "strings" "testing" - "vitess.io/vitess/go/test/utils" - "github.com/stretchr/testify/assert" - - "context" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vterrors" + querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/srvtopo" - "vitess.io/vitess/go/vt/vterrors" ) // This file uses the sandbox_test framework. @@ -391,15 +389,17 @@ func TestMultiExecs(t *testing.T) { rss := []*srvtopo.ResolvedShard{ { Target: &querypb.Target{ - Keyspace: "TestMultiExecs", - Shard: "0", + Keyspace: "TestMultiExecs", + Shard: "0", + TabletType: topodatapb.TabletType_REPLICA, }, Gateway: sbc0, }, { Target: &querypb.Target{ - Keyspace: "TestMultiExecs", - Shard: "1", + Keyspace: "TestMultiExecs", + Shard: "1", + TabletType: topodatapb.TabletType_REPLICA, }, Gateway: sbc1, }, @@ -419,7 +419,8 @@ func TestMultiExecs(t *testing.T) { }, } - _, _ = sc.ExecuteMultiShard(ctx, rss, queries, NewSafeSession(nil), false, false) + _, err := sc.ExecuteMultiShard(ctx, rss, queries, NewSafeSession(nil), false, false) + require.NoError(t, vterrors.Aggregate(err)) if len(sbc0.Queries) == 0 || len(sbc1.Queries) == 0 { t.Fatalf("didn't get expected query") } diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index e8d1da842e5..beea97c3d84 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -221,23 +221,7 @@ func (stc *ScatterConn) ExecuteMultiShard( qs, err = getQueryService(rs, info) if err != nil { - // an error here could mean that the tablet we were targeting earlier has changed type. - // if we have a transaction, we'll have to fail, but if we only had a reserved connection, - // we can create a new reserved connection to a new tablet that is on the right shard - // and has the right type - switch info.actionNeeded { - case nothing: - info.actionNeeded = reserve - case begin: - info.actionNeeded = reserveBegin - default: - return nil, err - } - retry := checkAndResetShardSession(info, err, session) - if retry != newQS { - return nil, err - } - qs = rs.Gateway + return nil, err } retryRequest := func(exec func()) { diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index a0797f89f23..2e820ed2a09 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -351,12 +351,15 @@ func TestReservedConnFail(t *testing.T) { }) sbc0Th := ths[0] sbc0Th.Serving = false + sbc0.NotServing = true sbc0Rep := hc.AddTestTablet("aa", "0", 2, keyspace, "0", topodatapb.TabletType_REPLICA, true, 1, nil) sbc0.Queries = nil + sbc0.ExecCount.Set(0) _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) - assert.Equal(t, 0, len(sbc0.Queries), "no attempt should be made as the tablet is not serving") - assert.Equal(t, 1, len(sbc0Rep.Queries), "first attempt should pass as it is healthy") + assert.EqualValues(t, 1, sbc0.ExecCount.Get(), "first attempt should be made on original tablet") + assert.EqualValues(t, 0, len(sbc0.Queries), "no query should be executed on it") + assert.Equal(t, 1, len(sbc0Rep.Queries), "this attempt on new healthy tablet should pass") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") @@ -376,12 +379,17 @@ func TestReservedConnFail(t *testing.T) { Shard: tablet0Rep.GetShard(), TabletType: topodatapb.TabletType_SPARE, } + sbc0Rep.Tablet().Type = topodatapb.TabletType_SPARE sbc0Th.Serving = true + sbc0.NotServing = false + sbc0.ExecCount.Set(0) sbc0Rep.Queries = nil + sbc0Rep.ExecCount.Set(0) _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) - assert.Equal(t, 1, len(sbc0.Queries), "first attempt should pass as it is healthy and matches the target") - assert.Equal(t, 0, len(sbc0Rep.Queries), " no attempt should be made as the tablet target is changed") + assert.EqualValues(t, 1, sbc0Rep.ExecCount.Get(), "first attempt should be made on the changed tablet type") + assert.EqualValues(t, 0, len(sbc0Rep.Queries), "no query should be executed on it") + assert.Equal(t, 1, len(sbc0.Queries), "this attempt should pass as it is on new healthy tablet and matches the target") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 035ca529fcd..313d6d0f955 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -22,6 +22,8 @@ import ( "fmt" "sync" + "vitess.io/vitess/go/vt/sqlparser" + "context" "vitess.io/vitess/go/sqltypes" @@ -108,6 +110,8 @@ type SandboxConn struct { // this error will only happen once EphemeralShardErr error + + NotServing bool } var _ queryservice.QueryService = (*SandboxConn)(nil) // compile-time interface check @@ -147,6 +151,12 @@ func (sbc *SandboxConn) Execute(ctx context.Context, target *querypb.Target, que sbc.execMu.Lock() defer sbc.execMu.Unlock() sbc.ExecCount.Add(1) + if sbc.NotServing { + return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) + } + if sbc.tablet.Type != target.TabletType { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: %v, want: %v", vterrors.WrongTablet, target.TabletType, sbc.tablet.Type) + } bv := make(map[string]*querypb.BindVariable) for k, v := range bindVars { bv[k] = v @@ -159,7 +169,8 @@ func (sbc *SandboxConn) Execute(ctx context.Context, target *querypb.Target, que if err := sbc.getError(); err != nil { return nil, err } - return sbc.getNextResult(), nil + parse, _ := sqlparser.Parse(query) + return sbc.getNextResult(parse), nil } // ExecuteBatch is part of the QueryService interface. @@ -174,8 +185,9 @@ func (sbc *SandboxConn) ExecuteBatch(ctx context.Context, target *querypb.Target sbc.BatchQueries = append(sbc.BatchQueries, queries) sbc.Options = append(sbc.Options, options) result := make([]sqltypes.Result, 0, len(queries)) - for range queries { - result = append(result, *(sbc.getNextResult())) + for _, query := range queries { + parse, _ := sqlparser.Parse(query.Sql) + result = append(result, *(sbc.getNextResult(parse))) } return result, nil } @@ -198,14 +210,15 @@ func (sbc *SandboxConn) StreamExecute(ctx context.Context, target *querypb.Targe sbc.sExecMu.Unlock() return err } + ast, _ := sqlparser.Parse(query) if sbc.results == nil { - nextRs := sbc.getNextResult() + nextRs := sbc.getNextResult(ast) sbc.sExecMu.Unlock() return callback(nextRs) } for len(sbc.results) > 0 { - nextRs := sbc.getNextResult() + nextRs := sbc.getNextResult(ast) sbc.sExecMu.Unlock() err := callback(nextRs) if err != nil { @@ -378,7 +391,7 @@ func (sbc *SandboxConn) MessageStream(ctx context.Context, target *querypb.Targe if err := sbc.getError(); err != nil { return err } - r := sbc.getNextResult() + r := sbc.getNextResult(nil) if r == nil { return nil } @@ -505,13 +518,55 @@ func (sbc *SandboxConn) Tablet() *topodatapb.Tablet { return sbc.tablet } -func (sbc *SandboxConn) getNextResult() *sqltypes.Result { +func (sbc *SandboxConn) getNextResult(stmt sqlparser.Statement) *sqltypes.Result { if len(sbc.results) != 0 { r := sbc.results[0] sbc.results = sbc.results[1:] return r } - return SingleRowResult + if stmt == nil { + // if we didn't get a valid query, we'll assume we need a SELECT + return getSingleRowResult() + } + switch stmt.(type) { + case *sqlparser.Select, + *sqlparser.Union, + *sqlparser.Show, + *sqlparser.Explain, + *sqlparser.OtherRead: + return getSingleRowResult() + case *sqlparser.Set, + sqlparser.DDLStatement, + *sqlparser.AlterVschema, + *sqlparser.Use, + *sqlparser.OtherAdmin, + *sqlparser.SetTransaction, + *sqlparser.Savepoint, + *sqlparser.SRollback, + *sqlparser.Release: + return &sqltypes.Result{} + } + + // for everything else we fake a single row being affected + return &sqltypes.Result{RowsAffected: 1} +} + +// getSingleRowResult is used to get a SingleRowResult but it creates separate fields because some tests change the fields +// If these fields are not created separately then the constants value also changes which leads to some other tests failing later +func getSingleRowResult() *sqltypes.Result { + singleRowResult := &sqltypes.Result{ + InsertID: SingleRowResult.InsertID, + Rows: SingleRowResult.Rows, + } + + for _, field := range SingleRowResult.Fields { + singleRowResult.Fields = append(singleRowResult.Fields, &querypb.Field{ + Name: field.Name, + Type: field.Type, + }) + } + + return singleRowResult } //StringQueries returns the queries executed as a slice of strings From 96fb6af521c990d0808b556a5f94c431980b6b26 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 10 May 2021 17:09:51 +0530 Subject: [PATCH 154/310] Queryservice fix Backport of #8089 This is a combination of 3 commits. * remove precheck of tablet serving and target * remove the additional logic and return error if queryservice not found to serve query * fix test as per new change Signed-off-by: Harshit Gangal Signed-off-by: Andres Taylor --- go/vt/discovery/fake_healthcheck.go | 7 ------- go/vt/discovery/healthcheck.go | 8 -------- go/vt/vtgate/legacy_scatter_conn_test.go | 25 ++++++++++++----------- go/vt/vtgate/scatter_conn.go | 18 +--------------- go/vt/vtgate/scatter_conn_test.go | 16 +++++++++++---- go/vt/vttablet/sandboxconn/sandboxconn.go | 17 +++++++++++---- 6 files changed, 39 insertions(+), 52 deletions(-) diff --git a/go/vt/discovery/fake_healthcheck.go b/go/vt/discovery/fake_healthcheck.go index bbb1ec98baa..4407ae50ebc 100644 --- a/go/vt/discovery/fake_healthcheck.go +++ b/go/vt/discovery/fake_healthcheck.go @@ -150,13 +150,6 @@ func (fhc *FakeHealthCheck) TabletConnection(alias *topodatapb.TabletAlias, targ defer fhc.mu.RUnlock() for _, item := range fhc.items { if proto.Equal(alias, item.ts.Tablet.Alias) { - if !item.ts.Serving { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) - } - if target != nil && !proto.Equal(item.ts.Target, target) { - return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, item.ts.Target, target) - } - return item.ts.Conn, nil } } diff --git a/go/vt/discovery/healthcheck.go b/go/vt/discovery/healthcheck.go index b21cdac44a0..83a4048fe87 100644 --- a/go/vt/discovery/healthcheck.go +++ b/go/vt/discovery/healthcheck.go @@ -45,8 +45,6 @@ import ( "sync" "time" - "github.com/golang/protobuf/proto" - "vitess.io/vitess/go/flagutil" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/log" @@ -711,12 +709,6 @@ func (hc *HealthCheckImpl) TabletConnection(alias *topodata.TabletAlias, target //TODO: test that throws this error return nil, vterrors.Errorf(vtrpc.Code_NOT_FOUND, "tablet: %v is either down or nonexistent", alias) } - if !thc.Serving { - return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, vterrors.NotServing) - } - if target != nil && !proto.Equal(thc.Target, target) { - return nil, vterrors.Errorf(vtrpc.Code_FAILED_PRECONDITION, "%s: target mismatch %v vs %v", vterrors.WrongTablet, thc.Target, target) - } return thc.Connection(), nil } diff --git a/go/vt/vtgate/legacy_scatter_conn_test.go b/go/vt/vtgate/legacy_scatter_conn_test.go index fa18f27bd17..4c48cd2bf04 100644 --- a/go/vt/vtgate/legacy_scatter_conn_test.go +++ b/go/vt/vtgate/legacy_scatter_conn_test.go @@ -17,28 +17,26 @@ limitations under the License. package vtgate import ( + "context" "fmt" "reflect" "strings" "testing" - "vitess.io/vitess/go/test/utils" - "github.com/stretchr/testify/assert" - - "context" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/test/utils" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" + "vitess.io/vitess/go/vt/srvtopo" + "vitess.io/vitess/go/vt/vterrors" + querypb "vitess.io/vitess/go/vt/proto/query" topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtgatepb "vitess.io/vitess/go/vt/proto/vtgate" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/srvtopo" - "vitess.io/vitess/go/vt/vterrors" ) // This file uses the sandbox_test framework. @@ -387,15 +385,17 @@ func TestMultiExecs(t *testing.T) { rss := []*srvtopo.ResolvedShard{ { Target: &querypb.Target{ - Keyspace: "TestMultiExecs", - Shard: "0", + Keyspace: "TestMultiExecs", + Shard: "0", + TabletType: topodatapb.TabletType_REPLICA, }, Gateway: sbc0, }, { Target: &querypb.Target{ - Keyspace: "TestMultiExecs", - Shard: "1", + Keyspace: "TestMultiExecs", + Shard: "1", + TabletType: topodatapb.TabletType_REPLICA, }, Gateway: sbc1, }, @@ -415,7 +415,8 @@ func TestMultiExecs(t *testing.T) { }, } - _, _ = sc.ExecuteMultiShard(ctx, rss, queries, NewSafeSession(nil), false, false) + _, err := sc.ExecuteMultiShard(ctx, rss, queries, NewSafeSession(nil), false, false) + require.NoError(t, vterrors.Aggregate(err)) if len(sbc0.Queries) == 0 || len(sbc1.Queries) == 0 { t.Fatalf("didn't get expected query") } diff --git a/go/vt/vtgate/scatter_conn.go b/go/vt/vtgate/scatter_conn.go index ea8e27b26c9..1e4b0600241 100644 --- a/go/vt/vtgate/scatter_conn.go +++ b/go/vt/vtgate/scatter_conn.go @@ -221,23 +221,7 @@ func (stc *ScatterConn) ExecuteMultiShard( qs, err = getQueryService(rs, info) if err != nil { - // an error here could mean that the tablet we were targeting earlier has changed type. - // if we have a transaction, we'll have to fail, but if we only had a reserved connection, - // we can create a new reserved connection to a new tablet that is on the right shard - // and has the right type - switch info.actionNeeded { - case nothing: - info.actionNeeded = reserve - case begin: - info.actionNeeded = reserveBegin - default: - return nil, err - } - retry := checkAndResetShardSession(info, err, session) - if retry != newQS { - return nil, err - } - qs = rs.Gateway + return nil, err } retryRequest := func(exec func()) { diff --git a/go/vt/vtgate/scatter_conn_test.go b/go/vt/vtgate/scatter_conn_test.go index 4a5a8dcd8d5..ff1c4af62bc 100644 --- a/go/vt/vtgate/scatter_conn_test.go +++ b/go/vt/vtgate/scatter_conn_test.go @@ -351,12 +351,15 @@ func TestReservedConnFail(t *testing.T) { }) sbc0Th := ths[0] sbc0Th.Serving = false + sbc0.NotServing = true sbc0Rep := hc.AddTestTablet("aa", "0", 2, keyspace, "0", topodatapb.TabletType_REPLICA, true, 1, nil) sbc0.Queries = nil + sbc0.ExecCount.Set(0) _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) - assert.Equal(t, 0, len(sbc0.Queries), "no attempt should be made as the tablet is not serving") - assert.Equal(t, 1, len(sbc0Rep.Queries), "first attempt should pass as it is healthy") + assert.EqualValues(t, 1, sbc0.ExecCount.Get(), "first attempt should be made on original tablet") + assert.EqualValues(t, 0, len(sbc0.Queries), "no query should be executed on it") + assert.Equal(t, 1, len(sbc0Rep.Queries), "this attempt on new healthy tablet should pass") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") @@ -376,12 +379,17 @@ func TestReservedConnFail(t *testing.T) { Shard: tablet0Rep.GetShard(), TabletType: topodatapb.TabletType_SPARE, } + sbc0Rep.Tablet().Type = topodatapb.TabletType_SPARE sbc0Th.Serving = true + sbc0.NotServing = false + sbc0.ExecCount.Set(0) sbc0Rep.Queries = nil + sbc0Rep.ExecCount.Set(0) _ = executeOnShardsReturnsErr(t, res, keyspace, sc, session, destinations) - assert.Equal(t, 1, len(sbc0.Queries), "first attempt should pass as it is healthy and matches the target") - assert.Equal(t, 0, len(sbc0Rep.Queries), " no attempt should be made as the tablet target is changed") + assert.EqualValues(t, 1, sbc0Rep.ExecCount.Get(), "first attempt should be made on the changed tablet type") + assert.EqualValues(t, 0, len(sbc0Rep.Queries), "no query should be executed on it") + assert.Equal(t, 1, len(sbc0.Queries), "this attempt should pass as it is on new healthy tablet and matches the target") require.Equal(t, 1, len(session.ShardSessions)) assert.NotEqual(t, oldRId, session.Session.ShardSessions[0].ReservedId, "should have recreated a reserved connection since the last connection was lost") assert.NotEqual(t, oldAlias, session.Session.ShardSessions[0].TabletAlias, "tablet alias should have changed as this is a different tablet") diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 3fff1352aec..c0c7d740e27 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -114,6 +114,8 @@ type SandboxConn struct { // this error will only happen once EphemeralShardErr error + + NotServing bool } var _ queryservice.QueryService = (*SandboxConn)(nil) // compile-time interface check @@ -153,6 +155,12 @@ func (sbc *SandboxConn) Execute(ctx context.Context, target *querypb.Target, que sbc.execMu.Lock() defer sbc.execMu.Unlock() sbc.ExecCount.Add(1) + if sbc.NotServing { + return nil, vterrors.New(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.NotServing) + } + if sbc.tablet.Type != target.TabletType { + return nil, vterrors.Errorf(vtrpcpb.Code_FAILED_PRECONDITION, "%s: %v, want: %v", vterrors.WrongTablet, target.TabletType, sbc.tablet.Type) + } bv := make(map[string]*querypb.BindVariable) for k, v := range bindVars { bv[k] = v @@ -557,6 +565,11 @@ func (sbc *SandboxConn) Tablet() *topodatapb.Tablet { return sbc.tablet } +// ChangeTabletType changes the tablet type. +func (sbc *SandboxConn) ChangeTabletType(typ topodatapb.TabletType) { + sbc.tablet.Type = typ +} + func (sbc *SandboxConn) getNextResult(stmt sqlparser.Statement) *sqltypes.Result { if len(sbc.results) != 0 { r := sbc.results[0] @@ -596,10 +609,6 @@ func (sbc *SandboxConn) setTxReservedID(transactionID int64, reservedID int64) { sbc.txIDToRID[transactionID] = reservedID } -func (sbc *SandboxConn) ResultsAllFetched() bool { - return len(sbc.results) == 0 -} - func (sbc *SandboxConn) getTxReservedID(txID int64) int64 { sbc.mapMu.Lock() defer sbc.mapMu.Unlock() From c974aaa5a00401146e469211968caa3eee2668cf Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 16 Mar 2021 17:58:42 -0700 Subject: [PATCH 155/310] restore: check disable_active_reparents properly before waiting for position update Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/restore.go | 2 +- go/vt/wrangler/testlib/backup_test.go | 204 ++++++++++++++++++++++++ 2 files changed, 205 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index 790b41fed65..d85aa45f5cc 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -497,7 +497,7 @@ func (tm *TabletManager) startReplication(ctx context.Context, pos mysql.Positio // If active reparents are disabled, we don't restart replication. So it makes no sense to wait for an update on the replica. // Return immediately. - if !*mysqlctl.DisableActiveReparents { + if *mysqlctl.DisableActiveReparents { return nil } // wait for reliable seconds behind master diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index c33437a4c1d..8399102b959 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -245,6 +245,210 @@ func TestBackupRestore(t *testing.T) { assert.True(t, master.FakeMysqlDaemon.Running) } +// TestBackupRestoreLagged tests the changes made in https://github.com/vitessio/vitess/pull/5000 +// While doing a backup or a restore, we wait for a change of the replica's position before completing the action +// This is because otherwise SecondsBehindMaster is not accurate and the tablet may go into SERVING when it should not +func TestBackupRestoreLagged(t *testing.T) { + delay := discovery.GetTabletPickerRetryDelay() + defer func() { + discovery.SetTabletPickerRetryDelay(delay) + }() + discovery.SetTabletPickerRetryDelay(5 * time.Millisecond) + + // Initialize our environment + ctx := context.Background() + db := fakesqldb.New(t) + defer db.Close() + ts := memorytopo.NewServer("cell1", "cell2") + wr := wrangler.New(logutil.NewConsoleLogger(), ts, tmclient.NewTabletManagerClient()) + vp := NewVtctlPipe(t, ts) + defer vp.Close() + + // Set up mock query results. + db.AddQuery("CREATE DATABASE IF NOT EXISTS _vt", &sqltypes.Result{}) + db.AddQuery("BEGIN", &sqltypes.Result{}) + db.AddQuery("COMMIT", &sqltypes.Result{}) + db.AddQueryPattern(`SET @@session\.sql_log_bin = .*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.shard_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`CREATE TABLE IF NOT EXISTS _vt\.local_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`ALTER TABLE _vt\.local_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`ALTER TABLE _vt\.shard_metadata .*`, &sqltypes.Result{}) + db.AddQueryPattern(`UPDATE _vt\.local_metadata SET db_name=.*`, &sqltypes.Result{}) + db.AddQueryPattern(`UPDATE _vt\.shard_metadata SET db_name=.*`, &sqltypes.Result{}) + db.AddQueryPattern(`INSERT INTO _vt\.local_metadata .*`, &sqltypes.Result{}) + + // Initialize our temp dirs + root, err := ioutil.TempDir("", "backuptest") + require.NoError(t, err) + defer os.RemoveAll(root) + + // Initialize BackupStorage + fbsRoot := path.Join(root, "fbs") + *filebackupstorage.FileBackupStorageRoot = fbsRoot + *backupstorage.BackupStorageImplementation = "file" + + // Initialize the fake mysql root directories + sourceInnodbDataDir := path.Join(root, "source_innodb_data") + sourceInnodbLogDir := path.Join(root, "source_innodb_log") + sourceDataDir := path.Join(root, "source_data") + sourceDataDbDir := path.Join(sourceDataDir, "vt_db") + for _, s := range []string{sourceInnodbDataDir, sourceInnodbLogDir, sourceDataDbDir} { + require.NoError(t, os.MkdirAll(s, os.ModePerm)) + } + require.NoError(t, ioutil.WriteFile(path.Join(sourceInnodbDataDir, "innodb_data_1"), []byte("innodb data 1 contents"), os.ModePerm)) + require.NoError(t, ioutil.WriteFile(path.Join(sourceInnodbLogDir, "innodb_log_1"), []byte("innodb log 1 contents"), os.ModePerm)) + require.NoError(t, ioutil.WriteFile(path.Join(sourceDataDbDir, "db.opt"), []byte("db opt file"), os.ModePerm)) + + // create a master tablet, set its master position + master := NewFakeTablet(t, wr, "cell1", 0, topodatapb.TabletType_MASTER, db) + master.FakeMysqlDaemon.ReadOnly = false + master.FakeMysqlDaemon.Replicating = false + master.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + + // start master so that replica can fetch master position from it + master.StartActionLoop(t, wr) + defer master.StopActionLoop(t) + + // create a single tablet, set it up so we can do backups + // set its position same as that of master so that backup doesn't wait for catchup + sourceTablet := NewFakeTablet(t, wr, "cell1", 1, topodatapb.TabletType_REPLICA, db) + sourceTablet.FakeMysqlDaemon.ReadOnly = true + sourceTablet.FakeMysqlDaemon.Replicating = true + sourceTablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 456, + }, + }, + } + sourceTablet.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "START SLAVE", + } + sourceTablet.StartActionLoop(t, wr) + defer sourceTablet.StopActionLoop(t) + + sourceTablet.TM.Cnf = &mysqlctl.Mycnf{ + DataDir: sourceDataDir, + InnodbDataHomeDir: sourceInnodbDataDir, + InnodbLogGroupHomeDir: sourceInnodbLogDir, + } + + timer := time.NewTicker(1 * time.Second) + go func(tablet *FakeTablet) { + <-timer.C + tablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + }(sourceTablet) + + errCh := make(chan error, 1) + go func(ctx context.Context, tablet *FakeTablet) { + errCh <- vp.Run([]string{"Backup", topoproto.TabletAliasString(tablet.Tablet.Alias)}) + }(ctx, sourceTablet) + + timer2 := time.NewTicker(5 * time.Second) + select { + case err := <-errCh: + require.Nil(t, err) + // verify the full status + // verify the full status + require.NoError(t, sourceTablet.FakeMysqlDaemon.CheckSuperQueryList()) + assert.True(t, sourceTablet.FakeMysqlDaemon.Replicating) + assert.True(t, sourceTablet.FakeMysqlDaemon.Running) + assert.Equal(t, master.FakeMysqlDaemon.CurrentMasterPosition, sourceTablet.FakeMysqlDaemon.CurrentMasterPosition) + case <-timer2.C: + require.FailNow(t, "Backup timed out") + } + + // create a destination tablet, set it up so we can do restores + destTablet := NewFakeTablet(t, wr, "cell1", 2, topodatapb.TabletType_REPLICA, db) + destTablet.FakeMysqlDaemon.ReadOnly = true + destTablet.FakeMysqlDaemon.Replicating = true + destTablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 456, + }, + }, + } + destTablet.FakeMysqlDaemon.ExpectedExecuteSuperQueryList = []string{ + "STOP SLAVE", + "RESET SLAVE ALL", + "FAKE SET SLAVE POSITION", + "FAKE SET MASTER", + "START SLAVE", + } + destTablet.FakeMysqlDaemon.FetchSuperQueryMap = map[string]*sqltypes.Result{ + "SHOW DATABASES": {}, + } + destTablet.FakeMysqlDaemon.SetReplicationPositionPos = destTablet.FakeMysqlDaemon.CurrentMasterPosition + destTablet.FakeMysqlDaemon.SetMasterInput = topoproto.MysqlAddr(master.Tablet) + + destTablet.StartActionLoop(t, wr) + defer destTablet.StopActionLoop(t) + + destTablet.TM.Cnf = &mysqlctl.Mycnf{ + DataDir: sourceDataDir, + InnodbDataHomeDir: sourceInnodbDataDir, + InnodbLogGroupHomeDir: sourceInnodbLogDir, + BinLogPath: path.Join(root, "bin-logs/filename_prefix"), + RelayLogPath: path.Join(root, "relay-logs/filename_prefix"), + RelayLogIndexPath: path.Join(root, "relay-log.index"), + RelayLogInfoPath: path.Join(root, "relay-log.info"), + } + + timer = time.NewTicker(1 * time.Second) + go func(tablet *FakeTablet) { + <-timer.C + tablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + } + }(destTablet) + + errCh = make(chan error, 1) + go func(ctx context.Context, tablet *FakeTablet) { + errCh <- tablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */) + }(ctx, destTablet) + + timer2 = time.NewTicker(5 * time.Second) + select { + case err := <-errCh: + require.Nil(t, err) + // verify the full status + require.NoError(t, destTablet.FakeMysqlDaemon.CheckSuperQueryList(), "destTablet.FakeMysqlDaemon.CheckSuperQueryList failed") + assert.True(t, destTablet.FakeMysqlDaemon.Replicating) + assert.True(t, destTablet.FakeMysqlDaemon.Running) + assert.Equal(t, master.FakeMysqlDaemon.CurrentMasterPosition, destTablet.FakeMysqlDaemon.CurrentMasterPosition) + case <-timer2.C: + require.FailNow(t, "Restore timed out") + } +} + func TestRestoreUnreachableMaster(t *testing.T) { delay := discovery.GetTabletPickerRetryDelay() defer func() { From 150f28139ba941b22f0bcb8b96a705a05c223130 Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 16 Mar 2021 19:06:42 -0700 Subject: [PATCH 156/310] restore: call orc.EndMaintenance only if there is no error Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/restore.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/restore.go b/go/vt/vttablet/tabletmanager/restore.go index d85aa45f5cc..818c8d162c1 100644 --- a/go/vt/vttablet/tabletmanager/restore.go +++ b/go/vt/vttablet/tabletmanager/restore.go @@ -89,6 +89,9 @@ func (tm *TabletManager) RestoreData(ctx context.Context, logger logutil.Logger, } }() err := tm.restoreDataLocked(ctx, logger, waitForBackupInterval, deleteBeforeRestore) + if err != nil { + return err + } // Tell Orchestrator we're no longer stopped on purpose. // Do this in the background, as it's best-effort. go func() { @@ -99,7 +102,7 @@ func (tm *TabletManager) RestoreData(ctx context.Context, logger logutil.Logger, log.Warningf("Orchestrator EndMaintenance failed: %v", err) } }() - return err + return nil } func (tm *TabletManager) restoreDataLocked(ctx context.Context, logger logutil.Logger, waitForBackupInterval time.Duration, deleteBeforeRestore bool) error { From 8fd2b640f52b2c9b11f1e90f27997db7f7c676a0 Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 16 Mar 2021 19:07:04 -0700 Subject: [PATCH 157/310] backup: call orc.EndMaintenance only if there is no error Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/rpc_backup.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_backup.go b/go/vt/vttablet/tabletmanager/rpc_backup.go index 683d69b2064..caaf7107790 100644 --- a/go/vt/vttablet/tabletmanager/rpc_backup.go +++ b/go/vt/vttablet/tabletmanager/rpc_backup.go @@ -133,17 +133,18 @@ func (tm *TabletManager) Backup(ctx context.Context, concurrency int, logger log l.Errorf("mysql backup command returned error: %v", returnErr) } returnErr = err + } else { + // Tell Orchestrator we're no longer stopped on purpose. + // Do this in the background, as it's best-effort. + go func() { + if tm.orc == nil { + return + } + if err := tm.orc.EndMaintenance(tm.Tablet()); err != nil { + logger.Warningf("Orchestrator EndMaintenance failed: %v", err) + } + }() } - // Tell Orchestrator we're no longer stopped on purpose. - // Do this in the background, as it's best-effort. - go func() { - if tm.orc == nil { - return - } - if err := tm.orc.EndMaintenance(tm.Tablet()); err != nil { - logger.Warningf("Orchestrator EndMaintenance failed: %v", err) - } - }() } return returnErr From 5db56670e0b1cb9d1cd938d8addd6bde89f598eb Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 16 Mar 2021 19:07:38 -0700 Subject: [PATCH 158/310] replication: call orc.EndMaintenance in UndoDemoteMaster Signed-off-by: deepthi --- go/vt/vttablet/tabletmanager/rpc_replication.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 348832974bc..eeb08050009 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -462,7 +462,16 @@ func (tm *TabletManager) UndoDemoteMaster(ctx context.Context) error { if err := tm.QueryServiceControl.SetServingType(tablet.Type, logutil.ProtoToTime(tablet.MasterTermStartTime), true, ""); err != nil { return vterrors.Wrap(err, "SetServingType(serving=true) failed") } - + // Tell Orchestrator we're no longer stopped on purpose. + // Do this in the background, as it's best-effort. + go func() { + if tm.orc == nil { + return + } + if err := tm.orc.EndMaintenance(tm.Tablet()); err != nil { + log.Warningf("Orchestrator EndMaintenance failed: %v", err) + } + }() return nil } From 320376d54b249912842fb9f209b8215770210017 Mon Sep 17 00:00:00 2001 From: deepthi Date: Tue, 16 Mar 2021 19:54:00 -0700 Subject: [PATCH 159/310] tests: add mutex to FakeMysqlDaemon Signed-off-by: deepthi --- .../fakemysqldaemon/fakemysqldaemon.go | 11 ++++ go/vt/wrangler/testlib/backup_test.go | 52 +++++++++---------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go index 58502a90d62..9d2fa9ef6da 100644 --- a/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go +++ b/go/vt/mysqlctl/fakemysqldaemon/fakemysqldaemon.go @@ -20,6 +20,7 @@ import ( "fmt" "reflect" "strings" + "sync" "time" "context" @@ -39,6 +40,7 @@ import ( // FakeMysqlDaemon implements MysqlDaemon and allows the user to fake // everything. type FakeMysqlDaemon struct { + mu sync.Mutex // db is the fake SQL DB we may use for some queries. db *fakesqldb.DB @@ -248,11 +250,20 @@ func (fmd *FakeMysqlDaemon) GetMysqlPort() (int32, error) { return fmd.MysqlPort.Get(), nil } +// CurrentMasterPositionLocked is thread-safe +func (fmd *FakeMysqlDaemon) CurrentMasterPositionLocked(pos mysql.Position) { + fmd.mu.Lock() + defer fmd.mu.Unlock() + fmd.CurrentMasterPosition = pos +} + // ReplicationStatus is part of the MysqlDaemon interface func (fmd *FakeMysqlDaemon) ReplicationStatus() (mysql.ReplicationStatus, error) { if fmd.ReplicationStatusError != nil { return mysql.ReplicationStatus{}, fmd.ReplicationStatusError } + fmd.mu.Lock() + defer fmd.mu.Unlock() return mysql.ReplicationStatus{ Position: fmd.CurrentMasterPosition, FilePosition: fmd.CurrentMasterFilePosition, diff --git a/go/vt/wrangler/testlib/backup_test.go b/go/vt/wrangler/testlib/backup_test.go index 8399102b959..249bc1afa24 100644 --- a/go/vt/wrangler/testlib/backup_test.go +++ b/go/vt/wrangler/testlib/backup_test.go @@ -344,25 +344,23 @@ func TestBackupRestoreLagged(t *testing.T) { InnodbLogGroupHomeDir: sourceInnodbLogDir, } - timer := time.NewTicker(1 * time.Second) - go func(tablet *FakeTablet) { - <-timer.C - tablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ - GTIDSet: mysql.MariadbGTIDSet{ - 2: mysql.MariadbGTID{ - Domain: 2, - Server: 123, - Sequence: 457, - }, - }, - } - }(sourceTablet) - errCh := make(chan error, 1) go func(ctx context.Context, tablet *FakeTablet) { errCh <- vp.Run([]string{"Backup", topoproto.TabletAliasString(tablet.Tablet.Alias)}) }(ctx, sourceTablet) + timer := time.NewTicker(1 * time.Second) + <-timer.C + sourceTablet.FakeMysqlDaemon.CurrentMasterPositionLocked(mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + }) + timer2 := time.NewTicker(5 * time.Second) select { case err := <-errCh: @@ -416,25 +414,23 @@ func TestBackupRestoreLagged(t *testing.T) { RelayLogInfoPath: path.Join(root, "relay-log.info"), } - timer = time.NewTicker(1 * time.Second) - go func(tablet *FakeTablet) { - <-timer.C - tablet.FakeMysqlDaemon.CurrentMasterPosition = mysql.Position{ - GTIDSet: mysql.MariadbGTIDSet{ - 2: mysql.MariadbGTID{ - Domain: 2, - Server: 123, - Sequence: 457, - }, - }, - } - }(destTablet) - errCh = make(chan error, 1) go func(ctx context.Context, tablet *FakeTablet) { errCh <- tablet.TM.RestoreData(ctx, logutil.NewConsoleLogger(), 0 /* waitForBackupInterval */, false /* deleteBeforeRestore */) }(ctx, destTablet) + timer = time.NewTicker(1 * time.Second) + <-timer.C + destTablet.FakeMysqlDaemon.CurrentMasterPositionLocked(mysql.Position{ + GTIDSet: mysql.MariadbGTIDSet{ + 2: mysql.MariadbGTID{ + Domain: 2, + Server: 123, + Sequence: 457, + }, + }, + }) + timer2 = time.NewTicker(5 * time.Second) select { case err := <-errCh: From 345b61baeb8a3b6bbea7ff2b19a293cca420914a Mon Sep 17 00:00:00 2001 From: deepthi Date: Thu, 13 May 2021 14:52:36 -0700 Subject: [PATCH 160/310] fix unit tests Signed-off-by: deepthi --- go/vt/vttablet/sandboxconn/sandboxconn.go | 63 +++-------------------- 1 file changed, 8 insertions(+), 55 deletions(-) diff --git a/go/vt/vttablet/sandboxconn/sandboxconn.go b/go/vt/vttablet/sandboxconn/sandboxconn.go index 313d6d0f955..912fd19f5b0 100644 --- a/go/vt/vttablet/sandboxconn/sandboxconn.go +++ b/go/vt/vttablet/sandboxconn/sandboxconn.go @@ -22,8 +22,6 @@ import ( "fmt" "sync" - "vitess.io/vitess/go/vt/sqlparser" - "context" "vitess.io/vitess/go/sqltypes" @@ -169,8 +167,7 @@ func (sbc *SandboxConn) Execute(ctx context.Context, target *querypb.Target, que if err := sbc.getError(); err != nil { return nil, err } - parse, _ := sqlparser.Parse(query) - return sbc.getNextResult(parse), nil + return sbc.getNextResult(), nil } // ExecuteBatch is part of the QueryService interface. @@ -185,9 +182,8 @@ func (sbc *SandboxConn) ExecuteBatch(ctx context.Context, target *querypb.Target sbc.BatchQueries = append(sbc.BatchQueries, queries) sbc.Options = append(sbc.Options, options) result := make([]sqltypes.Result, 0, len(queries)) - for _, query := range queries { - parse, _ := sqlparser.Parse(query.Sql) - result = append(result, *(sbc.getNextResult(parse))) + for range queries { + result = append(result, *(sbc.getNextResult())) } return result, nil } @@ -210,15 +206,14 @@ func (sbc *SandboxConn) StreamExecute(ctx context.Context, target *querypb.Targe sbc.sExecMu.Unlock() return err } - ast, _ := sqlparser.Parse(query) if sbc.results == nil { - nextRs := sbc.getNextResult(ast) + nextRs := sbc.getNextResult() sbc.sExecMu.Unlock() return callback(nextRs) } for len(sbc.results) > 0 { - nextRs := sbc.getNextResult(ast) + nextRs := sbc.getNextResult() sbc.sExecMu.Unlock() err := callback(nextRs) if err != nil { @@ -391,7 +386,7 @@ func (sbc *SandboxConn) MessageStream(ctx context.Context, target *querypb.Targe if err := sbc.getError(); err != nil { return err } - r := sbc.getNextResult(nil) + r := sbc.getNextResult() if r == nil { return nil } @@ -518,55 +513,13 @@ func (sbc *SandboxConn) Tablet() *topodatapb.Tablet { return sbc.tablet } -func (sbc *SandboxConn) getNextResult(stmt sqlparser.Statement) *sqltypes.Result { +func (sbc *SandboxConn) getNextResult() *sqltypes.Result { if len(sbc.results) != 0 { r := sbc.results[0] sbc.results = sbc.results[1:] return r } - if stmt == nil { - // if we didn't get a valid query, we'll assume we need a SELECT - return getSingleRowResult() - } - switch stmt.(type) { - case *sqlparser.Select, - *sqlparser.Union, - *sqlparser.Show, - *sqlparser.Explain, - *sqlparser.OtherRead: - return getSingleRowResult() - case *sqlparser.Set, - sqlparser.DDLStatement, - *sqlparser.AlterVschema, - *sqlparser.Use, - *sqlparser.OtherAdmin, - *sqlparser.SetTransaction, - *sqlparser.Savepoint, - *sqlparser.SRollback, - *sqlparser.Release: - return &sqltypes.Result{} - } - - // for everything else we fake a single row being affected - return &sqltypes.Result{RowsAffected: 1} -} - -// getSingleRowResult is used to get a SingleRowResult but it creates separate fields because some tests change the fields -// If these fields are not created separately then the constants value also changes which leads to some other tests failing later -func getSingleRowResult() *sqltypes.Result { - singleRowResult := &sqltypes.Result{ - InsertID: SingleRowResult.InsertID, - Rows: SingleRowResult.Rows, - } - - for _, field := range SingleRowResult.Fields { - singleRowResult.Fields = append(singleRowResult.Fields, &querypb.Field{ - Name: field.Name, - Type: field.Type, - }) - } - - return singleRowResult + return SingleRowResult } //StringQueries returns the queries executed as a slice of strings From 2591fa7346bbda7d7570e1c22e3b6fe3e996f731 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 27 Apr 2021 19:42:30 +0200 Subject: [PATCH 161/310] Pad binlog values for binary() columns to match the value returned by a select query. This also ensures that if such columns are used as sharding keys we get the same keyspace_id Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/config.go | 22 ++++++++++++++----- go/test/endtoend/vreplication/helper.go | 3 +++ .../vreplication/unsharded_init_data.sql | 4 ++++ .../vreplication/vreplication_test.go | 7 ++++-- .../vreplication/vreplication_test_env.go | 16 ++++++++------ .../tabletserver/vstreamer/planbuilder.go | 22 ++++++++++++++----- .../tabletserver/vstreamer/vstreamer.go | 2 ++ 7 files changed, 57 insertions(+), 19 deletions(-) diff --git a/go/test/endtoend/vreplication/config.go b/go/test/endtoend/vreplication/config.go index 6d73e4db255..214876a2050 100644 --- a/go/test/endtoend/vreplication/config.go +++ b/go/test/endtoend/vreplication/config.go @@ -10,6 +10,7 @@ create table orders(oid int, cid int, pid int, mname varchar(128), price int, pr create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; create table customer2(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), sport set('football','cricket','baseball'),ts timestamp not null default current_timestamp, primary key(cid)); create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; +create table tenant(tenant_id binary(16), name varbinary(16), primary key (tenant_id)); ` initialProductVSchema = ` @@ -28,7 +29,8 @@ create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id) }, "order_seq": { "type": "sequence" - } + }, + "tenant": {} } } ` @@ -39,9 +41,12 @@ create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id) "vindexes": { "reverse_bits": { "type": "reverse_bits" - } + }, + "binary_md5": { + "type": "binary_md5" + } }, - "tables": { + "tables": { "customer": { "column_vindexes": [ { @@ -65,9 +70,16 @@ create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id) "column": "cid", "sequence": "customer_seq2" } - } + }, + "tenant": { + "column_vindexes": [ + { + "column": "tenant_id", + "name": "binary_md5" + } + ] + } } - } ` merchantVSchema = ` diff --git a/go/test/endtoend/vreplication/helper.go b/go/test/endtoend/vreplication/helper.go index 0fea60f0d83..15726e2dd36 100644 --- a/go/test/endtoend/vreplication/helper.go +++ b/go/test/endtoend/vreplication/helper.go @@ -24,6 +24,9 @@ import ( func execMultipleQueries(t *testing.T, conn *mysql.Conn, database string, lines string) { queries := strings.Split(lines, "\n") for _, query := range queries { + if strings.HasPrefix(query, "--") { + continue + } execVtgateQuery(t, conn, database, string(query)) } } diff --git a/go/test/endtoend/vreplication/unsharded_init_data.sql b/go/test/endtoend/vreplication/unsharded_init_data.sql index 15e2405eb0a..1b58404cfb7 100644 --- a/go/test/endtoend/vreplication/unsharded_init_data.sql +++ b/go/test/endtoend/vreplication/unsharded_init_data.sql @@ -11,3 +11,7 @@ insert into orders(oid, cid, mname, pid, price) values(3, 2, 'monoprice', 2, 20) insert into customer2(cid, name, typ, sport) values(1, 'john',1,'football,baseball'); insert into customer2(cid, name, typ, sport) values(2, 'paul','soho','cricket'); insert into customer2(cid, name, typ, sport) values(3, 'ringo','enterprise',''); +-- for testing edge case where inserted binary value is 15 bytes, field is 16, mysql adds a null while storing but binlog returns 15 bytes +insert into tenant(tenant_id, name) values (x'02BD00987932461E8820C908E84BAE', 'abc'); + + diff --git a/go/test/endtoend/vreplication/vreplication_test.go b/go/test/endtoend/vreplication/vreplication_test.go index dfdb39d7af6..4c06d5ec864 100644 --- a/go/test/endtoend/vreplication/vreplication_test.go +++ b/go/test/endtoend/vreplication/vreplication_test.go @@ -108,7 +108,9 @@ func TestBasicVreplicationWorkflow(t *testing.T) { materializeRollup(t) shardCustomer(t, true, []*Cell{defaultCell}, defaultCellName) - + // the tenant table was to test a specific case with binary sharding keys. Drop it now so that we don't + // have to update the rest of the tests + execVtgateQuery(t, vtgateConn, "customer", "drop table tenant") validateRollupReplicates(t) shardOrders(t) shardMerchant(t) @@ -249,7 +251,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl t.Fatal(err) } - tables := "customer" + tables := "customer,tenant" moveTables(t, sourceCellOrAlias, workflow, sourceKs, targetKs, tables) // Assume we are operating on first cell @@ -267,6 +269,7 @@ func shardCustomer(t *testing.T, testReverse bool, cells []*Cell, sourceCellOrAl insertQuery1 := "insert into customer(cid, name) values(1001, 'tempCustomer1')" matchInsertQuery1 := "insert into customer(cid, `name`) values (:vtg1, :vtg2)" require.True(t, validateThatQueryExecutesOnTablet(t, vtgateConn, productTab, "product", insertQuery1, matchInsertQuery1)) + execVtgateQuery(t, vtgateConn, "product", "update tenant set name='xyz'") vdiff(t, ksWorkflow, "") switchReadsDryRun(t, allCellNames, ksWorkflow, dryRunResultsReadCustomerShard) switchReads(t, allCellNames, ksWorkflow) diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index e618432a7ef..4c53f5104b8 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -19,14 +19,14 @@ package vreplication var dryRunResultsSwitchWritesCustomerShard = []string{ "Lock keyspace product", "Lock keyspace customer", - "Stop writes on keyspace product, tables [customer]:", + "Stop writes on keyspace product, tables [customer,tenant]:", "/ Keyspace product, Shard 0 at Position", "Wait for VReplication on stopped streams to catchup for upto 30s", "Create reverse replication workflow p2c_reverse", "Create journal entries on source databases", - "Enable writes on keyspace customer tables [customer]", + "Enable writes on keyspace customer tables [customer,tenant]", "Switch routing from keyspace product to keyspace customer", - "Routing rules for tables [customer] will be updated", + "Routing rules for tables [customer,tenant] will be updated", "SwitchWrites completed, freeze and delete vreplication streams on:", " tablet 200 ", " tablet 300 ", @@ -41,8 +41,8 @@ var dryRunResultsSwitchWritesCustomerShard = []string{ var dryRunResultsReadCustomerShard = []string{ "Lock keyspace product", - "Switch reads for tables [customer] to keyspace customer for tablet types [REPLICA,RDONLY]", - "Routing rules for tables [customer] will be updated", + "Switch reads for tables [customer,tenant] to keyspace customer for tablet types [REPLICA,RDONLY]", + "Routing rules for tables [customer,tenant] will be updated", "Unlock keyspace product", } @@ -91,7 +91,8 @@ var dryRunResultsDropSourcesDropCustomerShard = []string{ "Lock keyspace customer", "Dropping these tables from the database and removing them from the vschema for keyspace product:", " Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer", - "Blacklisted tables [customer] will be removed from:", + " Keyspace product Shard 0 DbName vt_product Tablet 100 Table tenant", + "Blacklisted tables [customer,tenant] will be removed from:", " Keyspace product Shard 0 Tablet 100", "Delete reverse vreplication streams on source:", " Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100", @@ -108,7 +109,8 @@ var dryRunResultsDropSourcesRenameCustomerShard = []string{ "Lock keyspace customer", "Renaming these tables from the database and removing them from the vschema for keyspace product:", " Keyspace product Shard 0 DbName vt_product Tablet 100 Table customer", - "Blacklisted tables [customer] will be removed from:", + " Keyspace product Shard 0 DbName vt_product Tablet 100 Table tenant", + "Blacklisted tables [customer,tenant] will be removed from:", " Keyspace product Shard 0 Tablet 100", "Delete reverse vreplication streams on source:", " Keyspace product Shard 0 Workflow p2c_reverse DbName vt_product Tablet 100", diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 3454183b069..527c825eda4 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -122,7 +122,7 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error return false, nil, nil } case VindexMatch: - ksid, err := getKeyspaceID(values, filter.Vindex, filter.VindexColumns) + ksid, err := getKeyspaceID(values, filter.Vindex, filter.VindexColumns, plan.Table.Fields) if err != nil { return false, nil, err } @@ -144,7 +144,7 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error if colExpr.Vindex == nil { result[i] = values[colExpr.ColNum] } else { - ksid, err := getKeyspaceID(values, colExpr.Vindex, colExpr.VindexColumns) + ksid, err := getKeyspaceID(values, colExpr.Vindex, colExpr.VindexColumns, plan.Table.Fields) if err != nil { return false, nil, err } @@ -154,10 +154,22 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error return true, result, nil } -func getKeyspaceID(values []sqltypes.Value, vindex vindexes.Vindex, vindexColumns []int) (key.DestinationKeyspaceID, error) { +func getKeyspaceID(values []sqltypes.Value, vindex vindexes.Vindex, vindexColumns []int, fields []*querypb.Field) (key.DestinationKeyspaceID, error) { vindexValues := make([]sqltypes.Value, 0, len(vindexColumns)) - for _, col := range vindexColumns { - vindexValues = append(vindexValues, values[col]) + for colNum, col := range vindexColumns { + // For binary(n) column types, mysql pads the data on the right with nulls. However the binlog event contains + // the data without this padding. In particular, this causes an issue if a binary(n) column is part of the + // sharding key: the keyspace_id() returned during the copy phase (where the value is the result of a mysql query) + // is different from the one during replication (where the value is the one from the binlogs) + // Hence we need to add the padding here + value := values[col] + if fields[colNum].Type == querypb.Type_BINARY { + newValueBytes := make([]byte, int(fields[colNum].ColumnLength)) + copy(newValueBytes[:value.Len()], value.Raw()) + value = sqltypes.MakeTrusted(fields[colNum].Type, newValueBytes) + } + + vindexValues = append(vindexValues, value) } destinations, err := vindexes.Map(vindex, nil, [][]sqltypes.Value{vindexValues}) if err != nil { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index 32e142828a6..f87faa4face 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -878,7 +878,9 @@ func (vs *vstreamer) extractRowAndFilter(plan *streamerPlan, data []byte, dataCo return false, nil, err } pos += l + values[colNum] = value + valueIndex++ } return plan.filter(values) From af2c47a6a86f013dd63ed7055a0e8668e8cd64a3 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Mon, 3 May 2021 23:15:17 +0200 Subject: [PATCH 162/310] Pad binary() values in the binlog reader directly so that all consumers see the padded value instead of doing it later in vstreamer or doint it just for keyspace id computation Signed-off-by: Rohit Nayak --- go/mysql/binlog_event_rbr.go | 12 ++++++++++ .../vreplication/table_plan_builder.go | 14 ++---------- .../vreplication/vcopier_test.go | 2 +- .../vreplication/vplayer_flaky_test.go | 12 +++++----- .../tabletserver/vstreamer/planbuilder.go | 16 ++------------ .../tabletserver/vstreamer/vstreamer.go | 1 - .../tabletserver/vstreamer/vstreamer_test.go | 22 +++++++++---------- 7 files changed, 34 insertions(+), 45 deletions(-) diff --git a/go/mysql/binlog_event_rbr.go b/go/mysql/binlog_event_rbr.go index 7c2341a322a..906ccba5c39 100644 --- a/go/mysql/binlog_event_rbr.go +++ b/go/mysql/binlog_event_rbr.go @@ -895,6 +895,18 @@ func CellValue(data []byte, pos int, typ byte, metadata uint16, styp querypb.Typ l := int(data[pos]) mdata := data[pos+1 : pos+1+l] if sqltypes.IsBinary(styp) { + // For binary(n) column types, mysql pads the data on the right with nulls. However the binlog event contains + // the data without this padding. This causes several issues: + // * if a binary(n) column is part of the sharding key, the keyspace_id() returned during the copy phase + // (where the value is the result of a mysql query) is different from the one during replication + // (where the value is the one from the binlogs) + // * mysql where clause comparisons do not do the right thing without padding + // So for fixed length binary() columns we right-pad it with nulls if necessary + if l < max { + paddedData := make([]byte, max) + copy(paddedData[:l], mdata) + mdata = paddedData + } return sqltypes.MakeTrusted(querypb.Type_BINARY, mdata), l + 1, nil } return sqltypes.MakeTrusted(querypb.Type_VARCHAR, mdata), l + 1, nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index dece8c11b21..91f05a21eec 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -678,16 +678,6 @@ func (tpb *tablePlanBuilder) generateDeleteStatement() *sqlparser.ParsedQuery { return buf.ParsedQuery() } -// For binary(n) column types, the value in the where clause needs to be padded with nulls upto the length of the column -// for MySQL comparison to work properly. This is achieved by casting it to the column type -func castIfNecessary(buf *sqlparser.TrackedBuffer, cexpr *colExpr) { - if cexpr.dataType == "binary" { - buf.Myprintf("cast(%v as %s)", cexpr.expr, cexpr.columnType) - return - } - buf.Myprintf("%v", cexpr.expr) -} - func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bindvarFormatter) { buf.WriteString(" where ") bvf.mode = bvBefore @@ -695,11 +685,11 @@ func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bi for _, cexpr := range tpb.pkCols { if _, ok := cexpr.expr.(*sqlparser.ColName); ok { buf.Myprintf("%s%v=", separator, cexpr.colName) - castIfNecessary(buf, cexpr) + buf.Myprintf("%v", cexpr.expr) } else { // Parenthesize non-trivial expressions. buf.Myprintf("%s%v=(", separator, cexpr.colName) - castIfNecessary(buf, cexpr) + buf.Myprintf("%v", cexpr.expr) buf.Myprintf(")") } separator = " and " diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index 1ebdcad540a..6d372b83540 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -121,7 +121,7 @@ func TestPlayerCopyCharPK(t *testing.T) { "/update _vt.vreplication set state='Copying'", "insert into dst(idc,val) values ('a\\0',1)", `/update _vt.copy_state set lastpk='fields: rows: ' where vrepl_id=.*`, - `update dst set val=3 where idc=cast('a' as binary(2)) and ('a') <= ('a\0')`, + `update dst set val=3 where idc='a\0' and ('a\0') <= ('a\0')`, "insert into dst(idc,val) values ('c\\0',2)", `/update _vt.copy_state set lastpk='fields: rows: ' where vrepl_id=.*`, "/delete from _vt.copy_state.*dst", diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 99357e79ef4..42c5e90487d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -182,14 +182,14 @@ func TestCharPK(t *testing.T) { data [][]string }{{ //binary(2) input: "insert into t1 values(1, 'a')", - output: "insert into t1(id,val) values (1,'a')", + output: "insert into t1(id,val) values (1,'a\\0')", table: "t1", data: [][]string{ {"1", "a\000"}, }, }, { input: "update t1 set id = 2 where val = 'a\000'", - output: "update t1 set id=2 where val=cast('a' as binary(2))", + output: "update t1 set id=2 where val='a\\0'", table: "t1", data: [][]string{ {"2", "a\000"}, @@ -1321,16 +1321,16 @@ func TestPlayerTypes(t *testing.T) { fmt.Sprintf("create table %s.vitess_ints(tiny tinyint, tinyu tinyint unsigned, small smallint, smallu smallint unsigned, medium mediumint, mediumu mediumint unsigned, normal int, normalu int unsigned, big bigint, bigu bigint unsigned, y year, primary key(tiny))", vrepldb), "create table vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", fmt.Sprintf("create table %s.vitess_fracts(id int, deci decimal(5,2), num numeric(5,2), f float, d double, primary key(id))", vrepldb), - "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", - fmt.Sprintf("create table %s.vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(4), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", vrepldb), + "create table vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(5), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", + fmt.Sprintf("create table %s.vitess_strings(vb varbinary(16), c char(16), vc varchar(16), b binary(5), tb tinyblob, bl blob, ttx tinytext, tx text, en enum('a','b'), s set('a','b'), primary key(vb))", vrepldb), "create table vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", fmt.Sprintf("create table %s.vitess_misc(id int, b bit(8), d date, dt datetime, t time, g geometry, primary key(id))", vrepldb), "create table vitess_null(id int, val varbinary(128), primary key(id))", fmt.Sprintf("create table %s.vitess_null(id int, val varbinary(128), primary key(id))", vrepldb), "create table src1(id int, val varbinary(128), primary key(id))", fmt.Sprintf("create table %s.src1(id int, val varbinary(128), primary key(id))", vrepldb), - "create table binary_pk(b binary(4), val varbinary(4), primary key(b))", - fmt.Sprintf("create table %s.binary_pk(b binary(4), val varbinary(4), primary key(b))", vrepldb), + "create table binary_pk(b binary(7), val varbinary(4), primary key(b))", + fmt.Sprintf("create table %s.binary_pk(b binary(7), val varbinary(4), primary key(b))", vrepldb), }) defer execStatements(t, []string{ "drop table vitess_ints", diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 527c825eda4..35ce57eb6f3 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -156,20 +156,8 @@ func (plan *Plan) filter(values []sqltypes.Value) (bool, []sqltypes.Value, error func getKeyspaceID(values []sqltypes.Value, vindex vindexes.Vindex, vindexColumns []int, fields []*querypb.Field) (key.DestinationKeyspaceID, error) { vindexValues := make([]sqltypes.Value, 0, len(vindexColumns)) - for colNum, col := range vindexColumns { - // For binary(n) column types, mysql pads the data on the right with nulls. However the binlog event contains - // the data without this padding. In particular, this causes an issue if a binary(n) column is part of the - // sharding key: the keyspace_id() returned during the copy phase (where the value is the result of a mysql query) - // is different from the one during replication (where the value is the one from the binlogs) - // Hence we need to add the padding here - value := values[col] - if fields[colNum].Type == querypb.Type_BINARY { - newValueBytes := make([]byte, int(fields[colNum].ColumnLength)) - copy(newValueBytes[:value.Len()], value.Raw()) - value = sqltypes.MakeTrusted(fields[colNum].Type, newValueBytes) - } - - vindexValues = append(vindexValues, value) + for _, col := range vindexColumns { + vindexValues = append(vindexValues, values[col]) } destinations, err := vindexes.Map(vindex, nil, [][]sqltypes.Value{vindexValues}) if err != nil { diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go index f87faa4face..9a46b9affbc 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer.go @@ -880,7 +880,6 @@ func (vs *vstreamer) extractRowAndFilter(plan *streamerPlan, data []byte, dataCo pos += l values[colNum] = value - valueIndex++ } return plan.filter(values) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 8047c8047e0..2c9a4b57c43 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -110,9 +110,9 @@ func TestSetAndEnum(t *testing.T) { output: [][]string{{ `begin`, fe.String(), - `type:ROW row_event: > > `, - `type:ROW row_event: > > `, - `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, `gtid`, `commit`, }}, @@ -133,8 +133,8 @@ func TestCellValuePadding(t *testing.T) { engine.se.Reload(context.Background()) queries := []string{ "begin", - "insert into t1 values (1, 'aaa')", - "insert into t1 values (2, 'bbb')", + "insert into t1 values (1, 'aaa\000')", + "insert into t1 values (2, 'bbb\000')", "update t1 set id = 11 where val = 'aaa\000'", "insert into t2 values (1, 'aaa')", "insert into t2 values (2, 'bbb')", @@ -147,9 +147,9 @@ func TestCellValuePadding(t *testing.T) { output: [][]string{{ `begin`, `type:FIELD field_event: fields: > `, - `type:ROW row_event: > > `, - `type:ROW row_event: > > `, - `type:ROW row_event: after: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `type:ROW row_event: after: > > `, `type:FIELD field_event: fields: > `, `type:ROW row_event: > > `, `type:ROW row_event: > > `, @@ -1561,13 +1561,13 @@ func TestTypes(t *testing.T) { }, { // TODO(sougou): validate that binary and char data generate correct DMLs on the other end. input: []string{ - "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", + "insert into vitess_strings values('a', 'b', 'c', 'd\000\000\000', 'e', 'f', 'g', 'h', 'a', 'a,b')", }, output: [][]string{{ `begin`, `type:FIELD field_event: fields: fields: fields: fields: fields: fields: fields: fields: fields: > `, - `type:ROW row_event: > > `, + `type:ROW row_event: > > `, `gtid`, `commit`, }}, From 0ae1db0f0112cf46ce9362269517fc80c9a7ccc2 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 4 May 2021 11:52:38 +0200 Subject: [PATCH 163/310] Fix tests Signed-off-by: Rohit Nayak --- .../tabletmanager/vreplication/framework_test.go | 5 ++++- .../vreplication/vplayer_flaky_test.go | 14 +++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go index 5efbfbfc413..e48b2bdf454 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/framework_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/framework_test.go @@ -121,12 +121,15 @@ func TestMain(m *testing.M) { playerEngine = NewTestEngine(env.TopoServ, env.Cells[0], env.Mysqld, realDBClientFactory, vrepldb, externalConfig) playerEngine.Open(context.Background()) defer playerEngine.Close() - if err := env.Mysqld.ExecuteSuperQueryList(context.Background(), binlogplayer.CreateVReplicationTable()); err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 } + for _, query := range binlogplayer.AlterVReplicationTable { + env.Mysqld.ExecuteSuperQuery(context.Background(), query) + } + if err := env.Mysqld.ExecuteSuperQuery(context.Background(), createCopyState); err != nil { fmt.Fprintf(os.Stderr, "%v", err) return 1 diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 42c5e90487d..9916bc65046 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -1329,8 +1329,8 @@ func TestPlayerTypes(t *testing.T) { fmt.Sprintf("create table %s.vitess_null(id int, val varbinary(128), primary key(id))", vrepldb), "create table src1(id int, val varbinary(128), primary key(id))", fmt.Sprintf("create table %s.src1(id int, val varbinary(128), primary key(id))", vrepldb), - "create table binary_pk(b binary(7), val varbinary(4), primary key(b))", - fmt.Sprintf("create table %s.binary_pk(b binary(7), val varbinary(4), primary key(b))", vrepldb), + "create table binary_pk(b binary(4), val varbinary(4), primary key(b))", + fmt.Sprintf("create table %s.binary_pk(b binary(4), val varbinary(4), primary key(b))", vrepldb), }) defer execStatements(t, []string{ "drop table vitess_ints", @@ -1394,10 +1394,10 @@ func TestPlayerTypes(t *testing.T) { }, }, { input: "insert into vitess_strings values('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a', 'a,b')", - output: "insert into vitess_strings(vb,c,vc,b,tb,bl,ttx,tx,en,s) values ('a','b','c','d','e','f','g','h','1','3')", + output: "insert into vitess_strings(vb,c,vc,b,tb,bl,ttx,tx,en,s) values ('a','b','c','d\\0\\0\\0\\0','e','f','g','h','1','3')", table: "vitess_strings", data: [][]string{ - {"a", "b", "c", "d\000\000\000", "e", "f", "g", "h", "a", "a,b"}, + {"a", "b", "c", "d\000\000\000\000", "e", "f", "g", "h", "a", "a,b"}, }, }, { input: "insert into vitess_misc values(1, '\x01', '2012-01-01', '2012-01-01 15:45:45', '15:45:45', point(1, 2))", @@ -1415,7 +1415,7 @@ func TestPlayerTypes(t *testing.T) { }, }, { input: "insert into binary_pk values('a', 'aaa')", - output: "insert into binary_pk(b,val) values ('a','aaa')", + output: "insert into binary_pk(b,val) values ('a\\0\\0\\0','aaa')", table: "binary_pk", data: [][]string{ {"a\000\000\000", "aaa"}, @@ -1423,10 +1423,10 @@ func TestPlayerTypes(t *testing.T) { }, { // Binary pk is a special case: https://github.com/vitessio/vitess/issues/3984 input: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", - output: "update binary_pk set val='bbb' where b=cast('a' as binary(4))", + output: "update binary_pk set val='bbb' where b='a\\0\\0\\0'", table: "binary_pk", data: [][]string{ - {"a\x00\x00\x00", "bbb"}, + {"a\000\000\000", "bbb"}, }, }} if enableJSONColumnTesting { From 78d3f2c0ffccebef1e4b204256add3f9a037d971 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 20 May 2021 16:29:15 +0530 Subject: [PATCH 164/310] added failing test Signed-off-by: GuptaManan100 --- go/vt/sqlparser/parse_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index f64a3b072bb..bda582166d7 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1644,6 +1644,9 @@ var ( output: "select schema() from dual", }, { input: "select title from video as v where match(v.title, v.tag) against ('DEMO' in boolean mode)", + }, { + input: "SELECT id FROM blog_posts USE INDEX (PRIMARY) WHERE id = 10", + output: "select id from blog_posts use index (`PRIMARY`) where id = 10", }, { input: "select name, group_concat(score) from t group by name", output: "select `name`, group_concat(score) from t group by `name`", From c64cf90435cab8269ca74d2524448d51df774efa Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 20 May 2021 16:37:19 +0530 Subject: [PATCH 165/310] allow PRIMARY to be passed to index lists as well Signed-off-by: GuptaManan100 --- go/vt/sqlparser/sql.go | 6346 ++++++++++++++++++++-------------------- go/vt/sqlparser/sql.y | 26 +- 2 files changed, 3241 insertions(+), 3131 deletions(-) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 6c521afb8b9..24ea77f6b03 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1036,7 +1036,7 @@ var yyExca = [...]int{ 1, -1, -2, 0, -1, 42, - 163, 907, + 163, 911, -2, 89, -1, 43, 1, 107, @@ -1074,11 +1074,11 @@ var yyExca = [...]int{ 300, 113, -2, 334, -1, 550, - 149, 918, - -2, 914, + 149, 922, + -2, 918, -1, 551, - 149, 919, - -2, 915, + 149, 923, + -2, 919, -1, 568, 55, 531, -2, 543, @@ -1086,17 +1086,17 @@ var yyExca = [...]int{ 55, 532, -2, 544, -1, 589, - 117, 1245, + 117, 1249, -2, 82, -1, 590, - 117, 1132, + 117, 1136, -2, 83, -1, 596, - 117, 1180, - -2, 892, + 117, 1184, + -2, 896, -1, 730, - 117, 1074, - -2, 889, + 117, 1078, + -2, 893, -1, 762, 174, 36, 179, 36, @@ -1118,8 +1118,8 @@ var yyExca = [...]int{ 179, 37, -2, 242, -1, 1333, - 149, 921, - -2, 917, + 149, 925, + -2, 921, -1, 1423, 73, 64, 81, 64, @@ -1129,491 +1129,477 @@ var yyExca = [...]int{ 451, 269, -2, 113, -1, 1831, - 5, 786, - 18, 786, - 20, 786, - 32, 786, - 82, 786, + 5, 790, + 18, 790, + 20, 790, + 32, 790, + 82, 790, -2, 569, - -1, 2043, - 45, 860, - -2, 858, + -1, 2046, + 45, 864, + -2, 862, } const yyPrivate = 57344 -const yyLast = 26340 +const yyLast = 26967 var yyAct = [...]int{ - 550, 2129, 2116, 1878, 2043, 1749, 2093, 2056, 493, 1647, - 1989, 1718, 1967, 894, 79, 3, 1811, 1506, 1812, 522, - 1441, 1615, 1370, 1875, 561, 1648, 508, 1808, 1356, 1005, - 1476, 960, 1722, 1012, 1461, 1706, 734, 1634, 491, 1481, - 1705, 853, 142, 1823, 1770, 1420, 1575, 173, 1327, 1261, - 185, 1319, 458, 185, 1504, 1137, 792, 1248, 474, 594, - 185, 128, 757, 1698, 892, 77, 1049, 1483, 1042, 1033, - 1402, 570, 1409, 1010, 1015, 1353, 1035, 1372, 999, 495, - 1296, 1553, 741, 763, 1144, 555, 1330, 738, 474, 31, - 1032, 474, 185, 474, 1039, 484, 1484, 1385, 1227, 742, - 1472, 591, 758, 759, 1048, 1425, 1046, 1022, 564, 75, - 1129, 1155, 760, 1264, 111, 112, 770, 834, 8, 481, - 973, 105, 145, 74, 106, 7, 172, 976, 6, 1741, - 1740, 1535, 1991, 1214, 80, 1613, 1462, 1367, 1368, 2085, - 1282, 2040, 1946, 1854, 2018, 2017, 1962, 796, 795, 1963, - 2135, 2090, 2128, 735, 1488, 113, 76, 576, 580, 2067, - 2119, 578, 1879, 1523, 2089, 556, 107, 2066, 185, 82, - 83, 84, 85, 86, 87, 1486, 797, 1787, 185, 1908, - 847, 482, 483, 185, 749, 1614, 33, 794, 436, 68, - 37, 38, 1838, 1839, 588, 174, 175, 176, 1542, 1837, - 808, 809, 1541, 812, 813, 814, 815, 171, 1435, 818, + 550, 2134, 2121, 1878, 2046, 1749, 2098, 2059, 493, 1718, + 1991, 1967, 1647, 79, 3, 1506, 1441, 1615, 1812, 522, + 1811, 508, 1370, 1875, 561, 960, 1005, 1648, 1356, 1808, + 1476, 491, 1722, 1012, 1461, 1481, 734, 1705, 1983, 1706, + 1823, 142, 1420, 1770, 853, 894, 1575, 173, 1327, 892, + 185, 1319, 458, 185, 1504, 1634, 792, 1248, 474, 1261, + 185, 128, 757, 1483, 594, 77, 1698, 1042, 1049, 1409, + 1137, 1402, 570, 1010, 1372, 1015, 1035, 495, 1032, 999, + 1353, 1296, 555, 1553, 741, 1144, 31, 738, 474, 484, + 1227, 474, 185, 474, 1039, 1472, 1033, 763, 1484, 1385, + 758, 759, 742, 1048, 1022, 1046, 75, 1425, 564, 172, + 1129, 1155, 1264, 111, 760, 112, 834, 770, 973, 145, + 1462, 105, 106, 481, 74, 976, 8, 7, 6, 1741, + 1740, 1993, 1535, 591, 1367, 1368, 1214, 2090, 1282, 1613, + 2043, 1946, 2020, 2019, 1854, 1962, 796, 795, 1963, 2140, + 2095, 2133, 1488, 735, 2070, 113, 2124, 76, 576, 580, + 1879, 1523, 556, 107, 2094, 2069, 1787, 1908, 185, 749, + 1614, 1678, 436, 1486, 1677, 797, 1837, 1679, 185, 863, + 847, 1838, 1839, 185, 1435, 482, 483, 794, 1542, 1436, + 1437, 890, 1541, 588, 174, 175, 176, 811, 462, 80, + 808, 809, 554, 812, 813, 814, 815, 553, 595, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, - 829, 830, 831, 832, 595, 485, 751, 107, 773, 750, - 1436, 1437, 774, 1050, 535, 1051, 541, 542, 539, 540, - 462, 538, 537, 536, 752, 554, 1114, 798, 799, 800, - 166, 543, 544, 553, 1485, 811, 863, 861, 805, 1369, - 67, 1717, 102, 178, 179, 180, 1455, 1678, 872, 873, - 1677, 753, 166, 1679, 881, 108, 883, 130, 890, 174, - 175, 176, 810, 1127, 1689, 150, 1751, 1939, 461, 2069, - 1899, 1897, 102, 167, 472, 107, 1281, 108, 476, 130, - 1283, 1284, 1285, 470, 874, 1538, 1723, 150, 875, 872, - 873, 97, 1204, 880, 882, 1505, 140, 1236, 1228, 1237, - 1238, 129, 2030, 922, 921, 931, 932, 924, 925, 926, - 927, 928, 929, 930, 923, 1771, 1233, 933, 140, 147, - 2118, 148, 835, 129, 864, 862, 1131, 1132, 139, 138, - 165, 1745, 888, 1205, 2086, 1206, 889, 1752, 1746, 1754, - 869, 147, 842, 148, 1550, 462, 102, 94, 1131, 1132, - 139, 138, 165, 98, 867, 868, 99, 100, 1773, 865, - 866, 462, 817, 816, 1753, 1230, 2014, 1232, 772, 1957, - 1234, 1507, 781, 779, 1403, 790, 789, 788, 134, 1133, - 141, 787, 1130, 786, 135, 136, 1853, 785, 151, 784, - 878, 783, 778, 461, 101, 170, 1487, 754, 156, 1557, - 134, 1133, 141, 1123, 1130, 877, 135, 136, 1231, 461, - 151, 2065, 791, 1540, 1958, 1775, 185, 1779, 1426, 1774, - 156, 1772, 845, 2105, 101, 2133, 1777, 739, 462, 739, - 876, 879, 766, 737, 2136, 1776, 739, 886, 104, 474, - 474, 474, 1143, 1142, 846, 765, 746, 772, 1778, 1780, - 1616, 1618, 582, 1755, 1529, 2006, 1241, 474, 474, 856, - 857, 858, 859, 860, 782, 780, 2057, 772, 898, 801, - 1715, 772, 1537, 904, 1796, 1795, 461, 2070, 1794, 891, - 747, 1733, 69, 922, 921, 931, 932, 924, 925, 926, - 927, 928, 929, 930, 923, 1555, 772, 933, 101, 143, - 1554, 1525, 771, 435, 895, 896, 177, 1442, 775, 765, - 2031, 2047, 1549, 1928, 1555, 1548, 945, 946, 776, 1554, - 1836, 143, 1216, 1215, 1217, 1218, 1219, 1639, 1594, 933, - 1583, 1515, 1431, 1026, 185, 958, 777, 851, 174, 175, - 176, 923, 1576, 839, 933, 1674, 1617, 807, 137, 1262, - 943, 1381, 1003, 772, 911, 912, 910, 1591, 1278, 474, - 131, 870, 185, 132, 185, 185, 885, 474, 913, 1002, - 137, 2131, 913, 474, 2132, 1265, 2130, 907, 887, 2022, - 591, 771, 131, 910, 905, 132, 90, 906, 765, 768, - 769, 793, 739, 961, 2007, 2005, 762, 766, 1694, 913, - 1821, 771, 1229, 848, 849, 771, 1052, 775, 765, 1031, - 1000, 841, 765, 768, 769, 761, 739, 776, 912, 910, - 762, 766, 1016, 836, 1524, 837, 908, 840, 838, 914, - 771, 91, 855, 1789, 1014, 913, 975, 978, 980, 982, - 983, 985, 987, 988, 979, 981, 1354, 984, 986, 1354, - 989, 1601, 997, 144, 149, 146, 152, 153, 154, 155, - 157, 158, 159, 160, 1263, 485, 945, 946, 1118, 161, - 162, 163, 164, 1004, 971, 144, 149, 146, 152, 153, - 154, 155, 157, 158, 159, 160, 1522, 771, 1452, 806, - 1266, 161, 162, 163, 164, 945, 946, 174, 175, 176, - 1453, 1321, 1520, 595, 1008, 1011, 924, 925, 926, 927, - 928, 929, 930, 923, 185, 781, 933, 779, 1110, 926, - 927, 928, 929, 930, 923, 1517, 185, 933, 1119, 1120, - 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, - 2137, 474, 933, 1139, 854, 1589, 2050, 1687, 1517, 1521, - 1019, 1148, 1223, 1588, 2120, 1152, 2110, 1322, 474, 474, - 1303, 474, 1149, 474, 474, 1945, 474, 474, 474, 474, - 474, 474, 1519, 169, 1301, 1302, 1300, 1135, 911, 912, - 910, 474, 2121, 1944, 2111, 185, 1188, 1183, 1184, 1121, - 1122, 911, 912, 910, 1221, 745, 913, 1703, 1128, 1791, - 1859, 1201, 1568, 1569, 1570, 1702, 1147, 2138, 1798, 913, - 1222, 1701, 474, 67, 1386, 1387, 1491, 1185, 1211, 1224, - 185, 911, 912, 910, 1209, 1299, 185, 1208, 1207, 185, - 1247, 1199, 185, 1193, 1146, 1190, 174, 175, 176, 913, - 1681, 2123, 1116, 185, 1109, 185, 1125, 1191, 1192, 1590, - 1126, 1124, 1220, 1197, 1198, 1189, 1799, 474, 474, 185, - 474, 474, 185, 474, 474, 1145, 1145, 744, 1164, 1138, - 1157, 1047, 1158, 2122, 1160, 1162, 1210, 2112, 1166, 1168, - 1170, 1172, 1174, 1253, 2101, 1255, 2079, 1257, 1258, 1259, - 1260, 1250, 748, 1980, 1942, 911, 912, 910, 1383, 1916, - 1800, 1267, 921, 931, 932, 924, 925, 926, 927, 928, - 929, 930, 923, 913, 1320, 933, 1297, 1711, 1186, 581, - 1242, 1268, 1269, 1323, 1271, 1272, 1699, 1274, 1275, 1291, - 1293, 1294, 911, 912, 910, 1565, 1533, 474, 174, 175, - 176, 1292, 1499, 751, 107, 1532, 750, 174, 175, 176, - 913, 1497, 1331, 1251, 1212, 1342, 1345, 1200, 1196, 586, - 1382, 1355, 1195, 1194, 1324, 1325, 1748, 565, 1335, 1336, - 2012, 474, 474, 1864, 2104, 1337, 1298, 2011, 1276, 174, - 175, 176, 185, 1202, 1877, 911, 912, 910, 174, 175, - 176, 1864, 2063, 76, 474, 1725, 1332, 1252, 1333, 1864, - 2048, 185, 1714, 913, 474, 583, 584, 1376, 185, 1450, - 185, 1635, 1377, 1668, 961, 1864, 565, 1388, 185, 185, - 1331, 1426, 1361, 1362, 1820, 474, 1864, 2020, 474, 1338, - 1339, 1809, 1421, 1344, 1347, 1348, 1960, 565, 591, 474, - 1820, 591, 1517, 565, 1926, 565, 1864, 1869, 1923, 1334, - 1635, 1286, 1287, 1288, 1289, 1851, 1850, 1847, 1848, 1360, - 1847, 1846, 1363, 1364, 1400, 33, 1333, 1427, 1396, 1395, - 565, 1394, 565, 1426, 1742, 1446, 1427, 1113, 1727, 1406, - 1445, 511, 510, 513, 514, 515, 516, 1463, 1464, 1465, - 512, 909, 517, 78, 474, 1720, 1721, 551, 1406, 565, - 1518, 1449, 1496, 1498, 909, 565, 1340, 1341, 2021, 33, - 1405, 1398, 1996, 1424, 1864, 474, 1113, 1112, 1820, 1478, - 1849, 474, 1058, 1057, 33, 1148, 1429, 1148, 1428, 1406, - 1433, 1432, 1434, 1606, 1642, 1516, 1430, 1428, 1394, 67, - 2055, 1448, 1447, 1605, 1394, 1426, 1517, 186, 1500, 1384, - 186, 1503, 1365, 558, 1517, 475, 1643, 186, 1394, 1240, - 1406, 595, 1044, 756, 595, 474, 755, 1320, 67, 1969, - 1876, 1934, 1320, 1320, 1115, 1477, 1747, 1479, 1510, 1473, - 1513, 1467, 1514, 67, 1947, 475, 1474, 1475, 475, 186, - 475, 1466, 1490, 1489, 1440, 1492, 1495, 1226, 67, 1179, - 1140, 1526, 1508, 1509, 1136, 1111, 1479, 185, 1512, 92, - 1951, 185, 185, 185, 185, 185, 1708, 171, 1528, 1707, - 1527, 185, 185, 1530, 1531, 185, 773, 67, 1176, 1750, - 774, 1948, 1949, 1950, 1970, 1411, 1414, 1415, 1416, 1412, - 1145, 1413, 1417, 185, 185, 185, 1180, 1181, 1182, 1824, - 1825, 1488, 2107, 1480, 1952, 1953, 2125, 185, 1830, 2088, - 185, 474, 2117, 1708, 1842, 186, 488, 1827, 565, 1809, - 1829, 1716, 1177, 1178, 1279, 186, 1244, 1659, 1656, 1657, - 186, 1655, 1660, 1559, 1658, 1661, 1801, 1415, 1416, 1563, - 1624, 1013, 1456, 1927, 1457, 1458, 1459, 1460, 1867, 1633, - 1297, 1536, 1632, 2075, 2072, 2109, 2092, 1558, 2094, 2100, - 1468, 1469, 1470, 1471, 922, 921, 931, 932, 924, 925, - 926, 927, 928, 929, 930, 923, 1622, 2099, 933, 2044, - 1239, 2042, 1578, 552, 1623, 96, 1579, 1712, 1350, 803, - 802, 571, 1585, 1707, 897, 1735, 185, 1586, 1587, 2052, - 1006, 1734, 1351, 1593, 185, 572, 1596, 1597, 1686, 108, - 1298, 1571, 1007, 2051, 1603, 1994, 1604, 1511, 1154, 1607, - 1608, 1609, 1610, 1611, 1153, 1141, 185, 1921, 1017, 1018, - 574, 168, 573, 1379, 181, 1493, 1621, 185, 185, 185, - 185, 185, 1386, 1387, 1649, 1580, 1581, 1644, 1628, 185, - 1584, 1243, 2013, 185, 556, 1964, 185, 185, 1600, 1419, - 185, 185, 185, 559, 560, 562, 1598, 1666, 1631, 1640, - 2114, 1637, 1000, 1680, 1612, 2113, 1630, 2097, 2076, 1664, - 1665, 1620, 1920, 1863, 1501, 563, 78, 1919, 1627, 1804, - 1635, 2127, 2126, 1693, 1595, 1592, 1027, 1020, 1638, 1636, - 2127, 1669, 2045, 1940, 1380, 1671, 558, 1651, 1652, 81, - 1654, 76, 1692, 73, 1695, 1696, 1697, 1683, 1, 474, - 1662, 1250, 1690, 1691, 1667, 445, 571, 1650, 1366, 1672, - 1653, 1675, 474, 998, 457, 2115, 1213, 1203, 474, 1684, - 572, 474, 1880, 1148, 1724, 1966, 1602, 1870, 474, 1494, - 1704, 1482, 1728, 764, 133, 1443, 1444, 2059, 89, 1730, - 1739, 1700, 732, 568, 569, 574, 88, 573, 185, 767, - 884, 1502, 1710, 2004, 1625, 1626, 1011, 1961, 1688, 1738, - 1709, 1454, 1938, 186, 1841, 1685, 2049, 474, 185, 1064, - 1737, 1062, 1128, 1063, 1061, 1066, 1065, 1060, 1729, 1280, - 471, 1418, 1053, 1332, 1021, 1333, 475, 475, 475, 804, - 1852, 1736, 1451, 1277, 474, 1534, 452, 871, 448, 941, - 1320, 1629, 1676, 592, 475, 475, 585, 1767, 1815, 95, - 2098, 2073, 2071, 2041, 1990, 2074, 2039, 2108, 2091, 1764, - 1765, 1378, 1758, 1009, 1759, 1769, 1918, 1803, 1768, 1760, - 474, 1756, 1599, 970, 1352, 1036, 494, 1290, 509, 506, - 185, 1766, 1788, 507, 1389, 1782, 1641, 915, 492, 486, - 474, 1781, 1028, 1410, 1408, 1407, 474, 474, 1245, 1040, - 1826, 1649, 1810, 1767, 1822, 1034, 1393, 1539, 1744, 567, - 93, 1349, 2029, 1813, 1907, 1807, 566, 59, 36, 185, - 478, 186, 2084, 900, 1816, 575, 1411, 1414, 1415, 1416, - 1412, 30, 1413, 1417, 29, 1819, 1824, 1825, 28, 521, - 23, 22, 21, 20, 19, 1831, 475, 1828, 25, 186, - 18, 186, 186, 17, 475, 1832, 16, 1834, 103, 1835, - 475, 1844, 1845, 1860, 1833, 46, 185, 185, 43, 41, - 110, 474, 109, 44, 40, 1840, 843, 27, 26, 15, - 14, 1797, 1866, 13, 185, 12, 11, 10, 9, 184, - 5, 1855, 469, 4, 903, 24, 959, 1856, 2, 184, - 1871, 1881, 474, 474, 474, 0, 185, 1865, 1818, 0, - 0, 0, 0, 1790, 1857, 1858, 1911, 1868, 0, 1874, - 0, 0, 579, 579, 1873, 0, 0, 0, 0, 0, - 0, 184, 0, 947, 948, 949, 950, 951, 952, 953, - 954, 955, 956, 1890, 0, 1889, 0, 1805, 0, 1891, - 1886, 1887, 0, 0, 0, 0, 1895, 0, 0, 0, + 829, 830, 831, 832, 107, 753, 751, 750, 752, 1689, + 773, 861, 1455, 774, 82, 83, 84, 85, 86, 87, + 33, 872, 873, 68, 37, 38, 461, 1939, 1114, 798, + 799, 800, 1485, 1050, 449, 1051, 1369, 171, 2074, 805, + 472, 1899, 1897, 450, 470, 1281, 810, 864, 476, 889, + 166, 1723, 535, 447, 541, 542, 539, 540, 1505, 538, + 537, 536, 1538, 97, 1745, 1751, 1330, 1228, 2123, 543, + 544, 1746, 107, 835, 888, 108, 1233, 130, 1283, 1284, + 1285, 174, 175, 176, 842, 150, 869, 462, 174, 175, + 176, 1753, 444, 1754, 67, 102, 178, 179, 180, 862, + 1550, 456, 2032, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 462, 140, 933, 102, 94, + 817, 129, 102, 167, 1236, 98, 1237, 1238, 99, 100, + 1234, 816, 2091, 867, 868, 461, 1752, 865, 866, 147, + 1230, 148, 2016, 462, 1957, 772, 117, 118, 139, 138, + 165, 874, 781, 1507, 1204, 875, 872, 873, 2138, 779, + 1403, 790, 789, 461, 788, 787, 786, 881, 785, 883, + 437, 438, 439, 1232, 454, 455, 465, 784, 783, 778, + 451, 453, 466, 440, 441, 468, 467, 1853, 443, 442, + 754, 461, 446, 463, 1487, 1205, 1123, 1206, 134, 115, + 141, 122, 114, 1540, 135, 136, 880, 882, 151, 2068, + 791, 845, 1958, 886, 1231, 1557, 185, 739, 156, 123, + 739, 765, 766, 846, 737, 2141, 2110, 578, 746, 772, + 876, 879, 739, 126, 124, 119, 120, 121, 125, 474, + 474, 474, 1426, 116, 782, 170, 2075, 101, 104, 2008, + 462, 780, 127, 1143, 1142, 582, 1755, 474, 474, 1616, + 1618, 772, 856, 857, 858, 859, 860, 2060, 1529, 1241, + 101, 898, 904, 801, 101, 772, 1715, 1537, 1796, 771, + 1795, 772, 891, 1794, 747, 775, 765, 1733, 435, 895, + 896, 485, 177, 1549, 1771, 776, 1548, 2050, 461, 1525, + 945, 946, 1928, 878, 2136, 1836, 1639, 2137, 1583, 2135, + 2033, 1555, 1594, 777, 1515, 1431, 1554, 464, 877, 143, + 1026, 958, 851, 1442, 459, 1216, 1215, 1217, 1218, 1219, + 923, 1591, 933, 933, 185, 1674, 69, 1773, 1555, 460, + 1262, 1381, 885, 1554, 807, 913, 90, 1278, 943, 1789, + 772, 1003, 2024, 793, 887, 1617, 1821, 1265, 1229, 474, + 870, 1303, 185, 771, 185, 185, 1052, 474, 137, 1002, + 765, 768, 769, 474, 739, 1301, 1302, 1300, 762, 766, + 131, 908, 855, 132, 840, 907, 905, 906, 2009, 2007, + 961, 91, 848, 849, 1775, 771, 1779, 761, 1774, 1354, + 1772, 775, 765, 910, 1687, 1777, 1031, 1703, 1118, 771, + 1000, 776, 591, 839, 1776, 771, 765, 768, 769, 913, + 739, 841, 1524, 1016, 762, 766, 2053, 1778, 1780, 1522, + 1019, 911, 912, 910, 975, 978, 980, 982, 983, 985, + 987, 988, 979, 981, 2142, 984, 986, 1520, 989, 913, + 945, 946, 1354, 565, 1601, 1263, 997, 922, 921, 931, + 932, 924, 925, 926, 927, 928, 929, 930, 923, 945, + 946, 933, 1266, 144, 149, 146, 152, 153, 154, 155, + 157, 158, 159, 160, 771, 1452, 806, 595, 781, 161, + 162, 163, 164, 836, 854, 837, 779, 1453, 838, 922, + 921, 931, 932, 924, 925, 926, 927, 928, 929, 930, + 923, 2143, 1590, 933, 185, 1517, 1576, 1945, 1110, 926, + 927, 928, 929, 930, 923, 2125, 185, 933, 1119, 1120, + 924, 925, 926, 927, 928, 929, 930, 923, 1004, 1521, + 933, 474, 745, 1139, 1291, 1293, 1294, 911, 912, 910, + 169, 1148, 1517, 2126, 1944, 1152, 1292, 1223, 474, 474, + 67, 474, 1149, 474, 474, 913, 474, 474, 474, 474, + 474, 474, 1299, 174, 175, 176, 1519, 1135, 174, 175, + 176, 474, 1321, 912, 910, 185, 1188, 1183, 1184, 1121, + 1122, 1568, 1569, 1570, 2115, 911, 912, 910, 1128, 1859, + 913, 1201, 931, 932, 924, 925, 926, 927, 928, 929, + 930, 923, 474, 913, 933, 1222, 1702, 1185, 1386, 1387, + 185, 1147, 2116, 1798, 1701, 1491, 185, 1109, 1224, 185, + 1247, 1221, 185, 1694, 1014, 1146, 1211, 1209, 1322, 748, + 1208, 1116, 1207, 185, 744, 185, 1125, 1191, 1192, 1126, + 1199, 1124, 1138, 1197, 1198, 1193, 1190, 474, 474, 185, + 474, 474, 185, 474, 474, 1189, 1145, 1145, 1164, 2128, + 1157, 1799, 1158, 2127, 1160, 1162, 1047, 1911, 1166, 1168, + 1170, 1172, 1174, 174, 175, 176, 1253, 1681, 1255, 1220, + 1257, 1258, 1259, 1260, 1210, 2117, 1250, 2106, 2084, 911, + 912, 910, 1186, 1980, 1942, 1916, 1268, 1269, 1800, 1271, + 1272, 1267, 1274, 1275, 1320, 914, 1297, 913, 1711, 581, + 1242, 1699, 1565, 1323, 922, 921, 931, 932, 924, 925, + 926, 927, 928, 929, 930, 923, 1533, 474, 933, 1532, + 1251, 107, 1212, 751, 750, 1200, 1589, 1196, 174, 175, + 176, 485, 1499, 1195, 1588, 1342, 1345, 1324, 1325, 1194, + 971, 1355, 1383, 1748, 586, 911, 912, 910, 1335, 1336, + 565, 474, 474, 1791, 1298, 1337, 2014, 1276, 2013, 911, + 912, 910, 185, 913, 1331, 174, 175, 176, 76, 1497, + 1008, 1011, 1864, 2109, 474, 1877, 1332, 913, 174, 175, + 176, 185, 1202, 1333, 474, 583, 584, 1376, 185, 1725, + 185, 961, 1377, 174, 175, 176, 1714, 1388, 185, 185, + 1864, 2066, 1361, 1362, 1382, 474, 1864, 2051, 474, 2037, + 565, 1421, 511, 510, 513, 514, 515, 516, 1450, 474, + 1820, 512, 1923, 517, 1864, 2022, 1334, 1960, 565, 911, + 912, 910, 1331, 921, 931, 932, 924, 925, 926, 927, + 928, 929, 930, 923, 1400, 565, 933, 913, 1635, 1396, + 591, 1333, 78, 591, 1635, 1446, 1517, 565, 33, 1445, + 1926, 565, 1864, 1869, 1851, 1850, 33, 1463, 1464, 1465, + 1847, 1848, 1847, 1846, 474, 1394, 565, 551, 1426, 1742, + 1427, 1449, 1496, 1498, 1113, 1727, 1720, 1721, 1398, 1406, + 565, 1642, 33, 1424, 1427, 474, 909, 565, 1668, 1478, + 1518, 474, 1113, 1112, 909, 1148, 1426, 1148, 1429, 1433, + 1432, 1058, 1057, 1643, 1809, 1516, 1406, 1394, 2023, 1448, + 1447, 1395, 1820, 1820, 1947, 595, 1864, 186, 595, 1405, + 186, 1503, 67, 558, 1849, 475, 1406, 186, 1434, 1998, + 67, 1428, 1606, 1605, 1394, 474, 1517, 1320, 1500, 1430, + 1384, 1365, 1320, 1320, 1517, 1428, 1240, 1479, 1044, 756, + 755, 1474, 1475, 1426, 2058, 475, 67, 1492, 475, 186, + 475, 1948, 1949, 1950, 1490, 1513, 1489, 1514, 1495, 1406, + 1179, 1526, 67, 1969, 1876, 1509, 1479, 185, 1934, 1512, + 1394, 185, 185, 185, 185, 185, 1508, 1115, 1528, 1477, + 1527, 185, 185, 1530, 1531, 185, 1747, 67, 773, 1338, + 1339, 774, 1510, 1344, 1347, 1348, 1473, 1467, 1466, 1226, + 1140, 1145, 1136, 185, 185, 185, 1111, 1180, 1181, 1182, + 1708, 92, 171, 1824, 1825, 1750, 1970, 185, 1951, 1360, + 185, 474, 1363, 1364, 1707, 186, 488, 1488, 2130, 1910, + 1411, 1414, 1415, 1416, 1412, 186, 1413, 1417, 2122, 1842, + 186, 1827, 1809, 1252, 1176, 1716, 1559, 1279, 1244, 1830, + 1013, 1829, 1563, 1656, 1456, 1655, 1457, 1458, 1459, 1460, + 1297, 1536, 1952, 1953, 2112, 1659, 1657, 2093, 1708, 1558, + 1660, 1658, 1468, 1469, 1470, 1471, 922, 921, 931, 932, + 924, 925, 926, 927, 928, 929, 930, 923, 1177, 1178, + 933, 1661, 1578, 1415, 1416, 1801, 1579, 1286, 1287, 1288, + 1289, 571, 1585, 1624, 1927, 1867, 185, 1586, 1587, 1633, + 1632, 2080, 2077, 1593, 185, 572, 1596, 1597, 1298, 2114, + 2097, 2099, 1571, 2105, 1603, 2104, 1604, 1622, 96, 1607, + 1608, 1609, 1610, 1611, 2047, 1623, 185, 2045, 1017, 1018, + 574, 1239, 573, 1621, 552, 1712, 1350, 185, 185, 185, + 185, 185, 1340, 1341, 1649, 1628, 1644, 1584, 1707, 185, + 1351, 556, 803, 185, 802, 897, 185, 185, 1006, 1735, + 185, 185, 185, 1600, 168, 1734, 1666, 181, 1637, 1686, + 1007, 108, 1000, 1680, 2055, 1612, 2054, 1996, 1620, 1664, + 1665, 1511, 1154, 1153, 1141, 1921, 1379, 1640, 1627, 1386, + 1387, 1493, 1243, 1693, 2015, 1964, 1419, 1631, 1669, 1638, + 1636, 562, 1671, 559, 560, 1630, 1919, 2119, 1692, 2118, + 1695, 1696, 1697, 2102, 2081, 1650, 1683, 1662, 1653, 474, + 1920, 1863, 1690, 1691, 1501, 1667, 1250, 563, 1672, 78, + 1440, 1804, 474, 1675, 1651, 1652, 1635, 1654, 474, 1684, + 1595, 474, 1592, 1148, 1724, 2132, 2131, 558, 474, 1027, + 1728, 1411, 1414, 1415, 1416, 1412, 571, 1413, 1417, 1020, + 1739, 1824, 1825, 2132, 1700, 2048, 1940, 1380, 185, 76, + 572, 81, 1710, 73, 1, 1738, 1709, 445, 1366, 998, + 457, 2120, 1213, 186, 1203, 1880, 1966, 474, 185, 1480, + 1737, 1730, 1128, 568, 569, 574, 1870, 573, 1494, 1704, + 1482, 764, 133, 1332, 1443, 1444, 475, 475, 475, 2062, + 1333, 1736, 89, 1729, 474, 732, 88, 767, 884, 1502, + 1320, 2006, 1961, 1688, 475, 475, 1454, 1938, 1841, 1685, + 2052, 1064, 1062, 1063, 1061, 1066, 1756, 1065, 1060, 1764, + 1765, 1280, 1769, 471, 1418, 1580, 1581, 1053, 1768, 1760, + 474, 1021, 1758, 804, 1759, 1852, 1451, 1277, 1534, 1767, + 185, 1766, 1788, 452, 1782, 871, 1598, 448, 941, 1629, + 474, 1781, 1676, 592, 585, 1815, 474, 474, 95, 2103, + 2078, 1649, 2076, 2044, 1992, 1810, 2079, 2042, 2113, 2096, + 1378, 1009, 1918, 1813, 1803, 1807, 1599, 970, 1352, 185, + 1036, 186, 494, 1290, 1816, 509, 506, 507, 1389, 1641, + 915, 492, 486, 1028, 1410, 1767, 1408, 1407, 1245, 521, + 1040, 1826, 1822, 1034, 1828, 1831, 475, 1393, 1539, 186, + 1744, 186, 186, 1819, 475, 1905, 567, 1844, 1845, 93, + 475, 1833, 1349, 1860, 2031, 1907, 185, 185, 566, 59, + 36, 474, 478, 1832, 1840, 1834, 2089, 1835, 900, 575, + 30, 1797, 1866, 29, 185, 28, 23, 22, 21, 184, + 20, 19, 469, 25, 1856, 1855, 18, 17, 1871, 184, + 16, 1881, 474, 474, 474, 103, 185, 1865, 1818, 46, + 43, 41, 110, 1868, 1857, 1858, 109, 1873, 44, 1874, + 40, 843, 579, 579, 27, 26, 15, 14, 13, 12, + 11, 184, 10, 947, 948, 949, 950, 951, 952, 953, + 954, 955, 956, 1890, 9, 1889, 5, 4, 903, 1891, + 24, 959, 1602, 1886, 1887, 2, 1895, 0, 0, 0, 1900, 1901, 0, 922, 921, 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, 0, 1915, 933, 0, 1649, - 0, 0, 0, 0, 1917, 0, 0, 0, 1922, 0, - 0, 0, 0, 1924, 1925, 0, 1931, 1929, 0, 0, + 1625, 1626, 1011, 0, 1917, 0, 0, 0, 0, 0, + 1922, 0, 0, 1924, 1925, 0, 0, 1929, 1931, 0, 0, 186, 0, 1930, 0, 0, 0, 184, 0, 0, 0, 0, 0, 186, 474, 474, 1936, 184, 0, 0, - 0, 1937, 184, 0, 0, 1955, 0, 474, 475, 0, - 474, 1941, 0, 1943, 0, 1954, 0, 0, 1965, 0, - 0, 0, 0, 1968, 1973, 475, 475, 0, 475, 1959, - 475, 475, 0, 475, 475, 475, 475, 475, 475, 0, - 0, 0, 0, 474, 474, 474, 185, 0, 475, 0, - 1971, 0, 186, 0, 1983, 1985, 1986, 474, 1972, 474, - 0, 0, 1979, 0, 0, 474, 0, 0, 1987, 0, - 1997, 1984, 1995, 1813, 1999, 0, 2002, 1813, 0, 475, - 0, 1988, 1993, 1909, 0, 2001, 0, 186, 0, 185, - 0, 2003, 2009, 186, 2010, 0, 186, 2008, 0, 186, - 474, 185, 0, 0, 0, 0, 485, 0, 2016, 2019, - 186, 2023, 186, 1932, 0, 0, 1933, 0, 0, 1935, + 0, 0, 184, 1955, 0, 0, 0, 474, 475, 0, + 474, 1941, 0, 1943, 166, 1954, 1965, 0, 0, 1937, + 0, 0, 0, 0, 1973, 475, 475, 0, 475, 1959, + 475, 475, 0, 475, 475, 475, 475, 475, 475, 108, + 0, 0, 0, 474, 474, 474, 185, 1971, 475, 150, + 0, 0, 186, 0, 0, 1968, 0, 474, 1972, 474, + 0, 0, 1979, 0, 0, 474, 0, 0, 1989, 1999, + 0, 1984, 1997, 1813, 2004, 0, 1995, 1813, 2001, 475, + 0, 1990, 1987, 1988, 0, 2003, 0, 186, 2011, 185, + 2012, 2005, 2010, 186, 0, 0, 186, 0, 0, 186, + 474, 185, 0, 147, 0, 148, 2018, 0, 2021, 2025, + 186, 0, 186, 0, 165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 475, 186, 475, 475, 186, - 475, 475, 0, 2025, 2026, 2027, 2028, 0, 2032, 2038, - 2033, 2034, 2035, 2046, 2036, 2037, 1813, 0, 1892, 1893, - 0, 1894, 474, 474, 1896, 0, 1898, 0, 2053, 0, - 0, 0, 0, 0, 2058, 1968, 2060, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, - 2068, 0, 0, 0, 1649, 2077, 474, 0, 2064, 0, - 0, 2080, 0, 0, 0, 0, 0, 2083, 0, 2087, - 0, 0, 0, 0, 475, 0, 2096, 2095, 0, 0, - 0, 1992, 485, 0, 0, 0, 0, 0, 0, 0, - 0, 2106, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 174, 175, 176, 0, 0, 475, 475, - 2102, 2103, 0, 0, 0, 0, 0, 0, 2124, 186, - 0, 0, 0, 0, 0, 184, 0, 0, 0, 2134, - 0, 475, 0, 0, 0, 0, 1910, 0, 186, 0, + 475, 475, 0, 2027, 2028, 2029, 2030, 2041, 2034, 0, + 2035, 2036, 2038, 0, 0, 0, 2039, 2040, 1813, 2049, + 1892, 1893, 0, 1894, 474, 474, 1896, 0, 1898, 2056, + 0, 0, 0, 0, 0, 2061, 0, 0, 474, 0, + 0, 0, 151, 0, 0, 0, 0, 0, 0, 1790, + 0, 474, 156, 2073, 0, 0, 0, 1649, 0, 474, + 2067, 2082, 0, 0, 2085, 0, 0, 0, 2088, 1968, + 2063, 0, 2092, 0, 475, 0, 0, 0, 0, 0, + 0, 2101, 2100, 1805, 922, 921, 931, 932, 924, 925, + 926, 927, 928, 929, 930, 923, 2111, 0, 933, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 475, 475, + 0, 0, 0, 0, 0, 2107, 2108, 0, 0, 186, + 0, 0, 0, 2129, 0, 184, 0, 0, 0, 0, + 0, 475, 0, 0, 2139, 0, 0, 0, 186, 0, 0, 475, 0, 0, 0, 186, 0, 186, 0, 0, - 0, 0, 0, 0, 0, 186, 186, 0, 0, 0, - 0, 0, 475, 449, 0, 475, 0, 1905, 0, 0, - 0, 0, 450, 0, 0, 0, 475, 0, 0, 0, - 0, 0, 447, 922, 921, 931, 932, 924, 925, 926, - 927, 928, 929, 930, 923, 0, 0, 933, 0, 0, + 0, 0, 0, 143, 0, 186, 186, 0, 0, 0, + 0, 917, 475, 920, 0, 475, 0, 0, 1904, 934, + 935, 936, 937, 938, 939, 940, 475, 918, 919, 916, + 922, 921, 931, 932, 924, 925, 926, 927, 928, 929, + 930, 923, 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, 1295, 0, 0, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, - 0, 444, 0, 0, 0, 0, 0, 0, 0, 0, - 456, 475, 0, 0, 0, 0, 0, 0, 0, 0, + 1903, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 475, 0, 0, 0, 0, 0, 0, 0, 1909, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 579, 475, 0, - 0, 0, 0, 0, 1357, 0, 0, 0, 0, 0, - 0, 184, 462, 184, 1043, 922, 921, 931, 932, 924, - 925, 926, 927, 928, 929, 930, 923, 0, 0, 933, - 0, 0, 0, 1904, 0, 0, 0, 0, 0, 437, - 438, 439, 475, 454, 455, 465, 1761, 0, 0, 451, - 453, 466, 440, 441, 468, 467, 0, 443, 442, 0, - 461, 446, 463, 0, 0, 0, 922, 921, 931, 932, + 0, 0, 485, 0, 1357, 0, 0, 0, 0, 1932, + 0, 184, 1933, 184, 1043, 1935, 922, 921, 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, 0, 0, - 933, 0, 166, 0, 186, 0, 0, 0, 186, 186, + 933, 0, 1902, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 475, 0, 0, 0, 0, 144, 149, 146, + 152, 153, 154, 155, 157, 158, 159, 160, 0, 0, + 0, 0, 0, 161, 162, 163, 164, 0, 922, 921, + 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, + 0, 0, 933, 0, 186, 0, 0, 0, 186, 186, 186, 186, 186, 0, 0, 0, 0, 0, 186, 186, - 0, 0, 186, 0, 0, 166, 0, 108, 0, 0, - 0, 520, 0, 0, 0, 0, 0, 150, 0, 0, - 186, 186, 186, 0, 0, 0, 0, 0, 0, 0, - 108, 0, 0, 0, 186, 0, 0, 186, 475, 0, - 150, 922, 921, 931, 932, 924, 925, 926, 927, 928, - 929, 930, 923, 0, 0, 933, 0, 0, 1682, 0, - 0, 0, 0, 184, 0, 0, 0, 0, 0, 473, - 1001, 147, 0, 148, 0, 184, 0, 0, 0, 0, - 0, 0, 165, 0, 0, 0, 464, 1903, 0, 0, - 0, 0, 0, 459, 147, 0, 148, 0, 0, 593, - 0, 0, 736, 1151, 743, 165, 0, 0, 460, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 183, 0, 0, 186, 0, 0, 0, 0, 1151, 1151, - 477, 186, 0, 0, 184, 0, 0, 0, 0, 0, - 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 156, 0, 0, 186, 0, 0, 0, 0, 0, 0, - 0, 0, 740, 151, 186, 186, 186, 186, 186, 184, - 0, 0, 0, 156, 0, 184, 186, 0, 184, 0, + 0, 0, 186, 0, 166, 0, 0, 1994, 485, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 186, 186, 186, 520, 0, 0, 0, 0, 0, 108, + 0, 0, 0, 0, 186, 0, 0, 186, 475, 150, + 922, 921, 931, 932, 924, 925, 926, 927, 928, 929, + 930, 923, 0, 0, 933, 0, 0, 0, 0, 0, + 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, + 1682, 473, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 147, 0, 148, 0, 0, 0, 0, + 0, 0, 0, 1151, 165, 0, 0, 0, 0, 0, + 0, 593, 0, 0, 736, 1761, 743, 0, 0, 0, + 0, 0, 0, 186, 0, 0, 0, 0, 1151, 1151, + 0, 186, 0, 0, 184, 922, 921, 931, 932, 924, + 925, 926, 927, 928, 929, 930, 923, 0, 0, 933, + 0, 0, 0, 186, 0, 0, 0, 0, 0, 1001, + 0, 0, 151, 0, 186, 186, 186, 186, 186, 184, + 0, 0, 156, 0, 0, 184, 186, 0, 184, 0, 186, 1249, 0, 186, 186, 0, 0, 186, 186, 186, - 0, 0, 184, 1577, 184, 922, 921, 931, 932, 924, - 925, 926, 927, 928, 929, 930, 923, 0, 184, 933, - 0, 184, 0, 922, 921, 931, 932, 924, 925, 926, - 927, 928, 929, 930, 923, 0, 0, 933, 1572, 1573, - 1574, 0, 0, 0, 0, 0, 0, 0, 833, 0, - 0, 0, 0, 0, 0, 0, 475, 0, 844, 0, - 0, 143, 0, 850, 0, 0, 0, 0, 0, 475, + 0, 0, 184, 0, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 184, 183, + 0, 184, 0, 1577, 0, 0, 0, 0, 0, 477, + 0, 0, 0, 0, 0, 0, 0, 0, 1572, 1573, + 1574, 0, 0, 922, 921, 931, 932, 924, 925, 926, + 927, 928, 929, 930, 923, 0, 475, 933, 0, 0, + 0, 740, 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, 0, 0, 0, 475, 0, 0, 475, 0, - 0, 0, 0, 0, 143, 475, 0, 0, 0, 0, + 0, 0, 0, 143, 0, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 579, 1249, 0, 0, 0, 579, 579, 0, 186, 579, 579, 579, 0, 0, 0, 1151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 186, 0, 0, 0, 0, - 0, 0, 579, 579, 579, 579, 579, 0, 0, 0, - 0, 1374, 0, 0, 0, 0, 0, 0, 0, 0, - 1902, 475, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 579, 579, 579, 579, 579, 833, 0, 0, + 0, 1374, 0, 0, 0, 0, 0, 844, 0, 0, + 0, 475, 850, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, 1249, 184, 0, 184, 0, 0, 0, 0, 0, 0, 0, 184, 184, 0, 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, - 0, 0, 0, 475, 475, 144, 149, 146, 152, 153, - 154, 155, 157, 158, 159, 160, 0, 0, 0, 0, - 0, 161, 162, 163, 164, 0, 186, 0, 144, 149, - 146, 152, 153, 154, 155, 157, 158, 159, 160, 0, - 0, 0, 0, 0, 161, 162, 163, 164, 922, 921, - 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, - 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, - 593, 593, 593, 186, 186, 0, 0, 0, 475, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 899, 901, + 0, 0, 0, 0, 0, 0, 0, 186, 0, 523, + 32, 0, 0, 0, 0, 0, 0, 475, 0, 0, + 0, 0, 0, 475, 475, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32, 0, 0, 0, 186, 144, 149, 146, + 152, 153, 154, 155, 157, 158, 159, 160, 0, 0, + 0, 0, 0, 161, 162, 163, 164, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 557, 0, 0, 0, 0, + 0, 0, 0, 186, 186, 0, 0, 0, 475, 0, + 0, 0, 593, 593, 593, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1762, 1763, 0, 852, 0, 0, 475, + 899, 901, 0, 1762, 1763, 0, 0, 0, 0, 475, 475, 475, 0, 186, 0, 0, 0, 0, 1783, 1784, 0, 1785, 1786, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1792, 1793, 922, 921, 931, 932, 924, 925, - 926, 927, 928, 929, 930, 923, 0, 0, 933, 0, + 0, 0, 1792, 1793, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 184, 184, 184, 184, 184, 0, 0, 0, 0, 0, 184, 184, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1024, 0, 1560, 1561, 184, 0, 0, 0, 593, 0, - 0, 0, 0, 0, 1054, 0, 184, 0, 0, 184, - 0, 0, 0, 1843, 0, 0, 0, 0, 0, 0, - 0, 475, 475, 0, 0, 0, 0, 0, 523, 32, + 0, 0, 1560, 1561, 184, 852, 0, 0, 0, 0, + 0, 0, 1024, 0, 0, 0, 184, 0, 0, 184, + 593, 0, 0, 1843, 0, 0, 1054, 0, 0, 0, + 0, 475, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 0, 0, 475, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1030, 0, 0, 1041, 0, 0, 579, 579, - 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 579, 579, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475, 475, 475, 186, 0, 0, 0, 0, 0, 579, 0, 0, 0, 0, 475, 0, 475, 0, 1888, 0, 0, 0, 475, 0, 0, 184, 0, 0, 0, 0, - 0, 0, 0, 1374, 557, 0, 0, 0, 0, 0, + 0, 0, 0, 1374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, 0, 0, 0, 0, 579, 184, 0, 475, 186, 0, 0, 0, 0, 0, 0, 1151, 184, 184, 184, 184, - 184, 0, 0, 0, 0, 0, 0, 0, 1663, 0, + 184, 1030, 0, 0, 1041, 0, 0, 0, 1663, 0, 0, 0, 184, 0, 0, 184, 184, 0, 0, 184, 1673, 1249, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 736, 0, 0, 0, 0, 0, 0, 475, - 475, 0, 0, 0, 0, 1150, 0, 0, 0, 1156, - 1156, 0, 1156, 0, 1156, 1156, 0, 1165, 1156, 1156, - 1156, 1156, 1156, 0, 1059, 475, 0, 0, 0, 0, - 1150, 1150, 736, 475, 0, 0, 1117, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1974, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 475, 475, 0, 736, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 475, 0, 1150, 0, 0, + 0, 1156, 1156, 0, 1156, 0, 1156, 1156, 475, 1165, + 1156, 1156, 1156, 1156, 1156, 0, 475, 0, 0, 0, + 0, 0, 1150, 1150, 736, 0, 0, 0, 0, 1974, 1975, 1976, 1977, 1978, 0, 1151, 0, 1981, 1982, 0, - 0, 0, 0, 1225, 0, 1249, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, - 0, 0, 0, 0, 0, 1187, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 184, 593, 593, - 0, 593, 593, 0, 593, 593, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1235, 0, 579, 0, 0, 0, 1041, 0, 0, 1246, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1254, 0, 1256, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1270, - 0, 0, 1273, 0, 0, 0, 0, 0, 0, 184, - 0, 0, 0, 0, 0, 0, 0, 0, 1326, 0, - 593, 0, 1151, 0, 0, 0, 0, 0, 0, 0, - 0, 2081, 0, 0, 1150, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, - 0, 0, 1358, 1359, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1390, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1024, 0, 0, 593, 166, - 0, 0, 0, 0, 0, 184, 184, 0, 0, 0, - 0, 0, 0, 1151, 0, 0, 593, 0, 0, 593, - 0, 0, 0, 184, 108, 0, 130, 0, 0, 0, - 736, 0, 0, 0, 150, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 184, 0, 893, 893, 893, - 0, 1397, 0, 0, 0, 0, 0, 0, 1401, 0, - 1404, 0, 0, 0, 0, 140, 0, 32, 0, 1423, - 129, 0, 0, 0, 0, 0, 0, 0, 942, 944, - 0, 0, 0, 0, 0, 743, 0, 0, 147, 0, - 148, 0, 0, 0, 0, 117, 118, 139, 138, 165, - 0, 0, 0, 0, 0, 0, 736, 0, 0, 957, - 1151, 0, 743, 962, 963, 964, 965, 966, 967, 968, - 969, 0, 972, 974, 977, 977, 977, 974, 977, 977, - 974, 977, 990, 991, 992, 993, 994, 995, 996, 0, - 0, 0, 0, 0, 0, 0, 32, 134, 115, 141, - 122, 114, 0, 135, 136, 0, 736, 151, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 156, 123, 0, - 0, 0, 1037, 0, 0, 0, 0, 0, 1081, 0, - 0, 0, 126, 124, 119, 120, 121, 125, 0, 0, - 0, 0, 116, 0, 0, 0, 0, 0, 917, 0, - 920, 127, 0, 0, 0, 1374, 934, 935, 936, 937, - 938, 939, 940, 0, 918, 919, 916, 922, 921, 931, - 932, 924, 925, 926, 927, 928, 929, 930, 923, 0, - 0, 933, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, - 0, 0, 1567, 0, 0, 0, 0, 1041, 0, 0, - 184, 1543, 1544, 1545, 1546, 1547, 0, 0, 143, 0, - 0, 1551, 1552, 0, 0, 1556, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1069, 0, 0, 0, 0, 1562, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1564, 0, 0, - 1566, 0, 0, 0, 0, 0, 0, 137, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, - 0, 0, 132, 1082, 0, 1151, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1150, 0, 1095, - 1098, 1099, 1100, 1101, 1102, 1103, 0, 1104, 1105, 1106, - 1107, 1108, 1083, 1084, 1085, 1086, 1067, 1068, 1096, 0, - 1070, 0, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, - 1079, 1080, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, - 0, 0, 144, 149, 146, 152, 153, 154, 155, 157, - 158, 159, 160, 0, 0, 0, 0, 0, 161, 162, - 163, 164, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1670, 0, 0, - 1713, 0, 0, 0, 0, 893, 893, 0, 893, 893, - 0, 893, 893, 1719, 0, 0, 0, 1150, 0, 1726, - 1097, 0, 1719, 0, 0, 0, 0, 593, 0, 1731, - 33, 34, 35, 68, 37, 38, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 72, 0, 0, 0, 0, 39, 65, 66, 0, 63, - 0, 0, 0, 0, 0, 64, 0, 0, 593, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 52, 593, 0, 0, 0, 0, - 0, 0, 0, 0, 67, 0, 0, 0, 1743, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1757, 0, - 0, 1156, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 593, 0, 0, 1150, 0, 0, 1817, 1156, 0, - 0, 0, 0, 0, 0, 0, 1422, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 42, 45, 48, 47, - 50, 0, 62, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1802, 0, 0, 0, 0, 0, 0, 51, 71, 70, - 0, 0, 60, 61, 49, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 736, 0, 0, 1150, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 53, 54, - 0, 55, 56, 57, 58, 0, 0, 0, 0, 0, - 0, 0, 0, 1882, 1883, 1884, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1861, 1862, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1872, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1885, 0, 0, 0, - 0, 0, 1150, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1719, 1956, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1719, 0, + 0, 0, 0, 0, 0, 1249, 0, 0, 893, 893, + 893, 0, 0, 0, 0, 1225, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 184, 32, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 942, + 944, 0, 0, 0, 0, 0, 0, 184, 0, 0, + 0, 0, 0, 1059, 0, 0, 0, 0, 0, 0, + 593, 593, 0, 593, 593, 1117, 593, 593, 0, 0, + 957, 0, 579, 0, 962, 963, 964, 965, 966, 967, + 968, 969, 0, 972, 974, 977, 977, 977, 974, 977, + 977, 974, 977, 990, 991, 992, 993, 994, 995, 996, + 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, + 0, 0, 0, 0, 1187, 0, 0, 0, 0, 0, + 0, 0, 1151, 1037, 0, 0, 0, 0, 0, 0, + 1326, 0, 593, 0, 2086, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1150, 0, 184, 1235, + 0, 0, 0, 0, 0, 1041, 0, 0, 1246, 0, + 0, 0, 0, 0, 1358, 1359, 0, 166, 0, 0, + 0, 0, 1254, 0, 1256, 0, 0, 0, 1717, 0, + 0, 0, 0, 0, 0, 0, 0, 1390, 1270, 0, + 0, 1273, 108, 0, 130, 184, 184, 1024, 0, 0, + 593, 0, 150, 1151, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 184, 0, 0, 0, 0, 593, 0, 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 736, 140, 0, 184, 0, 0, 129, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 147, 0, 148, 0, + 0, 0, 0, 1131, 1132, 139, 138, 165, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 743, 0, 0, + 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, + 1151, 0, 0, 0, 1127, 0, 0, 0, 736, 0, + 0, 0, 0, 0, 743, 134, 1133, 141, 108, 1130, + 130, 135, 136, 0, 0, 151, 0, 0, 150, 0, + 1397, 0, 0, 0, 0, 156, 0, 1401, 0, 1404, + 0, 0, 0, 0, 0, 0, 0, 0, 1423, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 736, 140, + 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 147, 0, 148, 0, 0, 0, 0, 1131, + 1132, 139, 138, 165, 0, 1374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1719, 1719, 1719, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1998, 0, - 2000, 0, 0, 0, 0, 0, 1719, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1582, 0, 0, 557, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1619, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 893, 893, 0, 893, + 893, 0, 893, 893, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 143, 0, 184, 0, + 0, 134, 1133, 141, 0, 1130, 0, 135, 136, 0, + 184, 151, 0, 0, 1567, 0, 0, 0, 0, 0, + 0, 156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1037, 0, 0, 0, 0, 2015, - 0, 1645, 1646, 593, 593, 1037, 1037, 1037, 1037, 1037, - 0, 2024, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1422, 0, 0, 1037, 0, 0, 1150, 1037, 2078, - 0, 0, 0, 0, 0, 0, 0, 1719, 0, 0, + 0, 0, 0, 0, 0, 137, 0, 0, 0, 33, + 34, 35, 68, 37, 38, 0, 0, 131, 0, 0, + 132, 0, 0, 0, 0, 0, 0, 0, 0, 72, + 0, 0, 0, 0, 39, 65, 66, 0, 63, 0, + 0, 0, 0, 0, 64, 0, 0, 0, 1151, 0, + 0, 0, 0, 0, 0, 0, 1041, 0, 0, 0, + 1543, 1544, 1545, 1546, 1547, 0, 0, 0, 0, 1081, + 1551, 1552, 0, 52, 1556, 0, 0, 0, 0, 0, + 0, 0, 143, 67, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1562, 0, 0, 1422, 0, 1150, + 0, 0, 0, 0, 0, 0, 1564, 0, 0, 1566, + 144, 149, 146, 152, 153, 154, 155, 157, 158, 159, + 160, 0, 0, 0, 0, 0, 161, 162, 163, 164, + 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 131, 0, 0, 132, 0, 0, 0, + 0, 0, 0, 0, 0, 42, 45, 48, 47, 50, + 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1069, 1713, 0, 0, 0, 51, 71, 70, 0, + 0, 60, 61, 49, 0, 1719, 0, 0, 0, 1150, + 0, 1726, 0, 0, 1719, 0, 0, 0, 0, 593, + 0, 1731, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1082, 0, 0, 53, 54, 0, + 55, 56, 57, 58, 0, 0, 144, 149, 146, 152, + 153, 154, 155, 157, 158, 159, 160, 0, 0, 0, + 593, 0, 161, 162, 163, 164, 1670, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1095, 1098, 1099, 1100, 1101, 1102, 1103, 593, 1104, 1105, + 1106, 1107, 1108, 1083, 1084, 1085, 1086, 1067, 1068, 1096, + 0, 1070, 0, 1071, 1072, 1073, 1074, 1075, 1076, 1077, + 1078, 1079, 1080, 1087, 1088, 1089, 1090, 1091, 1092, 1093, + 1094, 0, 0, 1156, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, + 0, 0, 0, 593, 0, 0, 1150, 0, 0, 1817, + 1156, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1743, 0, 0, + 0, 1097, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1757, 0, 0, + 0, 1582, 0, 0, 557, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 736, 0, 0, 1150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1619, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1882, 1883, 1884, 0, 0, + 0, 0, 0, 0, 0, 1037, 0, 0, 0, 1802, + 0, 0, 1645, 1646, 0, 0, 1037, 1037, 1037, 1037, + 1037, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1422, 0, 0, 1037, 0, 0, 0, 1037, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1732, 0, 0, + 0, 0, 0, 0, 1150, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1861, 1862, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1719, 1956, 0, + 0, 0, 0, 1872, 0, 0, 0, 0, 0, 0, + 1719, 0, 0, 593, 0, 0, 0, 0, 1732, 0, + 0, 0, 0, 0, 0, 1885, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 893, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1985, 1985, 1985, 0, + 0, 0, 0, 0, 0, 0, 893, 0, 0, 0, + 2000, 0, 2002, 0, 0, 0, 0, 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1814, 0, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 593, 593, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1037, 0, + 0, 2071, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1150, 0, 2083, 0, 0, 0, 0, 0, + 0, 0, 1719, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1814, 0, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1037, 0, 0, + 2026, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1912, 1913, 1914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1622,744 +1608,517 @@ 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, 0, 1906, 0, 0, 0, - 0, 0, 0, 1912, 1913, 1914, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1814, 0, 32, 0, 1814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1814, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 714, 701, 32, 2057, 652, 717, 623, + 641, 726, 643, 646, 684, 604, 665, 321, 638, 0, + 627, 600, 634, 601, 625, 654, 237, 658, 622, 703, + 668, 716, 280, 0, 628, 334, 686, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 723, 284, 675, 0, 379, 306, 0, 0, 0, + 656, 706, 663, 697, 651, 685, 612, 674, 718, 639, + 682, 719, 270, 221, 192, 318, 380, 249, 0, 0, + 0, 174, 175, 176, 0, 2064, 2065, 0, 0, 0, + 0, 0, 213, 0, 219, 679, 713, 636, 681, 233, + 268, 239, 232, 394, 683, 729, 599, 676, 0, 602, + 605, 725, 709, 631, 632, 0, 0, 0, 0, 0, + 0, 0, 655, 664, 694, 649, 0, 0, 0, 0, + 0, 0, 0, 0, 629, 0, 673, 0, 0, 0, + 608, 603, 0, 0, 0, 0, 653, 0, 0, 0, + 611, 0, 630, 695, 0, 597, 256, 606, 307, 699, + 708, 650, 421, 712, 648, 647, 715, 690, 609, 705, + 642, 279, 607, 276, 188, 202, 0, 640, 317, 355, + 360, 704, 626, 635, 224, 633, 358, 330, 409, 209, + 247, 352, 335, 356, 672, 688, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 621, 700, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 692, 728, 329, 359, 215, 411, 378, + 616, 620, 614, 615, 666, 667, 617, 720, 721, 722, + 696, 610, 0, 618, 619, 0, 702, 710, 711, 671, + 187, 200, 282, 724, 349, 250, 432, 416, 414, 598, + 613, 230, 624, 0, 0, 637, 644, 645, 657, 659, + 660, 661, 662, 670, 677, 678, 680, 687, 689, 691, + 693, 698, 707, 727, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 669, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 714, + 701, 0, 0, 652, 717, 623, 641, 726, 643, 646, + 684, 604, 665, 321, 638, 0, 627, 600, 634, 601, + 625, 654, 237, 658, 622, 703, 668, 716, 280, 0, + 628, 334, 686, 370, 223, 289, 287, 396, 246, 240, + 236, 222, 265, 294, 332, 387, 326, 723, 284, 675, + 0, 379, 306, 0, 0, 0, 656, 706, 663, 697, + 651, 685, 612, 674, 718, 639, 682, 719, 270, 221, + 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, + 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, + 219, 679, 713, 636, 681, 233, 268, 239, 232, 394, + 683, 729, 599, 676, 0, 602, 605, 725, 709, 631, + 632, 0, 0, 0, 0, 0, 0, 0, 655, 664, + 694, 649, 0, 0, 0, 0, 0, 0, 1806, 0, + 629, 0, 673, 0, 0, 0, 608, 603, 0, 0, + 0, 0, 653, 0, 0, 0, 611, 0, 630, 695, + 0, 597, 256, 606, 307, 699, 708, 650, 421, 712, + 648, 647, 715, 690, 609, 705, 642, 279, 607, 276, + 188, 202, 0, 640, 317, 355, 360, 704, 626, 635, + 224, 633, 358, 330, 409, 209, 247, 352, 335, 356, + 672, 688, 357, 285, 398, 347, 408, 422, 423, 231, + 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, + 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, + 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, + 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, + 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, + 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, + 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, + 381, 413, 434, 211, 621, 700, 393, 427, 430, 0, + 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, + 210, 342, 259, 312, 206, 264, 377, 277, 286, 692, + 728, 329, 359, 215, 411, 378, 616, 620, 614, 615, + 666, 667, 617, 720, 721, 722, 696, 610, 0, 618, + 619, 0, 702, 710, 711, 671, 187, 200, 282, 724, + 349, 250, 432, 416, 414, 598, 613, 230, 624, 0, + 0, 637, 644, 645, 657, 659, 660, 661, 662, 670, + 677, 678, 680, 687, 689, 691, 693, 698, 707, 727, + 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, + 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, + 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, + 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, + 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, + 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, + 290, 669, 194, 220, 207, 227, 241, 243, 271, 299, + 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, + 389, 390, 392, 303, 234, 714, 701, 0, 0, 652, + 717, 623, 641, 726, 643, 646, 684, 604, 665, 321, + 638, 0, 627, 600, 634, 601, 625, 654, 237, 658, + 622, 703, 668, 716, 280, 0, 628, 334, 686, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 723, 284, 675, 0, 379, 306, 0, + 0, 0, 656, 706, 663, 697, 651, 685, 612, 674, + 718, 639, 682, 719, 270, 221, 192, 318, 380, 249, + 67, 0, 0, 174, 175, 176, 0, 0, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 679, 713, 636, + 681, 233, 268, 239, 232, 394, 683, 729, 599, 676, + 0, 602, 605, 725, 709, 631, 632, 0, 0, 0, + 0, 0, 0, 0, 655, 664, 694, 649, 0, 0, + 0, 0, 0, 0, 0, 0, 629, 0, 673, 0, + 0, 0, 608, 603, 0, 0, 0, 0, 653, 0, + 0, 0, 611, 0, 630, 695, 0, 597, 256, 606, + 307, 699, 708, 650, 421, 712, 648, 647, 715, 690, + 609, 705, 642, 279, 607, 276, 188, 202, 0, 640, + 317, 355, 360, 704, 626, 635, 224, 633, 358, 330, + 409, 209, 247, 352, 335, 356, 672, 688, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 621, 700, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 692, 728, 329, 359, 215, + 411, 378, 616, 620, 614, 615, 666, 667, 617, 720, + 721, 722, 696, 610, 0, 618, 619, 0, 702, 710, + 711, 671, 187, 200, 282, 724, 349, 250, 432, 416, + 414, 598, 613, 230, 624, 0, 0, 637, 644, 645, + 657, 659, 660, 661, 662, 670, 677, 678, 680, 687, + 689, 691, 693, 698, 707, 727, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 669, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 714, 701, 0, 0, 652, 717, 623, 641, 726, + 643, 646, 684, 604, 665, 321, 638, 0, 627, 600, + 634, 601, 625, 654, 237, 658, 622, 703, 668, 716, + 280, 0, 628, 334, 686, 370, 223, 289, 287, 396, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 723, + 284, 675, 0, 379, 306, 0, 0, 0, 656, 706, + 663, 697, 651, 685, 612, 674, 718, 639, 682, 719, + 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, + 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 219, 679, 713, 636, 681, 233, 268, 239, + 232, 394, 683, 729, 599, 676, 0, 602, 605, 725, + 709, 631, 632, 0, 0, 0, 0, 0, 0, 0, + 655, 664, 694, 649, 0, 0, 0, 0, 0, 0, + 1674, 0, 629, 0, 673, 0, 0, 0, 608, 603, + 0, 0, 0, 0, 653, 0, 0, 0, 611, 0, + 630, 695, 0, 597, 256, 606, 307, 699, 708, 650, + 421, 712, 648, 647, 715, 690, 609, 705, 642, 279, + 607, 276, 188, 202, 0, 640, 317, 355, 360, 704, + 626, 635, 224, 633, 358, 330, 409, 209, 247, 352, + 335, 356, 672, 688, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 621, 700, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, + 286, 692, 728, 329, 359, 215, 411, 378, 616, 620, + 614, 615, 666, 667, 617, 720, 721, 722, 696, 610, + 0, 618, 619, 0, 702, 710, 711, 671, 187, 200, + 282, 724, 349, 250, 432, 416, 414, 598, 613, 230, + 624, 0, 0, 637, 644, 645, 657, 659, 660, 661, + 662, 670, 677, 678, 680, 687, 689, 691, 693, 698, + 707, 727, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 669, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, 714, 701, 0, + 0, 652, 717, 623, 641, 726, 643, 646, 684, 604, + 665, 321, 638, 0, 627, 600, 634, 601, 625, 654, + 237, 658, 622, 703, 668, 716, 280, 0, 628, 334, + 686, 370, 223, 289, 287, 396, 246, 240, 236, 222, + 265, 294, 332, 387, 326, 723, 284, 675, 0, 379, + 306, 0, 0, 0, 656, 706, 663, 697, 651, 685, + 612, 674, 718, 639, 682, 719, 270, 221, 192, 318, + 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, + 0, 0, 0, 0, 0, 0, 213, 0, 219, 679, + 713, 636, 681, 233, 268, 239, 232, 394, 683, 729, + 599, 676, 0, 602, 605, 725, 709, 631, 632, 0, + 0, 0, 0, 0, 0, 0, 655, 664, 694, 649, + 0, 0, 0, 0, 0, 0, 1399, 0, 629, 0, + 673, 0, 0, 0, 608, 603, 0, 0, 0, 0, + 653, 0, 0, 0, 611, 0, 630, 695, 0, 597, + 256, 606, 307, 699, 708, 650, 421, 712, 648, 647, + 715, 690, 609, 705, 642, 279, 607, 276, 188, 202, + 0, 640, 317, 355, 360, 704, 626, 635, 224, 633, + 358, 330, 409, 209, 247, 352, 335, 356, 672, 688, + 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, + 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, + 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, + 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, + 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, + 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, + 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, + 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, + 434, 211, 621, 700, 393, 427, 430, 0, 348, 212, + 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, + 259, 312, 206, 264, 377, 277, 286, 692, 728, 329, + 359, 215, 411, 378, 616, 620, 614, 615, 666, 667, + 617, 720, 721, 722, 696, 610, 0, 618, 619, 0, + 702, 710, 711, 671, 187, 200, 282, 724, 349, 250, + 432, 416, 414, 598, 613, 230, 624, 0, 0, 637, + 644, 645, 657, 659, 660, 661, 662, 670, 677, 678, + 680, 687, 689, 691, 693, 698, 707, 727, 189, 190, + 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, + 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, + 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, + 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, + 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, + 400, 410, 420, 424, 258, 407, 425, 0, 290, 669, + 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, + 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, + 392, 303, 234, 714, 701, 0, 0, 652, 717, 623, + 641, 726, 643, 646, 684, 604, 665, 321, 638, 0, + 627, 600, 634, 601, 625, 654, 237, 658, 622, 703, + 668, 716, 280, 0, 628, 334, 686, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 723, 284, 675, 0, 379, 306, 0, 0, 0, + 656, 706, 663, 697, 651, 685, 612, 674, 718, 639, + 682, 719, 270, 221, 192, 318, 380, 249, 0, 0, + 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, + 0, 0, 213, 0, 219, 679, 713, 636, 681, 233, + 268, 239, 232, 394, 683, 729, 599, 676, 0, 602, + 605, 725, 709, 631, 632, 0, 0, 0, 0, 0, + 0, 0, 655, 664, 694, 649, 0, 0, 0, 0, + 0, 0, 0, 0, 629, 0, 673, 0, 0, 0, + 608, 603, 0, 0, 0, 0, 653, 0, 0, 0, + 611, 0, 630, 695, 0, 597, 256, 606, 307, 699, + 708, 650, 421, 712, 648, 647, 715, 690, 609, 705, + 642, 279, 607, 276, 188, 202, 0, 640, 317, 355, + 360, 704, 626, 635, 224, 633, 358, 330, 409, 209, + 247, 352, 335, 356, 672, 688, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 621, 700, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 692, 728, 329, 359, 215, 411, 378, + 616, 620, 614, 615, 666, 667, 617, 720, 721, 722, + 696, 610, 0, 618, 619, 0, 702, 710, 711, 671, + 187, 200, 282, 724, 349, 250, 432, 416, 414, 598, + 613, 230, 624, 0, 0, 637, 644, 645, 657, 659, + 660, 661, 662, 670, 677, 678, 680, 687, 689, 691, + 693, 698, 707, 727, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 669, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 714, + 701, 0, 0, 652, 717, 623, 641, 726, 643, 646, + 684, 604, 665, 321, 638, 0, 627, 600, 634, 601, + 625, 654, 237, 658, 622, 703, 668, 716, 280, 0, + 628, 334, 686, 370, 223, 289, 287, 396, 246, 240, + 236, 222, 265, 294, 332, 387, 326, 723, 284, 675, + 0, 379, 306, 0, 0, 0, 656, 706, 663, 697, + 651, 685, 612, 674, 718, 639, 682, 719, 270, 221, + 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, + 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, + 219, 679, 713, 636, 681, 233, 268, 239, 232, 394, + 683, 729, 599, 676, 0, 602, 605, 725, 709, 631, + 632, 0, 0, 0, 0, 0, 0, 0, 655, 664, + 694, 649, 0, 0, 0, 0, 0, 0, 0, 0, + 629, 0, 673, 0, 0, 0, 608, 603, 0, 0, + 0, 0, 653, 0, 0, 0, 611, 0, 630, 695, + 0, 597, 256, 606, 307, 699, 708, 650, 421, 712, + 648, 647, 715, 690, 609, 705, 642, 279, 607, 276, + 188, 202, 0, 640, 317, 355, 360, 704, 626, 635, + 224, 633, 358, 330, 409, 209, 247, 352, 335, 356, + 672, 688, 357, 285, 398, 347, 408, 422, 423, 231, + 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, + 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, + 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, + 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, + 402, 225, 433, 204, 418, 199, 731, 417, 313, 397, + 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, + 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, + 381, 413, 434, 211, 621, 700, 393, 427, 430, 0, + 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, + 210, 342, 259, 596, 730, 590, 589, 277, 286, 692, + 728, 329, 359, 215, 411, 378, 616, 620, 614, 615, + 666, 667, 617, 720, 721, 722, 696, 610, 0, 618, + 619, 0, 702, 710, 711, 671, 187, 200, 282, 724, + 349, 250, 432, 416, 414, 598, 613, 230, 624, 0, + 0, 637, 644, 645, 657, 659, 660, 661, 662, 670, + 677, 678, 680, 687, 689, 691, 693, 698, 707, 727, + 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, + 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, + 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, + 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, + 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, + 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, + 290, 669, 194, 220, 207, 227, 241, 243, 271, 299, + 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, + 389, 390, 392, 303, 234, 714, 701, 0, 0, 652, + 717, 623, 641, 726, 643, 646, 684, 604, 665, 321, + 638, 0, 627, 600, 634, 601, 625, 654, 237, 658, + 622, 703, 668, 716, 280, 0, 628, 334, 686, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 723, 284, 675, 0, 379, 306, 0, + 0, 0, 656, 706, 663, 697, 651, 685, 612, 674, + 718, 639, 682, 719, 270, 221, 192, 318, 380, 249, + 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 679, 713, 636, + 681, 233, 268, 239, 232, 394, 683, 729, 599, 676, + 0, 602, 605, 725, 709, 631, 632, 0, 0, 0, + 0, 0, 0, 0, 655, 664, 694, 649, 0, 0, + 0, 0, 0, 0, 0, 0, 629, 0, 673, 0, + 0, 0, 608, 603, 0, 0, 0, 0, 653, 0, + 0, 0, 611, 0, 630, 695, 0, 597, 256, 606, + 307, 699, 708, 650, 421, 712, 648, 647, 715, 690, + 609, 705, 642, 279, 607, 276, 188, 202, 0, 640, + 317, 355, 360, 704, 626, 635, 224, 633, 358, 330, + 409, 209, 247, 352, 335, 356, 672, 688, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 1045, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 731, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 621, 700, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 596, + 730, 590, 589, 277, 286, 692, 728, 329, 359, 215, + 411, 378, 616, 620, 614, 615, 666, 667, 617, 720, + 721, 722, 696, 610, 0, 618, 619, 0, 702, 710, + 711, 671, 187, 200, 282, 724, 349, 250, 432, 416, + 414, 598, 613, 230, 624, 0, 0, 637, 644, 645, + 657, 659, 660, 661, 662, 670, 677, 678, 680, 687, + 689, 691, 693, 698, 707, 727, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 669, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 714, 701, 0, 0, 652, 717, 623, 641, 726, + 643, 646, 684, 604, 665, 321, 638, 0, 627, 600, + 634, 601, 625, 654, 237, 658, 622, 703, 668, 716, + 280, 0, 628, 334, 686, 370, 223, 289, 287, 396, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 723, + 284, 675, 0, 379, 306, 0, 0, 0, 656, 706, + 663, 697, 651, 685, 612, 674, 718, 639, 682, 719, + 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, + 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 219, 679, 713, 636, 681, 233, 268, 239, + 232, 394, 683, 729, 599, 676, 0, 602, 605, 725, + 709, 631, 632, 0, 0, 0, 0, 0, 0, 0, + 655, 664, 694, 649, 0, 0, 0, 0, 0, 0, + 0, 0, 629, 0, 673, 0, 0, 0, 608, 603, + 0, 0, 0, 0, 653, 0, 0, 0, 611, 0, + 630, 695, 0, 597, 256, 606, 307, 699, 708, 650, + 421, 712, 648, 647, 715, 690, 609, 705, 642, 279, + 607, 276, 188, 202, 0, 640, 317, 355, 360, 704, + 626, 635, 224, 633, 358, 330, 409, 209, 247, 352, + 335, 356, 672, 688, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 587, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 731, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 621, 700, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 596, 730, 590, 589, 277, + 286, 692, 728, 329, 359, 215, 411, 378, 616, 620, + 614, 615, 666, 667, 617, 720, 721, 722, 696, 610, + 0, 618, 619, 0, 702, 710, 711, 671, 187, 200, + 282, 724, 349, 250, 432, 416, 414, 598, 613, 230, + 624, 0, 0, 637, 644, 645, 657, 659, 660, 661, + 662, 670, 677, 678, 680, 687, 689, 691, 693, 698, + 707, 727, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 669, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, + 1328, 0, 490, 0, 0, 0, 237, 0, 489, 0, + 0, 0, 280, 0, 1329, 334, 0, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, + 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, + 0, 0, 270, 221, 192, 318, 380, 249, 67, 0, + 0, 174, 175, 176, 511, 510, 513, 514, 515, 516, + 0, 0, 213, 512, 219, 517, 518, 519, 0, 233, + 268, 239, 232, 394, 0, 0, 0, 487, 504, 0, + 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 501, 502, 577, 0, 0, 0, 548, 0, 503, 0, + 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 0, 307, 547, + 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, + 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, + 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, + 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, + 535, 546, 541, 542, 539, 540, 534, 538, 537, 536, + 549, 526, 527, 528, 529, 531, 0, 543, 544, 530, + 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1814, 0, 32, 0, 1814, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, + 0, 0, 0, 0, 490, 0, 0, 0, 237, 0, + 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, + 0, 0, 1438, 0, 270, 221, 192, 318, 380, 249, + 67, 0, 0, 174, 175, 176, 511, 510, 513, 514, + 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, + 1439, 233, 268, 239, 232, 394, 0, 0, 0, 487, + 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 501, 502, 0, 0, 0, 0, 548, 0, + 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, + 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, + 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, + 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, + 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, + 411, 378, 535, 546, 541, 542, 539, 540, 534, 538, + 537, 536, 549, 526, 527, 528, 529, 531, 0, 543, + 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, + 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1814, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 714, 701, 32, 2054, 652, 717, 623, 641, 726, 643, - 646, 684, 604, 665, 321, 638, 0, 627, 600, 634, - 601, 625, 654, 237, 658, 622, 703, 668, 716, 280, - 0, 628, 334, 686, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 723, 284, - 675, 0, 379, 306, 0, 0, 0, 656, 706, 663, - 697, 651, 685, 612, 674, 718, 639, 682, 719, 270, - 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 2061, 2062, 0, 0, 0, 0, 0, 213, - 0, 219, 679, 713, 636, 681, 233, 268, 239, 232, - 394, 683, 729, 599, 676, 0, 602, 605, 725, 709, - 631, 632, 0, 0, 0, 0, 0, 0, 0, 655, - 664, 694, 649, 0, 0, 0, 0, 0, 0, 0, - 0, 629, 0, 673, 0, 0, 0, 608, 603, 0, - 0, 0, 0, 653, 0, 0, 0, 611, 0, 630, - 695, 0, 597, 256, 606, 307, 699, 708, 650, 421, - 712, 648, 647, 715, 690, 609, 705, 642, 279, 607, - 276, 188, 202, 0, 640, 317, 355, 360, 704, 626, - 635, 224, 633, 358, 330, 409, 209, 247, 352, 335, - 356, 672, 688, 357, 285, 398, 347, 408, 422, 423, - 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, - 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, - 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, - 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, - 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, - 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, - 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 621, 700, 393, 427, 430, - 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, - 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 692, 728, 329, 359, 215, 411, 378, 616, 620, 614, - 615, 666, 667, 617, 720, 721, 722, 696, 610, 0, - 618, 619, 0, 702, 710, 711, 671, 187, 200, 282, - 724, 349, 250, 432, 416, 414, 598, 613, 230, 624, - 0, 0, 637, 644, 645, 657, 659, 660, 661, 662, - 670, 677, 678, 680, 687, 689, 691, 693, 698, 707, - 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, - 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, - 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, - 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, - 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 669, 194, 220, 207, 227, 241, 243, 271, - 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 714, 701, 0, 0, - 652, 717, 623, 641, 726, 643, 646, 684, 604, 665, - 321, 638, 0, 627, 600, 634, 601, 625, 654, 237, - 658, 622, 703, 668, 716, 280, 0, 628, 334, 686, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 723, 284, 675, 0, 379, 306, - 0, 0, 0, 656, 706, 663, 697, 651, 685, 612, - 674, 718, 639, 682, 719, 270, 221, 192, 318, 380, - 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 679, 713, - 636, 681, 233, 268, 239, 232, 394, 683, 729, 599, - 676, 0, 602, 605, 725, 709, 631, 632, 0, 0, - 0, 0, 0, 0, 0, 655, 664, 694, 649, 0, - 0, 0, 0, 0, 0, 1806, 0, 629, 0, 673, - 0, 0, 0, 608, 603, 0, 0, 0, 0, 653, - 0, 0, 0, 611, 0, 630, 695, 0, 597, 256, - 606, 307, 699, 708, 650, 421, 712, 648, 647, 715, - 690, 609, 705, 642, 279, 607, 276, 188, 202, 0, - 640, 317, 355, 360, 704, 626, 635, 224, 633, 358, - 330, 409, 209, 247, 352, 335, 356, 672, 688, 357, - 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, - 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, - 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, - 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, - 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, - 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, - 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, - 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, - 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 312, 206, 264, 377, 277, 286, 692, 728, 329, 359, - 215, 411, 378, 616, 620, 614, 615, 666, 667, 617, - 720, 721, 722, 696, 610, 0, 618, 619, 0, 702, - 710, 711, 671, 187, 200, 282, 724, 349, 250, 432, - 416, 414, 598, 613, 230, 624, 0, 0, 637, 644, - 645, 657, 659, 660, 661, 662, 670, 677, 678, 680, - 687, 689, 691, 693, 698, 707, 727, 189, 190, 201, - 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, - 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, - 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, - 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, - 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 669, 194, - 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, - 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 714, 701, 0, 0, 652, 717, 623, 641, - 726, 643, 646, 684, 604, 665, 321, 638, 0, 627, - 600, 634, 601, 625, 654, 237, 658, 622, 703, 668, - 716, 280, 0, 628, 334, 686, 370, 223, 289, 287, - 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 723, 284, 675, 0, 379, 306, 0, 0, 0, 656, - 706, 663, 697, 651, 685, 612, 674, 718, 639, 682, - 719, 270, 221, 192, 318, 380, 249, 67, 0, 0, - 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, - 0, 213, 0, 219, 679, 713, 636, 681, 233, 268, - 239, 232, 394, 683, 729, 599, 676, 0, 602, 605, - 725, 709, 631, 632, 0, 0, 0, 0, 0, 0, - 0, 655, 664, 694, 649, 0, 0, 0, 0, 0, - 0, 0, 0, 629, 0, 673, 0, 0, 0, 608, - 603, 0, 0, 0, 0, 653, 0, 0, 0, 611, - 0, 630, 695, 0, 597, 256, 606, 307, 699, 708, - 650, 421, 712, 648, 647, 715, 690, 609, 705, 642, - 279, 607, 276, 188, 202, 0, 640, 317, 355, 360, - 704, 626, 635, 224, 633, 358, 330, 409, 209, 247, - 352, 335, 356, 672, 688, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 621, 700, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 692, 728, 329, 359, 215, 411, 378, 616, - 620, 614, 615, 666, 667, 617, 720, 721, 722, 696, - 610, 0, 618, 619, 0, 702, 710, 711, 671, 187, - 200, 282, 724, 349, 250, 432, 416, 414, 598, 613, - 230, 624, 0, 0, 637, 644, 645, 657, 659, 660, - 661, 662, 670, 677, 678, 680, 687, 689, 691, 693, - 698, 707, 727, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 669, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 714, 701, - 0, 0, 652, 717, 623, 641, 726, 643, 646, 684, - 604, 665, 321, 638, 0, 627, 600, 634, 601, 625, - 654, 237, 658, 622, 703, 668, 716, 280, 0, 628, - 334, 686, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 723, 284, 675, 0, - 379, 306, 0, 0, 0, 656, 706, 663, 697, 651, - 685, 612, 674, 718, 639, 682, 719, 270, 221, 192, - 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, - 679, 713, 636, 681, 233, 268, 239, 232, 394, 683, - 729, 599, 676, 0, 602, 605, 725, 709, 631, 632, - 0, 0, 0, 0, 0, 0, 0, 655, 664, 694, - 649, 0, 0, 0, 0, 0, 0, 1674, 0, 629, - 0, 673, 0, 0, 0, 608, 603, 0, 0, 0, - 0, 653, 0, 0, 0, 611, 0, 630, 695, 0, - 597, 256, 606, 307, 699, 708, 650, 421, 712, 648, - 647, 715, 690, 609, 705, 642, 279, 607, 276, 188, - 202, 0, 640, 317, 355, 360, 704, 626, 635, 224, - 633, 358, 330, 409, 209, 247, 352, 335, 356, 672, - 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, - 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, - 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, - 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, - 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, - 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, - 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, - 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, - 413, 434, 211, 621, 700, 393, 427, 430, 0, 348, - 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, - 342, 259, 312, 206, 264, 377, 277, 286, 692, 728, - 329, 359, 215, 411, 378, 616, 620, 614, 615, 666, - 667, 617, 720, 721, 722, 696, 610, 0, 618, 619, - 0, 702, 710, 711, 671, 187, 200, 282, 724, 349, - 250, 432, 416, 414, 598, 613, 230, 624, 0, 0, - 637, 644, 645, 657, 659, 660, 661, 662, 670, 677, - 678, 680, 687, 689, 691, 693, 698, 707, 727, 189, - 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, - 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, - 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, - 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, - 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, - 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, - 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, - 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 714, 701, 0, 0, 652, 717, - 623, 641, 726, 643, 646, 684, 604, 665, 321, 638, - 0, 627, 600, 634, 601, 625, 654, 237, 658, 622, - 703, 668, 716, 280, 0, 628, 334, 686, 370, 223, - 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 723, 284, 675, 0, 379, 306, 0, 0, - 0, 656, 706, 663, 697, 651, 685, 612, 674, 718, - 639, 682, 719, 270, 221, 192, 318, 380, 249, 0, - 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 0, 219, 679, 713, 636, 681, - 233, 268, 239, 232, 394, 683, 729, 599, 676, 0, - 602, 605, 725, 709, 631, 632, 0, 0, 0, 0, - 0, 0, 0, 655, 664, 694, 649, 0, 0, 0, - 0, 0, 0, 1399, 0, 629, 0, 673, 0, 0, - 0, 608, 603, 0, 0, 0, 0, 653, 0, 0, - 0, 611, 0, 630, 695, 0, 597, 256, 606, 307, - 699, 708, 650, 421, 712, 648, 647, 715, 690, 609, - 705, 642, 279, 607, 276, 188, 202, 0, 640, 317, - 355, 360, 704, 626, 635, 224, 633, 358, 330, 409, - 209, 247, 352, 335, 356, 672, 688, 357, 285, 398, - 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, - 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, - 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, - 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, - 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, - 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, - 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, - 308, 310, 0, 193, 0, 381, 413, 434, 211, 621, - 700, 393, 427, 430, 0, 348, 212, 253, 244, 344, - 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, - 264, 377, 277, 286, 692, 728, 329, 359, 215, 411, - 378, 616, 620, 614, 615, 666, 667, 617, 720, 721, - 722, 696, 610, 0, 618, 619, 0, 702, 710, 711, - 671, 187, 200, 282, 724, 349, 250, 432, 416, 414, - 598, 613, 230, 624, 0, 0, 637, 644, 645, 657, - 659, 660, 661, 662, 670, 677, 678, 680, 687, 689, - 691, 693, 698, 707, 727, 189, 190, 201, 208, 217, - 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, - 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, - 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, - 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, - 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, - 424, 258, 407, 425, 0, 290, 669, 194, 220, 207, - 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, - 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 714, 701, 0, 0, 652, 717, 623, 641, 726, 643, - 646, 684, 604, 665, 321, 638, 0, 627, 600, 634, - 601, 625, 654, 237, 658, 622, 703, 668, 716, 280, - 0, 628, 334, 686, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 723, 284, - 675, 0, 379, 306, 0, 0, 0, 656, 706, 663, - 697, 651, 685, 612, 674, 718, 639, 682, 719, 270, - 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, - 0, 219, 679, 713, 636, 681, 233, 268, 239, 232, - 394, 683, 729, 599, 676, 0, 602, 605, 725, 709, - 631, 632, 0, 0, 0, 0, 0, 0, 0, 655, - 664, 694, 649, 0, 0, 0, 0, 0, 0, 0, - 0, 629, 0, 673, 0, 0, 0, 608, 603, 0, - 0, 0, 0, 653, 0, 0, 0, 611, 0, 630, - 695, 0, 597, 256, 606, 307, 699, 708, 650, 421, - 712, 648, 647, 715, 690, 609, 705, 642, 279, 607, - 276, 188, 202, 0, 640, 317, 355, 360, 704, 626, - 635, 224, 633, 358, 330, 409, 209, 247, 352, 335, - 356, 672, 688, 357, 285, 398, 347, 408, 422, 423, - 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, - 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, - 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, - 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, - 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, - 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, - 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 621, 700, 393, 427, 430, - 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, - 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 692, 728, 329, 359, 215, 411, 378, 616, 620, 614, - 615, 666, 667, 617, 720, 721, 722, 696, 610, 0, - 618, 619, 0, 702, 710, 711, 671, 187, 200, 282, - 724, 349, 250, 432, 416, 414, 598, 613, 230, 624, - 0, 0, 637, 644, 645, 657, 659, 660, 661, 662, - 670, 677, 678, 680, 687, 689, 691, 693, 698, 707, - 727, 189, 190, 201, 208, 217, 229, 242, 248, 257, - 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, - 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, - 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, - 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 669, 194, 220, 207, 227, 241, 243, 271, - 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 714, 701, 0, 0, - 652, 717, 623, 641, 726, 643, 646, 684, 604, 665, - 321, 638, 0, 627, 600, 634, 601, 625, 654, 237, - 658, 622, 703, 668, 716, 280, 0, 628, 334, 686, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 723, 284, 675, 0, 379, 306, - 0, 0, 0, 656, 706, 663, 697, 651, 685, 612, - 674, 718, 639, 682, 719, 270, 221, 192, 318, 380, - 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 679, 713, - 636, 681, 233, 268, 239, 232, 394, 683, 729, 599, - 676, 0, 602, 605, 725, 709, 631, 632, 0, 0, - 0, 0, 0, 0, 0, 655, 664, 694, 649, 0, - 0, 0, 0, 0, 0, 0, 0, 629, 0, 673, - 0, 0, 0, 608, 603, 0, 0, 0, 0, 653, - 0, 0, 0, 611, 0, 630, 695, 0, 597, 256, - 606, 307, 699, 708, 650, 421, 712, 648, 647, 715, - 690, 609, 705, 642, 279, 607, 276, 188, 202, 0, - 640, 317, 355, 360, 704, 626, 635, 224, 633, 358, - 330, 409, 209, 247, 352, 335, 356, 672, 688, 357, - 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, - 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, - 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, - 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, - 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, - 204, 418, 199, 731, 417, 313, 397, 405, 302, 293, - 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, - 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 621, 700, 393, 427, 430, 0, 348, 212, 253, - 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 596, 730, 590, 589, 277, 286, 692, 728, 329, 359, - 215, 411, 378, 616, 620, 614, 615, 666, 667, 617, - 720, 721, 722, 696, 610, 0, 618, 619, 0, 702, - 710, 711, 671, 187, 200, 282, 724, 349, 250, 432, - 416, 414, 598, 613, 230, 624, 0, 0, 637, 644, - 645, 657, 659, 660, 661, 662, 670, 677, 678, 680, - 687, 689, 691, 693, 698, 707, 727, 189, 190, 201, - 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, - 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, - 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, - 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, - 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 669, 194, - 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, - 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 714, 701, 0, 0, 652, 717, 623, 641, - 726, 643, 646, 684, 604, 665, 321, 638, 0, 627, - 600, 634, 601, 625, 654, 237, 658, 622, 703, 668, - 716, 280, 0, 628, 334, 686, 370, 223, 289, 287, - 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 723, 284, 675, 0, 379, 306, 0, 0, 0, 656, - 706, 663, 697, 651, 685, 612, 674, 718, 639, 682, - 719, 270, 221, 192, 318, 380, 249, 0, 0, 0, - 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, - 0, 213, 0, 219, 679, 713, 636, 681, 233, 268, - 239, 232, 394, 683, 729, 599, 676, 0, 602, 605, - 725, 709, 631, 632, 0, 0, 0, 0, 0, 0, - 0, 655, 664, 694, 649, 0, 0, 0, 0, 0, - 0, 0, 0, 629, 0, 673, 0, 0, 0, 608, - 603, 0, 0, 0, 0, 653, 0, 0, 0, 611, - 0, 630, 695, 0, 597, 256, 606, 307, 699, 708, - 650, 421, 712, 648, 647, 715, 690, 609, 705, 642, - 279, 607, 276, 188, 202, 0, 640, 317, 355, 360, - 704, 626, 635, 224, 633, 358, 330, 409, 209, 247, - 352, 335, 356, 672, 688, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 1045, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 731, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 621, 700, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 596, 730, 590, 589, - 277, 286, 692, 728, 329, 359, 215, 411, 378, 616, - 620, 614, 615, 666, 667, 617, 720, 721, 722, 696, - 610, 0, 618, 619, 0, 702, 710, 711, 671, 187, - 200, 282, 724, 349, 250, 432, 416, 414, 598, 613, - 230, 624, 0, 0, 637, 644, 645, 657, 659, 660, - 661, 662, 670, 677, 678, 680, 687, 689, 691, 693, - 698, 707, 727, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 669, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 714, 701, - 0, 0, 652, 717, 623, 641, 726, 643, 646, 684, - 604, 665, 321, 638, 0, 627, 600, 634, 601, 625, - 654, 237, 658, 622, 703, 668, 716, 280, 0, 628, - 334, 686, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 723, 284, 675, 0, - 379, 306, 0, 0, 0, 656, 706, 663, 697, 651, - 685, 612, 674, 718, 639, 682, 719, 270, 221, 192, - 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, - 679, 713, 636, 681, 233, 268, 239, 232, 394, 683, - 729, 599, 676, 0, 602, 605, 725, 709, 631, 632, - 0, 0, 0, 0, 0, 0, 0, 655, 664, 694, - 649, 0, 0, 0, 0, 0, 0, 0, 0, 629, - 0, 673, 0, 0, 0, 608, 603, 0, 0, 0, - 0, 653, 0, 0, 0, 611, 0, 630, 695, 0, - 597, 256, 606, 307, 699, 708, 650, 421, 712, 648, - 647, 715, 690, 609, 705, 642, 279, 607, 276, 188, - 202, 0, 640, 317, 355, 360, 704, 626, 635, 224, - 633, 358, 330, 409, 209, 247, 352, 335, 356, 672, - 688, 357, 285, 398, 347, 408, 422, 423, 231, 311, - 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, - 304, 395, 275, 375, 254, 191, 283, 195, 386, 587, - 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, - 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, - 225, 433, 204, 418, 199, 731, 417, 313, 397, 405, - 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, - 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, - 413, 434, 211, 621, 700, 393, 427, 430, 0, 348, - 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, - 342, 259, 596, 730, 590, 589, 277, 286, 692, 728, - 329, 359, 215, 411, 378, 616, 620, 614, 615, 666, - 667, 617, 720, 721, 722, 696, 610, 0, 618, 619, - 0, 702, 710, 711, 671, 187, 200, 282, 724, 349, - 250, 432, 416, 414, 598, 613, 230, 624, 0, 0, - 637, 644, 645, 657, 659, 660, 661, 662, 670, 677, - 678, 680, 687, 689, 691, 693, 698, 707, 727, 189, - 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, - 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, - 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, - 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, - 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, - 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, - 669, 194, 220, 207, 227, 241, 243, 271, 299, 305, - 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 1328, 0, 490, - 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, - 0, 1329, 334, 0, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, - 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, - 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, - 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, - 176, 511, 510, 513, 514, 515, 516, 0, 0, 213, - 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, - 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 501, 502, 577, - 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, - 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, - 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, - 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, - 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, - 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, - 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, - 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, - 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, - 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, - 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, - 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, - 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, - 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, - 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 0, 0, 329, 359, 215, 411, 378, 535, 546, 541, - 542, 539, 540, 534, 538, 537, 536, 549, 526, 527, - 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, - 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, - 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, - 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, - 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, - 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, - 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, - 0, 490, 0, 0, 0, 237, 0, 489, 0, 0, - 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, - 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, - 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, - 0, 524, 525, 0, 0, 0, 0, 0, 0, 1438, - 0, 270, 221, 192, 318, 380, 249, 67, 0, 0, - 174, 175, 176, 511, 510, 513, 514, 515, 516, 0, - 0, 213, 512, 219, 517, 518, 519, 1439, 233, 268, - 239, 232, 394, 0, 0, 0, 487, 504, 0, 532, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, - 502, 0, 0, 0, 0, 548, 0, 503, 0, 0, - 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 256, 0, 307, 547, 0, - 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, - 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, - 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, - 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 0, 0, 329, 359, 215, 411, 378, 535, - 546, 541, 542, 539, 540, 534, 538, 537, 536, 549, - 526, 527, 528, 529, 531, 0, 543, 544, 530, 187, - 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, - 0, 0, 0, 490, 0, 0, 0, 237, 0, 489, - 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, - 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, - 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, - 0, 0, 0, 270, 221, 192, 318, 380, 249, 67, - 0, 565, 174, 175, 176, 511, 510, 513, 514, 515, - 516, 0, 0, 213, 512, 219, 517, 518, 519, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 487, 504, - 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 501, 502, 0, 0, 0, 0, 548, 0, 503, - 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, - 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, - 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, - 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, - 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, - 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, - 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, - 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, - 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, - 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, - 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, - 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, - 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, - 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, - 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 535, 546, 541, 542, 539, 540, 534, 538, 537, - 536, 549, 526, 527, 528, 529, 531, 0, 543, 544, - 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, - 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, - 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, - 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, - 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, - 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, - 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, - 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, - 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 0, 0, 0, 490, 0, 0, 0, 237, - 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, - 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, - 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, - 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 67, 0, 0, 174, 175, 176, 511, 510, 513, - 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, - 519, 0, 233, 268, 239, 232, 394, 0, 0, 0, - 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 501, 502, 577, 0, 0, 0, 548, - 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, - 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, - 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, - 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, - 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, - 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, - 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, - 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, - 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, - 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, - 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, - 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, - 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, - 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 535, 546, 541, 542, 539, 540, 534, - 538, 537, 536, 549, 526, 527, 528, 529, 531, 0, - 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, - 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, - 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, - 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, - 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, - 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, - 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, - 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, - 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, - 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 321, 0, 0, 0, 0, 490, 0, 0, - 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, - 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, - 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, - 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, - 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, - 318, 380, 249, 67, 0, 0, 174, 175, 176, 511, - 1346, 513, 514, 515, 516, 0, 0, 213, 512, 219, - 517, 518, 519, 0, 233, 268, 239, 232, 394, 0, - 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 501, 502, 577, 0, 0, - 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, - 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 256, 0, 307, 547, 0, 0, 421, 0, 0, - 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, - 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, - 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, - 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, - 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, - 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, - 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, - 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, - 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, - 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, - 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, - 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, - 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, - 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, - 329, 359, 215, 411, 378, 535, 546, 541, 542, 539, - 540, 534, 538, 537, 536, 549, 526, 527, 528, 529, - 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, - 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, - 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, - 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, - 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, - 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, - 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, - 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, - 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, - 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 0, 0, 490, - 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, - 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, - 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, - 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, - 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, - 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, - 176, 511, 1343, 513, 514, 515, 516, 0, 0, 213, - 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, - 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 501, 502, 577, - 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, - 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, - 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, - 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, - 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, - 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, - 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, - 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, - 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, - 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, - 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, - 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, - 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, - 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, - 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, - 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, - 0, 0, 329, 359, 215, 411, 378, 535, 546, 541, - 542, 539, 540, 534, 538, 537, 536, 549, 526, 527, - 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, - 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, - 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, - 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, - 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, - 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, - 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, - 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 558, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 0, 0, 0, 0, 490, 0, 0, 0, 237, 0, - 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, - 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 67, 0, 0, 174, 175, 176, 511, 510, 513, 514, - 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 487, - 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 501, 502, 0, 0, 0, 0, 548, 0, - 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 535, 546, 541, 542, 539, 540, 534, 538, - 537, 536, 549, 526, 527, 528, 529, 531, 0, 543, - 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 0, 490, 0, 0, 0, - 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, - 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, - 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, - 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 67, 0, 0, 174, 175, 176, 511, 510, - 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, - 518, 519, 0, 233, 268, 239, 232, 394, 0, 0, - 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 321, 0, 0, 0, 0, 490, 0, 0, 0, + 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, + 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, + 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, + 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, + 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, + 380, 249, 67, 0, 565, 174, 175, 176, 511, 510, + 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, + 518, 519, 0, 233, 268, 239, 232, 394, 0, 0, + 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, 0, 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, 500, @@ -2393,8 +2152,8 @@ var yyAct = [...]int{ 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, + 392, 303, 234, 321, 0, 0, 0, 0, 490, 0, + 0, 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, 525, @@ -2402,16 +2161,16 @@ var yyAct = [...]int{ 192, 318, 380, 249, 67, 0, 0, 174, 175, 176, 511, 510, 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, 394, - 0, 0, 0, 0, 504, 0, 532, 0, 0, 0, + 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 501, 502, 0, 0, + 0, 0, 0, 0, 0, 0, 501, 502, 577, 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 2082, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, @@ -2437,18 +2196,18 @@ var yyAct = [...]int{ 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 490, 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 67, 0, 565, 174, - 175, 176, 511, 510, 513, 514, 515, 516, 0, 0, + 270, 221, 192, 318, 380, 249, 67, 0, 0, 174, + 175, 176, 511, 1346, 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, 0, 233, 268, 239, - 232, 394, 0, 0, 0, 0, 504, 0, 532, 0, + 232, 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, - 0, 0, 0, 0, 548, 0, 503, 0, 0, 496, + 577, 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, @@ -2480,18 +2239,18 @@ var yyAct = [...]int{ 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 490, 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 67, 0, - 0, 174, 175, 176, 511, 510, 513, 514, 515, 516, + 0, 174, 175, 176, 511, 1343, 513, 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, 519, 0, 233, - 268, 239, 232, 394, 0, 0, 0, 0, 504, 0, + 268, 239, 232, 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 501, 502, 0, 0, 0, 0, 548, 0, 503, 0, + 501, 502, 577, 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, @@ -2518,157 +2277,157 @@ var yyAct = [...]int{ 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 922, 921, - 931, 932, 924, 925, 926, 927, 928, 929, 930, 923, - 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 772, 0, 0, 0, 0, 280, 0, 0, 334, - 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, - 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, - 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, - 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 256, 0, 307, 0, 0, 771, 421, 0, 0, 0, - 0, 0, 0, 768, 769, 279, 739, 276, 188, 202, - 762, 766, 317, 355, 360, 0, 0, 0, 224, 0, - 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, - 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, - 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, - 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, - 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, - 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, - 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, - 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, - 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, - 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, - 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, - 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, - 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 558, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, - 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, + 0, 0, 321, 0, 0, 0, 0, 490, 0, 0, + 0, 237, 0, 489, 0, 0, 0, 280, 0, 0, + 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, + 222, 265, 294, 332, 387, 326, 533, 284, 0, 0, + 379, 306, 0, 0, 0, 0, 0, 524, 525, 0, + 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, + 318, 380, 249, 67, 0, 0, 174, 175, 176, 511, + 510, 513, 514, 515, 516, 0, 0, 213, 512, 219, + 517, 518, 519, 0, 233, 268, 239, 232, 394, 0, + 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, - 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, - 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, - 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, - 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, - 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, - 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, - 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, - 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 0, 0, 1023, 0, 0, - 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, - 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, - 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, - 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 1025, 0, 0, 0, 0, 0, 0, 213, 0, - 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, - 911, 912, 910, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 913, 0, + 0, 0, 0, 0, 0, 501, 502, 0, 0, 0, + 0, 548, 0, 503, 0, 0, 496, 497, 499, 498, + 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 256, 0, 307, 547, 0, 0, 421, 0, 0, + 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, + 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, + 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, + 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, + 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, + 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, + 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, + 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, + 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, + 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, + 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, + 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, + 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, + 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, + 329, 359, 215, 411, 378, 535, 546, 541, 542, 539, + 540, 534, 538, 537, 536, 549, 526, 527, 528, 529, + 531, 0, 543, 544, 530, 187, 200, 282, 0, 349, + 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, + 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, + 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, + 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, + 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, + 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, + 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, + 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, + 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, + 390, 392, 303, 234, 321, 0, 0, 0, 0, 490, + 0, 0, 0, 237, 0, 489, 0, 0, 0, 280, + 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 533, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 524, + 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, + 176, 511, 510, 513, 514, 515, 516, 0, 0, 213, + 512, 219, 517, 518, 519, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 487, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 501, 502, 0, + 0, 0, 0, 548, 0, 503, 0, 0, 496, 497, + 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 307, 547, 0, 0, 421, + 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, + 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, + 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 0, 0, 329, 359, 215, 411, 378, 535, 546, 541, + 542, 539, 540, 534, 538, 537, 536, 549, 526, 527, + 528, 529, 531, 0, 543, 544, 530, 187, 200, 282, + 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, - 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, - 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, - 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, - 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, - 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, - 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, - 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, - 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, - 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, - 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, - 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, - 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, - 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, - 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 187, 200, 282, 0, - 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, + 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, + 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 533, 284, 0, 0, 379, 306, 0, 0, 0, 0, + 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, + 0, 270, 221, 192, 318, 380, 249, 67, 0, 0, + 174, 175, 176, 511, 510, 513, 514, 515, 516, 0, + 0, 213, 512, 219, 517, 518, 519, 0, 233, 268, + 239, 232, 394, 0, 0, 0, 0, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, + 502, 0, 0, 0, 0, 548, 0, 503, 0, 0, + 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 547, 0, + 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 2087, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 535, + 546, 541, 542, 539, 540, 534, 538, 537, 536, 549, + 526, 527, 528, 529, 531, 0, 543, 544, 530, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, - 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, - 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, - 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, - 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, - 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, - 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, - 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 33, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 321, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 387, 326, 533, 284, 0, 0, 379, 306, 0, 0, + 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 67, - 0, 565, 174, 175, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 565, 174, 175, 176, 511, 510, 513, 514, 515, + 516, 0, 0, 213, 512, 219, 517, 518, 519, 0, + 233, 268, 239, 232, 394, 0, 0, 0, 0, 504, + 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 501, 502, 0, 0, 0, 0, 548, 0, 503, + 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, @@ -2683,9 +2442,9 @@ var yyAct = [...]int{ 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, + 378, 535, 546, 541, 542, 539, 540, 534, 538, 537, + 536, 549, 526, 527, 528, 529, 531, 0, 543, 544, + 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, @@ -2697,24 +2456,24 @@ var yyAct = [...]int{ 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 0, 0, 1373, 0, 0, 0, 0, 237, + 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, - 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 294, 332, 387, 326, 533, 284, 0, 0, 379, 306, + 0, 0, 0, 0, 0, 524, 525, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, - 249, 0, 0, 0, 174, 175, 176, 0, 1375, 0, - 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, - 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 249, 67, 0, 0, 174, 175, 176, 511, 510, 513, + 514, 515, 516, 0, 0, 213, 512, 219, 517, 518, + 519, 0, 233, 268, 239, 232, 394, 0, 0, 0, + 0, 504, 0, 532, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 501, 502, 0, 0, 0, 0, 548, + 0, 503, 0, 0, 496, 497, 499, 498, 500, 505, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, - 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, + 0, 307, 547, 0, 0, 421, 0, 0, 545, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, - 330, 409, 209, 247, 352, 335, 356, 0, 1371, 357, + 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, @@ -2726,9 +2485,9 @@ var yyAct = [...]int{ 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, - 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, + 215, 411, 378, 535, 546, 541, 542, 539, 540, 534, + 538, 537, 536, 549, 526, 527, 528, 529, 531, 0, + 543, 544, 530, 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, @@ -2750,13 +2509,13 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 733, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 922, 921, 931, 932, 924, 925, 926, 927, 928, + 929, 930, 923, 0, 0, 933, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, - 0, 0, 0, 0, 0, 0, 279, 739, 276, 188, - 202, 737, 0, 317, 355, 360, 0, 0, 0, 224, + 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, + 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, @@ -2783,23 +2542,23 @@ var yyAct = [...]int{ 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 0, 1373, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, + 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 772, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, - 176, 0, 1375, 0, 0, 0, 0, 0, 0, 213, + 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, - 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, - 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 0, 0, 256, 0, 307, 0, 0, 771, 421, + 0, 0, 0, 0, 0, 0, 768, 769, 279, 739, + 276, 188, 202, 762, 766, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, @@ -2826,59 +2585,59 @@ var yyAct = [...]int{ 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, - 388, 389, 390, 392, 303, 234, 33, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 321, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 67, 0, 0, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, + 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, + 1023, 0, 0, 0, 0, 237, 0, 0, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, + 174, 175, 176, 0, 1025, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, + 239, 232, 394, 911, 912, 910, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 913, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, + 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 33, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, - 1391, 0, 0, 1392, 0, 0, 213, 0, 219, 0, + 380, 249, 67, 0, 565, 174, 175, 176, 0, 0, + 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2914,14 +2673,14 @@ var yyAct = [...]int{ 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, - 0, 0, 237, 0, 1056, 0, 0, 0, 280, 0, + 392, 303, 234, 321, 0, 0, 0, 1373, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 1055, 0, 0, 0, 0, 0, 0, 213, 0, + 0, 1375, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2932,7 +2691,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 0, 1371, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, @@ -2963,17 +2722,17 @@ var yyAct = [...]int{ 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 0, 0, 565, 174, + 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, + 739, 276, 188, 202, 737, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, @@ -3001,13 +2760,13 @@ var yyAct = [...]int{ 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 1373, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 270, 221, 192, 318, 380, 249, 67, 0, - 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, + 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, + 0, 174, 175, 176, 0, 1375, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3050,7 +2809,7 @@ var yyAct = [...]int{ 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 0, 0, 0, 174, 175, 176, 0, 1375, 0, 0, + 0, 0, 565, 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3058,7 +2817,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, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 307, 0, 0, 0, 421, 0, 0, 0, 0, 1986, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, @@ -3087,440 +2846,527 @@ var yyAct = [...]int{ 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, - 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, - 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 1025, - 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, - 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, + 234, 33, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, + 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, + 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, + 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, + 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, + 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, + 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, - 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, - 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, - 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, - 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, - 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, - 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, - 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, - 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, - 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, - 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, - 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, - 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, - 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, - 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, - 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, + 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, + 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, - 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, - 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, - 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, - 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, - 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, - 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, - 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, - 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 1175, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, - 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, - 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, - 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, - 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, + 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, + 174, 175, 176, 0, 0, 1391, 0, 0, 1392, 0, + 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, + 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, + 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, - 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, - 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, - 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, - 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, - 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, - 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, - 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, - 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, - 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, - 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, - 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, - 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, - 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, - 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 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, 200, 282, 0, - 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 1056, + 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, + 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, + 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, + 0, 0, 174, 175, 176, 0, 1055, 0, 0, 0, + 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, + 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, - 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, - 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, - 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, - 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, - 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, - 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, - 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 321, 0, 1173, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, - 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, - 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, - 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, - 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, + 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, + 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, + 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, + 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, + 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, + 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, + 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, + 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, + 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, + 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, + 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, + 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, + 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, + 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, + 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, + 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, + 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, + 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, + 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, + 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, + 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, + 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, + 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, + 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, + 321, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, + 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, + 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, + 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, + 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, - 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, - 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, - 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, - 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, - 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 321, 0, 1171, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, - 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, - 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, - 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, + 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, + 2072, 0, 0, 0, 279, 0, 276, 188, 202, 0, + 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, + 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, + 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, + 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, + 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, + 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, + 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, + 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, + 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, + 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, + 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, + 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, + 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, + 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, + 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, - 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, - 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, - 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, + 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, + 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, + 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, + 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, + 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, + 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, + 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, + 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, + 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, + 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, + 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, + 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, + 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, + 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, - 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, - 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, - 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, - 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, - 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, - 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, - 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, - 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, - 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, - 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, - 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, - 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, - 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, - 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, - 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, + 0, 0, 1986, 0, 0, 0, 279, 0, 276, 188, + 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, + 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, + 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, + 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, + 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, + 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, + 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, + 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, + 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, + 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, + 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, + 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, + 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, + 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 200, 282, 0, 349, + 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, - 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, - 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, - 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, - 0, 1169, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, + 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, + 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, + 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, + 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, + 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, + 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, + 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, + 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, + 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, + 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 67, 0, 0, 174, 175, + 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, + 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 0, 0, 0, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, + 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, + 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, + 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 321, 0, 1167, 0, 0, 0, 0, 0, 0, - 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, - 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, - 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, - 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, - 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, - 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, - 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, + 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, + 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, + 174, 175, 176, 0, 1375, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, + 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, - 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, - 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, - 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, - 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, - 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, - 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, - 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, - 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, - 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, - 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, - 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, - 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, - 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, - 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, - 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, + 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, - 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, - 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, - 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, - 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, - 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, - 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, - 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, - 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, - 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, - 392, 303, 234, 321, 0, 1163, 0, 0, 0, 0, - 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, - 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, - 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, - 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, - 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, - 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, - 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, + 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, + 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, + 0, 0, 174, 175, 176, 0, 1025, 0, 0, 0, + 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, + 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, - 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, - 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, - 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, - 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, - 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, - 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, - 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, - 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, - 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, - 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, - 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, - 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, - 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, - 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, - 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, + 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, + 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, + 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, + 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, + 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, + 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, + 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, + 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, + 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, + 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, + 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, + 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, + 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, + 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, + 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, + 378, 0, 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, 200, 282, 0, - 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, + 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, + 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, + 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, + 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, + 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, + 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, + 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, + 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, + 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, + 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, + 321, 0, 1175, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, + 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, + 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, - 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, - 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, - 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, - 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, - 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, - 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, - 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, - 389, 390, 392, 303, 234, 321, 0, 1161, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, - 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, - 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, + 249, 0, 0, 0, 174, 175, 176, 0, 0, 0, + 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, + 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, - 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, - 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, - 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 256, + 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, + 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, + 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, + 330, 409, 209, 247, 352, 335, 356, 0, 0, 357, + 285, 398, 347, 408, 422, 423, 231, 311, 415, 391, + 419, 431, 203, 228, 324, 384, 412, 376, 304, 395, + 275, 375, 254, 191, 283, 195, 386, 406, 214, 368, + 0, 0, 0, 197, 404, 383, 301, 272, 273, 196, + 0, 351, 235, 252, 226, 320, 401, 402, 225, 433, + 204, 418, 199, 205, 417, 313, 397, 405, 302, 293, + 198, 403, 300, 292, 278, 245, 261, 345, 288, 346, + 262, 309, 308, 310, 0, 193, 0, 381, 413, 434, + 211, 0, 0, 393, 427, 430, 0, 348, 212, 253, + 244, 344, 251, 281, 426, 428, 429, 210, 342, 259, + 312, 206, 264, 377, 277, 286, 0, 0, 329, 359, + 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, - 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, - 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, - 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, - 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, - 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, - 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, - 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, - 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, - 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, - 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, - 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, - 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, - 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, - 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, - 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, + 0, 0, 0, 187, 200, 282, 0, 349, 250, 432, + 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, - 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 189, 190, 201, + 208, 217, 229, 242, 248, 257, 260, 263, 266, 267, + 269, 274, 291, 295, 296, 297, 298, 314, 315, 316, + 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, + 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, + 366, 367, 371, 372, 373, 374, 382, 385, 399, 400, + 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, + 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, + 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, + 303, 234, 321, 0, 1173, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, + 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, + 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, + 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, + 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, + 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, - 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, - 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, - 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, - 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, - 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, - 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, - 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, - 369, 388, 389, 390, 392, 303, 234, 321, 0, 1159, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, - 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, - 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, - 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, - 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, - 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, - 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, + 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, + 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, + 0, 358, 330, 409, 209, 247, 352, 335, 356, 0, + 0, 357, 285, 398, 347, 408, 422, 423, 231, 311, + 415, 391, 419, 431, 203, 228, 324, 384, 412, 376, + 304, 395, 275, 375, 254, 191, 283, 195, 386, 406, + 214, 368, 0, 0, 0, 197, 404, 383, 301, 272, + 273, 196, 0, 351, 235, 252, 226, 320, 401, 402, + 225, 433, 204, 418, 199, 205, 417, 313, 397, 405, + 302, 293, 198, 403, 300, 292, 278, 245, 261, 345, + 288, 346, 262, 309, 308, 310, 0, 193, 0, 381, + 413, 434, 211, 0, 0, 393, 427, 430, 0, 348, + 212, 253, 244, 344, 251, 281, 426, 428, 429, 210, + 342, 259, 312, 206, 264, 377, 277, 286, 0, 0, + 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 187, 200, 282, 0, 349, + 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, - 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, - 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, - 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, - 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, - 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, - 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, - 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, - 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, - 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, - 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, - 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, - 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, - 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, - 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, - 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 189, + 190, 201, 208, 217, 229, 242, 248, 257, 260, 263, + 266, 267, 269, 274, 291, 295, 296, 297, 298, 314, + 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, + 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, + 364, 365, 366, 367, 371, 372, 373, 374, 382, 385, + 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, + 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, + 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, + 390, 392, 303, 234, 321, 0, 1171, 0, 0, 0, + 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, + 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, + 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, + 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, + 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, + 176, 0, 0, 0, 0, 0, 0, 0, 0, 213, + 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, + 394, 0, 0, 0, 0, 0, 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, 200, 282, 0, 349, 250, 432, 416, 414, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, - 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, - 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, - 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, - 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, - 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, - 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, - 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, - 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, - 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, - 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, - 1134, 0, 0, 174, 175, 176, 0, 0, 0, 0, - 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, - 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, + 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, + 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, + 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, + 356, 0, 0, 357, 285, 398, 347, 408, 422, 423, + 231, 311, 415, 391, 419, 431, 203, 228, 324, 384, + 412, 376, 304, 395, 275, 375, 254, 191, 283, 195, + 386, 406, 214, 368, 0, 0, 0, 197, 404, 383, + 301, 272, 273, 196, 0, 351, 235, 252, 226, 320, + 401, 402, 225, 433, 204, 418, 199, 205, 417, 313, + 397, 405, 302, 293, 198, 403, 300, 292, 278, 245, + 261, 345, 288, 346, 262, 309, 308, 310, 0, 193, + 0, 381, 413, 434, 211, 0, 0, 393, 427, 430, + 0, 348, 212, 253, 244, 344, 251, 281, 426, 428, + 429, 210, 342, 259, 312, 206, 264, 377, 277, 286, + 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 200, 282, + 0, 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 189, 190, 201, 208, 217, 229, 242, 248, 257, + 260, 263, 266, 267, 269, 274, 291, 295, 296, 297, + 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, + 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, + 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, + 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, + 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, + 388, 389, 390, 392, 303, 234, 321, 0, 1169, 0, + 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, + 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, + 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, + 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, - 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, - 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, - 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, - 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, - 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, - 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, - 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, - 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, - 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, - 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, - 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, - 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, - 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, - 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, - 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, - 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, + 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, + 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, - 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, - 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, - 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, - 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, - 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, - 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, - 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, - 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, - 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, - 234, 1038, 0, 0, 0, 0, 0, 0, 321, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, + 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, + 1167, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, @@ -3563,7 +3409,7 @@ var yyAct = [...]int{ 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, - 321, 0, 0, 0, 0, 0, 0, 0, 1029, 237, + 321, 0, 1163, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, @@ -3606,14 +3452,14 @@ var yyAct = [...]int{ 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, - 303, 234, 321, 0, 0, 0, 0, 0, 0, 0, + 303, 234, 321, 0, 1161, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, 0, - 902, 0, 0, 0, 0, 0, 0, 213, 0, 219, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3649,7 +3495,7 @@ var yyAct = [...]int{ 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, - 390, 392, 303, 234, 321, 0, 0, 0, 0, 0, + 390, 392, 303, 234, 321, 0, 1159, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, @@ -3663,7 +3509,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, 480, 0, 256, 0, 307, 0, 0, 0, 421, + 0, 0, 0, 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, 335, @@ -3689,7 +3535,7 @@ var yyAct = [...]int{ 298, 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, 374, - 382, 385, 399, 400, 410, 420, 424, 479, 407, 425, + 382, 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, 0, @@ -3698,109 +3544,326 @@ var yyAct = [...]int{ 396, 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 270, 221, 192, 318, 380, 249, 0, 0, 0, - 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, - 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, - 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, + 0, 270, 221, 192, 318, 380, 249, 1134, 0, 0, + 174, 175, 176, 0, 0, 0, 0, 0, 0, 0, + 0, 213, 0, 219, 0, 0, 0, 0, 233, 268, + 239, 232, 394, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 256, 0, 307, 0, 0, + 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, + 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, + 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, + 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, + 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, + 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, + 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, + 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, + 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, + 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, + 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, + 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, + 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, + 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, + 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, + 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, + 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, + 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, + 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, + 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, + 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, + 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, + 216, 369, 388, 389, 390, 392, 303, 234, 1038, 0, + 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, + 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, + 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, + 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, + 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, + 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, + 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, + 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, + 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, 321, 0, 0, + 0, 0, 0, 0, 0, 1029, 237, 0, 0, 0, + 0, 0, 280, 0, 0, 334, 0, 370, 223, 289, + 287, 396, 246, 240, 236, 222, 265, 294, 332, 387, + 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 270, 221, 192, 318, 380, 249, 0, 0, + 0, 174, 175, 176, 0, 0, 0, 0, 0, 0, + 0, 0, 213, 0, 219, 0, 0, 0, 0, 233, + 268, 239, 232, 394, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 256, 0, 307, 0, + 0, 0, 421, 0, 0, 0, 0, 0, 0, 0, + 0, 279, 0, 276, 188, 202, 0, 0, 317, 355, + 360, 0, 0, 0, 224, 0, 358, 330, 409, 209, + 247, 352, 335, 356, 0, 0, 357, 285, 398, 347, + 408, 422, 423, 231, 311, 415, 391, 419, 431, 203, + 228, 324, 384, 412, 376, 304, 395, 275, 375, 254, + 191, 283, 195, 386, 406, 214, 368, 0, 0, 0, + 197, 404, 383, 301, 272, 273, 196, 0, 351, 235, + 252, 226, 320, 401, 402, 225, 433, 204, 418, 199, + 205, 417, 313, 397, 405, 302, 293, 198, 403, 300, + 292, 278, 245, 261, 345, 288, 346, 262, 309, 308, + 310, 0, 193, 0, 381, 413, 434, 211, 0, 0, + 393, 427, 430, 0, 348, 212, 253, 244, 344, 251, + 281, 426, 428, 429, 210, 342, 259, 312, 206, 264, + 377, 277, 286, 0, 0, 329, 359, 215, 411, 378, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 187, 200, 282, 0, 349, 250, 432, 416, 414, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 189, 190, 201, 208, 217, 229, + 242, 248, 257, 260, 263, 266, 267, 269, 274, 291, + 295, 296, 297, 298, 314, 315, 316, 319, 322, 323, + 325, 327, 328, 331, 337, 338, 339, 340, 341, 343, + 350, 354, 361, 362, 363, 364, 365, 366, 367, 371, + 372, 373, 374, 382, 385, 399, 400, 410, 420, 424, + 258, 407, 425, 0, 290, 0, 194, 220, 207, 227, + 241, 243, 271, 299, 305, 333, 336, 255, 238, 218, + 353, 216, 369, 388, 389, 390, 392, 303, 234, 321, + 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, + 0, 0, 0, 0, 280, 0, 0, 334, 0, 370, + 223, 289, 287, 396, 246, 240, 236, 222, 265, 294, + 332, 387, 326, 0, 284, 0, 0, 379, 306, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 270, 221, 192, 318, 380, 249, + 0, 0, 0, 174, 175, 176, 0, 902, 0, 0, + 0, 0, 0, 0, 213, 0, 219, 0, 0, 0, + 0, 233, 268, 239, 232, 394, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 256, 0, + 307, 0, 0, 0, 421, 0, 0, 0, 0, 0, + 0, 0, 0, 279, 0, 276, 188, 202, 0, 0, + 317, 355, 360, 0, 0, 0, 224, 0, 358, 330, + 409, 209, 247, 352, 335, 356, 0, 0, 357, 285, + 398, 347, 408, 422, 423, 231, 311, 415, 391, 419, + 431, 203, 228, 324, 384, 412, 376, 304, 395, 275, + 375, 254, 191, 283, 195, 386, 406, 214, 368, 0, + 0, 0, 197, 404, 383, 301, 272, 273, 196, 0, + 351, 235, 252, 226, 320, 401, 402, 225, 433, 204, + 418, 199, 205, 417, 313, 397, 405, 302, 293, 198, + 403, 300, 292, 278, 245, 261, 345, 288, 346, 262, + 309, 308, 310, 0, 193, 0, 381, 413, 434, 211, + 0, 0, 393, 427, 430, 0, 348, 212, 253, 244, + 344, 251, 281, 426, 428, 429, 210, 342, 259, 312, + 206, 264, 377, 277, 286, 0, 0, 329, 359, 215, + 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 200, 282, 0, 349, 250, 432, 416, + 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 189, 190, 201, 208, + 217, 229, 242, 248, 257, 260, 263, 266, 267, 269, + 274, 291, 295, 296, 297, 298, 314, 315, 316, 319, + 322, 323, 325, 327, 328, 331, 337, 338, 339, 340, + 341, 343, 350, 354, 361, 362, 363, 364, 365, 366, + 367, 371, 372, 373, 374, 382, 385, 399, 400, 410, + 420, 424, 258, 407, 425, 0, 290, 0, 194, 220, + 207, 227, 241, 243, 271, 299, 305, 333, 336, 255, + 238, 218, 353, 216, 369, 388, 389, 390, 392, 303, + 234, 321, 0, 0, 0, 0, 0, 0, 0, 0, + 237, 0, 0, 0, 0, 0, 280, 0, 0, 334, + 0, 370, 223, 289, 287, 396, 246, 240, 236, 222, + 265, 294, 332, 387, 326, 0, 284, 0, 0, 379, + 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 270, 221, 192, 318, + 380, 249, 0, 0, 0, 174, 175, 176, 0, 0, + 0, 0, 0, 0, 0, 0, 213, 0, 219, 0, + 0, 0, 0, 233, 268, 239, 232, 394, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 480, 0, + 256, 0, 307, 0, 0, 0, 421, 0, 0, 0, + 0, 0, 0, 0, 0, 279, 0, 276, 188, 202, + 0, 0, 317, 355, 360, 0, 0, 0, 224, 0, + 358, 330, 409, 209, 247, 352, 335, 356, 0, 0, + 357, 285, 398, 347, 408, 422, 423, 231, 311, 415, + 391, 419, 431, 203, 228, 324, 384, 412, 376, 304, + 395, 275, 375, 254, 191, 283, 195, 386, 406, 214, + 368, 0, 0, 0, 197, 404, 383, 301, 272, 273, + 196, 0, 351, 235, 252, 226, 320, 401, 402, 225, + 433, 204, 418, 199, 205, 417, 313, 397, 405, 302, + 293, 198, 403, 300, 292, 278, 245, 261, 345, 288, + 346, 262, 309, 308, 310, 0, 193, 0, 381, 413, + 434, 211, 0, 0, 393, 427, 430, 0, 348, 212, + 253, 244, 344, 251, 281, 426, 428, 429, 210, 342, + 259, 312, 206, 264, 377, 277, 286, 0, 0, 329, + 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 187, 200, 282, 0, 349, 250, + 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 189, 190, + 201, 208, 217, 229, 242, 248, 257, 260, 263, 266, + 267, 269, 274, 291, 295, 296, 297, 298, 314, 315, + 316, 319, 322, 323, 325, 327, 328, 331, 337, 338, + 339, 340, 341, 343, 350, 354, 361, 362, 363, 364, + 365, 366, 367, 371, 372, 373, 374, 382, 385, 399, + 400, 410, 420, 424, 479, 407, 425, 0, 290, 0, + 194, 220, 207, 227, 241, 243, 271, 299, 305, 333, + 336, 255, 238, 218, 353, 216, 369, 388, 389, 390, + 392, 303, 234, 321, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 280, 0, + 0, 334, 0, 370, 223, 289, 287, 396, 246, 240, + 236, 222, 265, 294, 332, 387, 326, 0, 284, 0, + 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 270, 221, + 192, 318, 380, 249, 0, 0, 0, 174, 175, 176, + 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, + 219, 0, 0, 0, 0, 233, 268, 239, 232, 394, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 256, 0, 307, 0, 182, - 0, 421, 0, 0, 0, 0, 0, 0, 0, 0, - 279, 0, 276, 188, 202, 0, 0, 317, 355, 360, - 0, 0, 0, 224, 0, 358, 330, 409, 209, 247, - 352, 335, 356, 0, 0, 357, 285, 398, 347, 408, - 422, 423, 231, 311, 415, 391, 419, 431, 203, 228, - 324, 384, 412, 376, 304, 395, 275, 375, 254, 191, - 283, 195, 386, 406, 214, 368, 0, 0, 0, 197, - 404, 383, 301, 272, 273, 196, 0, 351, 235, 252, - 226, 320, 401, 402, 225, 433, 204, 418, 199, 205, - 417, 313, 397, 405, 302, 293, 198, 403, 300, 292, - 278, 245, 261, 345, 288, 346, 262, 309, 308, 310, - 0, 193, 0, 381, 413, 434, 211, 0, 0, 393, - 427, 430, 0, 348, 212, 253, 244, 344, 251, 281, - 426, 428, 429, 210, 342, 259, 312, 206, 264, 377, - 277, 286, 0, 0, 329, 359, 215, 411, 378, 0, + 0, 0, 256, 0, 307, 0, 182, 0, 421, 0, + 0, 0, 0, 0, 0, 0, 0, 279, 0, 276, + 188, 202, 0, 0, 317, 355, 360, 0, 0, 0, + 224, 0, 358, 330, 409, 209, 247, 352, 335, 356, + 0, 0, 357, 285, 398, 347, 408, 422, 423, 231, + 311, 415, 391, 419, 431, 203, 228, 324, 384, 412, + 376, 304, 395, 275, 375, 254, 191, 283, 195, 386, + 406, 214, 368, 0, 0, 0, 197, 404, 383, 301, + 272, 273, 196, 0, 351, 235, 252, 226, 320, 401, + 402, 225, 433, 204, 418, 199, 205, 417, 313, 397, + 405, 302, 293, 198, 403, 300, 292, 278, 245, 261, + 345, 288, 346, 262, 309, 308, 310, 0, 193, 0, + 381, 413, 434, 211, 0, 0, 393, 427, 430, 0, + 348, 212, 253, 244, 344, 251, 281, 426, 428, 429, + 210, 342, 259, 312, 206, 264, 377, 277, 286, 0, + 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 200, 282, 0, 349, 250, 432, 416, 414, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 200, 282, 0, + 349, 250, 432, 416, 414, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 189, 190, 201, 208, 217, 229, 242, - 248, 257, 260, 263, 266, 267, 269, 274, 291, 295, - 296, 297, 298, 314, 315, 316, 319, 322, 323, 325, - 327, 328, 331, 337, 338, 339, 340, 341, 343, 350, - 354, 361, 362, 363, 364, 365, 366, 367, 371, 372, - 373, 374, 382, 385, 399, 400, 410, 420, 424, 258, - 407, 425, 0, 290, 0, 194, 220, 207, 227, 241, - 243, 271, 299, 305, 333, 336, 255, 238, 218, 353, - 216, 369, 388, 389, 390, 392, 303, 234, 321, 0, - 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, - 0, 0, 0, 280, 0, 0, 334, 0, 370, 223, - 289, 287, 396, 246, 240, 236, 222, 265, 294, 332, - 387, 326, 0, 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 270, 221, 192, 318, 380, 249, 0, - 0, 0, 174, 175, 176, 0, 0, 0, 0, 0, - 0, 0, 0, 213, 0, 219, 0, 0, 0, 0, - 233, 268, 239, 232, 394, 0, 0, 0, 0, 0, + 189, 190, 201, 208, 217, 229, 242, 248, 257, 260, + 263, 266, 267, 269, 274, 291, 295, 296, 297, 298, + 314, 315, 316, 319, 322, 323, 325, 327, 328, 331, + 337, 338, 339, 340, 341, 343, 350, 354, 361, 362, + 363, 364, 365, 366, 367, 371, 372, 373, 374, 382, + 385, 399, 400, 410, 420, 424, 258, 407, 425, 0, + 290, 0, 194, 220, 207, 227, 241, 243, 271, 299, + 305, 333, 336, 255, 238, 218, 353, 216, 369, 388, + 389, 390, 392, 303, 234, 321, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 280, 0, 0, 334, 0, 370, 223, 289, 287, 396, + 246, 240, 236, 222, 265, 294, 332, 387, 326, 0, + 284, 0, 0, 379, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 270, 221, 192, 318, 380, 249, 0, 0, 0, 174, + 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, + 213, 0, 219, 0, 0, 0, 0, 233, 268, 239, + 232, 394, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 256, 0, 307, - 0, 0, 0, 421, 0, 0, 0, 0, 0, 0, - 0, 0, 279, 0, 276, 188, 202, 0, 0, 317, - 355, 360, 0, 0, 0, 224, 0, 358, 330, 409, - 209, 247, 352, 335, 356, 0, 0, 357, 285, 398, - 347, 408, 422, 423, 231, 311, 415, 391, 419, 431, - 203, 228, 324, 384, 412, 376, 304, 395, 275, 375, - 254, 191, 283, 195, 386, 406, 214, 368, 0, 0, - 0, 197, 404, 383, 301, 272, 273, 196, 0, 351, - 235, 252, 226, 320, 401, 402, 225, 433, 204, 418, - 199, 205, 417, 313, 397, 405, 302, 293, 198, 403, - 300, 292, 278, 245, 261, 345, 288, 346, 262, 309, - 308, 310, 0, 193, 0, 381, 413, 434, 211, 0, - 0, 393, 427, 430, 0, 348, 212, 253, 244, 344, - 251, 281, 426, 428, 429, 210, 342, 259, 312, 206, - 264, 377, 277, 286, 0, 0, 329, 359, 215, 411, - 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 200, 282, 0, 349, 250, 432, 416, 414, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 256, 0, 307, 0, 0, 0, + 421, 0, 0, 0, 0, 0, 0, 0, 0, 279, + 0, 276, 188, 202, 0, 0, 317, 355, 360, 0, + 0, 0, 224, 0, 358, 330, 409, 209, 247, 352, + 335, 356, 0, 0, 357, 285, 398, 347, 408, 422, + 423, 231, 311, 415, 391, 419, 431, 203, 228, 324, + 384, 412, 376, 304, 395, 275, 375, 254, 191, 283, + 195, 386, 406, 214, 368, 0, 0, 0, 197, 404, + 383, 301, 272, 273, 196, 0, 351, 235, 252, 226, + 320, 401, 402, 225, 433, 204, 418, 199, 205, 417, + 313, 397, 405, 302, 293, 198, 403, 300, 292, 278, + 245, 261, 345, 288, 346, 262, 309, 308, 310, 0, + 193, 0, 381, 413, 434, 211, 0, 0, 393, 427, + 430, 0, 348, 212, 253, 244, 344, 251, 281, 426, + 428, 429, 210, 342, 259, 312, 206, 264, 377, 277, + 286, 0, 0, 329, 359, 215, 411, 378, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 189, 190, 201, 208, 217, - 229, 242, 248, 257, 260, 263, 266, 267, 269, 274, - 291, 295, 296, 297, 298, 314, 315, 316, 319, 322, - 323, 325, 327, 328, 331, 337, 338, 339, 340, 341, - 343, 350, 354, 361, 362, 363, 364, 365, 366, 367, - 371, 372, 373, 374, 382, 385, 399, 400, 410, 420, - 424, 258, 407, 425, 0, 290, 0, 194, 220, 207, - 227, 241, 243, 271, 299, 305, 333, 336, 255, 238, - 218, 353, 216, 369, 388, 389, 390, 392, 303, 234, + 0, 0, 0, 0, 0, 0, 0, 0, 187, 200, + 282, 0, 349, 250, 432, 416, 414, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 189, 190, 201, 208, 217, 229, 242, 248, + 257, 260, 263, 266, 267, 269, 274, 291, 295, 296, + 297, 298, 314, 315, 316, 319, 322, 323, 325, 327, + 328, 331, 337, 338, 339, 340, 341, 343, 350, 354, + 361, 362, 363, 364, 365, 366, 367, 371, 372, 373, + 374, 382, 385, 399, 400, 410, 420, 424, 258, 407, + 425, 0, 290, 0, 194, 220, 207, 227, 241, 243, + 271, 299, 305, 333, 336, 255, 238, 218, 353, 216, + 369, 388, 389, 390, 392, 303, 234, } var yyPact = [...]int{ - 3884, -1000, -328, 1476, -1000, -1000, -1000, -1000, -1000, -1000, + 3693, -1000, -327, 1534, -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, 1440, 1138, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 526, 1149, 205, 1349, 3394, 131, 925, 364, 101, 25457, - 361, 2020, 25889, -1000, 77, -1000, 63, 25889, 69, 25025, - -1000, -1000, -1000, 12032, 1313, -29, -37, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1167, 1412, 1417, 1438, 1008, - 1474, -1000, 10291, 10291, 306, 306, 306, 8563, -1000, -1000, - 15933, 25889, 25889, 1161, 299, 337, 299, -138, -1000, -1000, - -1000, -1000, -1000, -1000, 1349, -1000, -1000, 129, -1000, 222, - 1105, -1000, 1102, -1000, 438, 359, 215, 288, 287, 214, - 212, 210, 206, 204, 200, 199, 198, 238, -1000, 494, - 494, -191, -192, 2360, 295, 295, 295, 324, 1326, 1325, - -1000, 544, -1000, 494, 494, 113, 494, 494, 494, 494, - 178, 177, 494, 494, 494, 494, 494, 494, 494, 494, - 494, 494, 494, 494, 494, 494, 494, 25889, -1000, 130, - 491, 530, 1349, 155, -1000, -1000, -1000, 25889, 297, 925, - 297, 297, 25889, -1000, 408, -1000, -1000, -1000, -1000, -1000, + -1000, 1483, 1092, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 486, 1191, 177, 1411, 265, 181, 950, 350, 154, 26084, + 346, 111, 26516, -1000, 38, -1000, 29, 26516, 39, 25652, + -1000, -1000, -1000, 11795, 1364, -75, -80, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1167, 1452, 1453, 1480, 1003, + 1504, -1000, 10054, 10054, 309, 309, 309, 8326, -1000, -1000, + 15696, 26516, 26516, 1196, 281, 341, 281, -153, -1000, -1000, + -1000, -1000, -1000, -1000, 1411, -1000, -1000, 83, -1000, 215, + 1119, -1000, 1118, -1000, 420, 336, 202, 274, 267, 201, + 200, 191, 189, 188, 187, 185, 184, 236, -1000, 456, + 456, -192, -193, 1879, 271, 271, 271, 328, 1390, 1388, + -1000, 541, -1000, 456, 456, 55, 456, 456, 456, 456, + 146, 135, 456, 456, 456, 456, 456, 456, 456, 456, + 456, 456, 456, 456, 456, 456, 456, 26516, -1000, 81, + 561, 487, 1411, 97, -1000, -1000, -1000, 26516, 276, 950, + 276, 276, 26516, -1000, 393, -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, @@ -3825,23 +3888,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, -1000, -1000, -1000, 25889, 639, 639, 639, 639, - 639, 639, 49, -1000, 48, 171, 166, 152, 22, 925, - 112, -1000, 423, -1000, 143, 74, -1000, 639, 5887, 5887, - 5887, -1000, 1333, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 323, -1000, -1000, -1000, -1000, 25889, 24593, 180, 529, - -1000, -1000, -1000, -1000, 1030, 468, -1000, 12032, 3489, 1108, - 1108, -1000, -1000, 386, -1000, -1000, 13328, 13328, 13328, 13328, - 13328, 13328, 13328, 13328, 13328, 13328, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 26516, 589, 589, 589, 589, + 589, 589, 23, -1000, -29, 149, 145, 98, 89, 950, + 225, -1000, 399, -1000, 85, -13, -1000, 589, 5650, 5650, + 5650, -1000, 1394, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 326, -1000, -1000, -1000, -1000, 26516, 25220, 234, 484, + -1000, -1000, -1000, -1000, 1063, 661, -1000, 11795, 2052, 1142, + 1142, -1000, -1000, 370, -1000, -1000, 13091, 13091, 13091, 13091, + 13091, 13091, 13091, 13091, 13091, 13091, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1108, 406, -1000, 11600, 1108, 1108, 1108, 1108, 1108, 1108, - 1108, 1108, 12032, 1108, 1108, 1108, 1108, 1108, 1108, 1108, - 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, - -1000, -1000, -1000, 25889, -1000, 1440, -1000, 1138, -1000, -1000, - -1000, 1350, 12032, 12032, 1440, -1000, 1256, 10291, -1000, -1000, - 1339, -1000, -1000, -1000, -1000, 677, 1455, -1000, 14624, 404, - 1454, 24161, -1000, 18538, 23729, 1101, 8117, -70, -1000, -1000, - -1000, 509, 17674, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1142, 392, -1000, 11363, 1142, 1142, 1142, 1142, 1142, 1142, + 1142, 1142, 11795, 1142, 1142, 1142, 1142, 1142, 1142, 1142, + 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, 1142, + -1000, -1000, -1000, 26516, -1000, 1483, -1000, 1092, -1000, -1000, + -1000, 1408, 11795, 11795, 1483, -1000, 1255, 10054, -1000, -1000, + 1339, -1000, -1000, -1000, -1000, 557, 1517, -1000, 14387, 391, + 1507, 24788, -1000, 19165, 24356, 1117, 7880, -50, -1000, -1000, + -1000, 469, 17869, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -3855,293 +3918,276 @@ 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, 1333, 1061, 25889, -1000, -1000, 3547, 925, -1000, 1145, - -1000, 1055, -1000, 1114, 130, 25889, 579, 925, 925, -1000, - -1000, -1000, 494, 494, 229, 3394, 267, -1000, -1000, -1000, - 23290, 1144, 925, -1000, 1140, -1000, 1366, 294, 487, 487, - 925, -1000, -1000, 25889, 925, 1365, 1359, 25889, 25889, -1000, - 22858, -1000, 22426, 21994, 800, 25889, 21562, 21130, 20698, 20266, - 19834, -1000, 1218, -1000, 1189, -1000, -1000, -1000, 25889, 25889, - 25889, -12, -1000, -1000, 25889, 925, -1000, -1000, 787, 767, - 494, 494, 765, 896, 895, 891, 494, 494, 763, 890, - 916, 132, 760, 759, 756, 808, 887, 103, 784, 742, - 751, 25889, 1137, -1000, 104, 505, 182, 225, 174, 25889, - 102, 1349, 1310, 1098, 311, 25889, 1397, 1224, 25889, 925, - -1000, 7225, -1000, -1000, 886, 12032, -1000, -1000, -1000, -1000, - -1000, 639, 25889, 639, 25889, 639, 639, 639, 639, 557, - 583, 557, -1000, -1000, -1000, -1000, 5887, 5887, 25889, 5887, - 5887, 25889, 5887, 5887, 583, -1000, -1000, -1000, 453, -1000, - 1222, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 67, -1000, - -1000, -1000, -1000, -1000, 1476, -1000, -1000, -1000, -123, 12032, - 12032, 12032, 12032, 852, 464, 13328, 753, 669, 13328, 13328, - 13328, 13328, 13328, 13328, 13328, 13328, 13328, 13328, 13328, 13328, - 13328, 13328, 13328, 634, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 925, -1000, 1470, 1015, 1015, 407, 407, 407, - 407, 407, 407, 407, 407, 407, 13760, 8995, 7225, 1008, - 1043, 1440, 10291, 10291, 12032, 12032, 11155, 10723, 10291, 1336, - 553, 468, 25889, -1000, 905, -1000, -1000, 12896, -1000, -1000, + -1000, 1394, 1070, 26516, -1000, -1000, 3728, 950, -1000, 1186, + -1000, 1061, -1000, 1157, 81, 26516, 519, 950, 950, -1000, + -1000, -1000, 456, 456, 222, 265, 3498, -1000, -1000, -1000, + 23917, 1182, 950, -1000, 1180, -1000, 1425, 305, 472, 472, + 950, -1000, -1000, 26516, 950, 1424, 1423, 26516, 26516, -1000, + 23485, -1000, 23053, 22621, 800, 26516, 22189, 21757, 21325, 20893, + 20461, -1000, 1274, -1000, 1190, -1000, -1000, -1000, 26516, 26516, + 26516, -54, -1000, -1000, 26516, 950, -1000, -1000, 797, 788, + 456, 456, 787, 892, 886, 880, 456, 456, 782, 878, + 935, 194, 774, 772, 769, 826, 875, 106, 821, 747, + 760, 26516, 1179, -1000, 73, 461, 157, 231, 134, 26516, + 129, 1411, 1361, 1115, 324, 26516, 1438, 1236, 26516, 950, + -1000, 6988, -1000, -1000, 873, 11795, -1000, -1000, -1000, -1000, + -1000, 589, 26516, 589, 26516, 589, 589, 589, 589, 548, + 565, 548, -1000, -1000, -1000, -1000, 5650, 5650, 26516, 5650, + 5650, 26516, 5650, 5650, 565, -1000, -1000, -1000, 442, -1000, + 1235, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 36, -1000, + -1000, -1000, -1000, -1000, 1534, -1000, -1000, -1000, -125, 11795, + 11795, 11795, 11795, 667, 441, 13091, 700, 470, 13091, 13091, + 13091, 13091, 13091, 13091, 13091, 13091, 13091, 13091, 13091, 13091, + 13091, 13091, 13091, 715, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 950, -1000, 1511, 966, 966, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 13523, 8758, 6988, 1003, + 1055, 1483, 10054, 10054, 11795, 11795, 10918, 10486, 10054, 1384, + 506, 661, 26516, -1000, 908, -1000, -1000, 12659, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 25889, 25889, 10291, 10291, 10291, 10291, 10291, -1000, 1091, -1000, - -168, 15501, 1417, 1008, 1339, 1376, 1464, 444, 899, 1088, - -1000, 809, 1417, 17242, 1077, -1000, 1339, -1000, -1000, -1000, - 25889, -1000, -1000, 19402, -1000, -1000, 6779, 25889, 197, 25889, - -1000, 1099, 1193, -1000, -1000, -1000, 1406, 16810, 25889, 1084, - 1075, -1000, -1000, 403, 7671, -70, -1000, 7671, 1071, -1000, - -96, -76, 9427, 385, -1000, -1000, -1000, 2360, 14192, 947, - 611, -11, -1000, -1000, -1000, 1114, -1000, 1114, 1114, 1114, - 1114, -12, -12, -12, -12, -1000, -1000, -1000, -1000, -1000, - 1131, 1121, -1000, 1114, 1114, 1114, 1114, -1000, -1000, -1000, + 26516, 26516, 10054, 10054, 10054, 10054, 10054, -1000, 1110, -1000, + -171, 15264, 1453, 1003, 1339, 1429, 1527, 434, 963, 1109, + -1000, 813, 1453, 17437, 1149, -1000, 1339, -1000, -1000, -1000, + 26516, -1000, -1000, 20029, -1000, -1000, 6542, 26516, 183, 26516, + -1000, 1138, 1228, -1000, -1000, -1000, 1443, 17005, 26516, 1122, + 1108, -1000, -1000, 386, 7434, -50, -1000, 7434, 1097, -1000, + -120, -117, 9190, 401, -1000, -1000, -1000, 1879, 13955, 976, + 608, -45, -1000, -1000, -1000, 1157, -1000, 1157, 1157, 1157, + 1157, -54, -54, -54, -54, -1000, -1000, -1000, -1000, -1000, + 1178, 1177, -1000, 1157, 1157, 1157, 1157, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1119, 1119, 1119, 1115, 1115, 282, - -1000, 12032, 81, 25889, 1387, 748, 104, -1000, 1381, 1198, - -1000, 884, 875, -1000, 1087, -1000, -1000, 1437, -1000, -1000, - 462, 632, 630, 458, 25889, 94, 194, -1000, 273, -1000, - 25889, 1118, 1358, 487, 925, -1000, 925, -1000, -1000, -1000, - -1000, 402, -1000, -1000, 925, 1085, -1000, 1093, 687, 617, - 664, 601, 1085, -1000, -1000, -172, 1085, -1000, 1085, -1000, - 1085, -1000, 1085, -1000, 1085, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 490, 25889, 94, 634, -1000, 309, -1000, - -1000, 634, 634, -1000, -1000, -1000, -1000, 878, 869, -1000, + -1000, -1000, -1000, -1000, 1176, 1176, 1176, 1159, 1159, 278, + -1000, 11795, 79, 26516, 1434, 757, 73, -1000, 1437, 1214, + -1000, 922, 885, -1000, 1107, -1000, -1000, 1477, -1000, -1000, + 466, 611, 603, 452, 26516, 57, 176, -1000, 263, -1000, + 26516, 1172, 1422, 472, 950, -1000, 950, -1000, -1000, -1000, + -1000, 385, -1000, -1000, 950, 1105, -1000, 1113, 691, 562, + 654, 544, 1105, -1000, -1000, -174, 1105, -1000, 1105, -1000, + 1105, -1000, 1105, -1000, 1105, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 488, 26516, 57, 715, -1000, 323, -1000, + -1000, 715, 715, -1000, -1000, -1000, -1000, 872, 869, -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, -317, 25889, 328, 85, 115, - 25889, 25889, 25889, 25889, 25889, 378, -1000, -1000, -1000, 159, - 25889, 25889, 357, -1000, 25889, 338, -1000, -1000, -1000, -1000, - -1000, -1000, 468, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 639, 25889, 25889, 25889, -1000, -1000, 639, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 25889, -1000, 868, 25889, - 25889, -1000, -1000, -1000, -1000, -1000, 468, 464, 531, 495, - -1000, -1000, 725, -1000, -1000, 2766, -1000, -1000, -1000, -1000, - 753, 13328, 13328, 13328, 375, 2766, 2445, 620, 793, 407, - 605, 605, 422, 422, 422, 422, 422, 594, 594, -1000, - -1000, -1000, -1000, 905, -1000, -1000, -1000, 905, 10291, 10291, - 1083, 1108, 401, -1000, 1167, -1000, -1000, 1417, 1010, 1010, - 692, 846, 565, 1453, 1010, 536, 1452, 1010, 1010, 10291, - -1000, -1000, 556, -1000, 12032, 905, -1000, 1206, 1082, 1072, - 1010, 905, 905, 1010, 1010, 25889, -1000, -291, -1000, -121, - 400, 1108, -1000, 18970, -1000, -1000, 1350, -1000, -1000, 1308, - -1000, 1253, 12032, 12032, 12032, -1000, -1000, -1000, 1350, 1426, - -1000, 1269, 1266, 1447, 10291, 18538, 1339, -1000, -1000, -1000, - 398, 1447, 1123, 1108, -1000, 25889, 18538, 18538, 18538, 18538, - 18538, -1000, 1239, 1236, -1000, 1237, 1235, 1243, 25889, -1000, - 1037, 1008, 16810, 197, 960, 18538, 25889, -1000, -1000, 18538, - 25889, 6333, -1000, 1071, -70, -38, -1000, -1000, -1000, -1000, - 468, -1000, 773, -1000, 2337, -1000, 275, -1000, -1000, -1000, - -1000, 1348, -1000, 670, 6, -1000, -1000, -12, -12, -1000, - -1000, 385, 475, 385, 385, 385, 859, 859, -1000, -1000, - -1000, -1000, -1000, 743, -1000, -1000, -1000, 737, -1000, -1000, - 735, 1207, 81, -1000, -1000, 494, 850, 1320, 25889, -1000, - -1000, 940, 326, -1000, 1219, -1000, -1000, -1000, -1000, -1000, - 245, 25889, 1034, -1000, 84, 25889, 933, 25889, -1000, 1016, - 25889, -1000, 925, -1000, -1000, 7225, -1000, 25889, 1108, -1000, - -1000, -1000, -1000, 339, 1341, 1335, 94, 84, 385, 925, - -1000, -1000, -1000, -1000, -1000, -320, 1012, 25889, 139, -1000, - 1116, 902, -1000, 1176, -1000, -1000, -1000, -1000, 83, 181, - 153, 308, -1000, -1000, -1000, -1000, 5887, 25889, -1000, -1000, - -1000, -1000, 557, -1000, 557, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 375, 2766, 2198, -1000, 13328, 13328, -1000, -1000, - 1010, 1010, 10291, 7225, 1440, 1350, -1000, -1000, 192, 634, - 192, 13328, 13328, -1000, 13328, 13328, -1000, -155, 1097, 537, - -1000, 12032, 705, -1000, -1000, 13328, 13328, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 335, 332, 331, 25889, - -1000, -1000, 789, 833, 1248, 468, 468, -1000, -1000, 25889, - -1000, -1000, -1000, -1000, 1445, 12032, -1000, 1068, -1000, 5441, - 1417, 1217, 25889, 1108, 1476, 15069, 25889, 1057, -1000, 503, - 1193, 1197, 1215, 1614, -1000, -1000, -1000, -1000, 1228, -1000, - 1216, -1000, -1000, -1000, -1000, -1000, 1008, 1447, 18538, 1018, - -1000, 1018, -1000, 391, -1000, -1000, -1000, -106, -117, -1000, - -1000, -1000, 2360, -1000, -1000, 1212, 13328, -1000, -1000, -1000, - 385, 385, -1000, -1000, -1000, -1000, -1000, -1000, 999, -1000, - 996, 1059, 994, 34, -1000, 1160, 1331, 494, 494, -1000, - 732, -1000, 925, -1000, -1000, 25889, 25889, 1436, 1053, -1000, - 25889, -1000, -1000, 25889, -1000, -1000, 1265, 81, 985, -1000, - -1000, -1000, 194, 25889, -1000, 1015, 84, -1000, -1000, -1000, - -1000, -1000, -1000, 1110, -1000, -1000, -1000, 922, -1000, -173, - 925, 25889, 25889, 25889, -1000, 25889, -1000, -1000, 639, 639, - -1000, 13328, 2766, 2766, -1000, -1000, 905, -1000, 1417, -1000, - 905, 1114, 1114, -1000, 1114, 1115, -1000, 1114, 54, 1114, - 53, 905, 905, 2680, 2427, 2273, 2147, 1108, -149, -1000, - 468, 12032, 2055, 1685, 1108, 1108, 1108, 981, 832, -12, - -1000, -1000, -1000, 1442, 1435, 468, -1000, -1000, -1000, 1369, - 979, 987, -1000, -1000, 9859, 983, 1260, 384, 981, 1440, - 25889, 12032, -1000, -1000, 12032, 1111, -1000, 12032, -1000, -1000, - -1000, 1440, 1440, 1018, -1000, -1000, 431, -1000, -1000, -1000, - -1000, 13, 1463, 2766, -1000, -1000, -12, 827, -12, 715, - -1000, 697, -1000, -1000, -230, -1000, -1000, 1174, 1200, -1000, - -1000, 1110, -1000, 25889, 25889, -1000, -1000, 190, -1000, 253, - 975, -1000, -189, -1000, -1000, 1402, 25889, -1000, -1000, 7225, - -1000, -1000, 1109, 1181, -1000, -1000, -1000, -1000, 2766, -1000, - 1350, -1000, -1000, 196, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 13328, 13328, 13328, 13328, 13328, 1417, 826, 468, - 13328, 13328, 18106, 25889, 25889, 16365, -12, -19, -1000, 12032, - 12032, 1356, -1000, 1108, -1000, 1079, 25889, 1108, 25889, -1000, - 1417, -1000, 468, 468, 25889, 468, 1417, -1000, 446, -1000, - -78, 385, -1000, 385, 915, 908, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1399, 1053, -1000, 186, 25889, -1000, - 194, -1000, -194, -195, 1138, 965, 1047, -1000, 482, 25889, - 25889, -1000, -1000, -1000, 1206, 1206, 1206, 1206, 195, 905, - -1000, 1206, 1206, 954, -1000, 954, 954, 400, -281, -1000, - 1309, 1306, 468, 1030, 1462, -1000, 1108, 1476, 382, 987, - -1000, -1000, 938, -1000, 672, 1354, -1000, 1340, -1000, -1000, - -1000, -1000, -1000, 1138, 1108, 1080, -1000, -1000, -1000, 151, - -1000, 7225, 4995, 930, -1000, -1000, -1000, -1000, -1000, 905, - 98, -177, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -19, - 242, -1000, 1273, 1271, 1431, 25889, 987, 25889, -1000, -1000, - 819, -1000, -1000, 151, 12464, 25889, -1000, -72, -1000, -1000, - -1000, -1000, -1000, 1176, -1000, 1221, -170, -186, 1277, 1280, - 1280, 1306, 1430, 1303, 1284, -1000, 817, 963, -1000, -1000, - -1000, 1206, 905, 912, 269, -1000, -1000, -173, -1000, 1214, - -1000, 1275, 704, -1000, -1000, -1000, -1000, 810, -1000, 1428, - 1423, -1000, -1000, -1000, 1210, 127, -1000, -175, -1000, 702, - -1000, -1000, -1000, 806, 774, 1204, -1000, 1451, -1000, -184, - -1000, -1000, -1000, -1000, -1000, 1460, 414, 414, -187, -1000, - -1000, -1000, 278, 730, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -316, 26516, 333, 62, 105, + 26516, 26516, 26516, 26516, 26516, 359, -1000, -1000, -1000, 115, + 26516, 26516, 381, -1000, 26516, 354, -1000, -1000, -1000, -1000, + -1000, -1000, 661, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 589, 26516, 26516, 26516, -1000, -1000, 589, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 26516, -1000, 855, 26516, + 26516, -1000, -1000, -1000, -1000, -1000, 661, 441, 696, 515, + -1000, -1000, 714, -1000, -1000, 1956, -1000, -1000, -1000, -1000, + 700, 13091, 13091, 13091, 549, 1956, 2465, 692, 944, 410, + 605, 605, 411, 411, 411, 411, 411, 618, 618, -1000, + -1000, -1000, -1000, 908, -1000, -1000, -1000, 908, 10054, 10054, + 1103, 1142, 379, -1000, 1167, -1000, -1000, 1453, 1034, 1034, + 893, 709, 539, 1500, 1034, 520, 1498, 1034, 1034, 10054, + -1000, -1000, 559, -1000, 11795, 908, -1000, 591, 1102, 1101, + 1034, 908, 908, 1034, 1034, 26516, -1000, -287, -1000, -136, + 409, 1142, -1000, 19597, -1000, -1000, 1408, -1000, -1000, 1349, + -1000, 1306, 11795, 11795, 11795, -1000, -1000, -1000, 1408, 1455, + -1000, 1317, 1316, 1493, 10054, 19165, 1339, -1000, -1000, -1000, + 377, 1493, 1100, 1142, -1000, 26516, 19165, 19165, 19165, 19165, + 19165, -1000, 1253, 1251, -1000, 1264, 1263, 1289, 26516, -1000, + 1048, 1003, 17005, 183, 1065, 19165, 26516, -1000, -1000, 19165, + 26516, 6096, -1000, 1097, -50, -134, -1000, -1000, -1000, -1000, + 661, -1000, 820, -1000, 2359, -1000, 266, -1000, -1000, -1000, + -1000, 1409, -1000, 527, -49, -1000, -1000, -54, -54, -1000, + -1000, 401, 710, 401, 401, 401, 854, 854, -1000, -1000, + -1000, -1000, -1000, 756, -1000, -1000, -1000, 748, -1000, -1000, + 545, 1252, 79, -1000, -1000, 456, 851, 1368, 26516, -1000, + -1000, 954, 332, -1000, 1233, -1000, -1000, -1000, -1000, -1000, + 3372, 26516, 1045, -1000, 49, 26516, 947, 26516, -1000, 1043, + 26516, -1000, 950, -1000, -1000, 6988, -1000, 26516, 1142, -1000, + -1000, -1000, -1000, 345, 1405, 1399, 57, 49, 401, 950, + -1000, -1000, -1000, -1000, -1000, -320, 1037, 26516, 72, -1000, + 1166, 899, -1000, 1202, -1000, -1000, -1000, -1000, 82, 108, + 107, 311, -1000, -1000, -1000, -1000, 5650, 26516, -1000, -1000, + -1000, -1000, 548, -1000, 548, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 549, 1956, 2367, -1000, 13091, 13091, -1000, -1000, + 1034, 1034, 10054, 6988, 1483, 1408, -1000, -1000, 371, 715, + 371, 13091, 13091, -1000, 13091, 13091, -1000, -166, 1076, 453, + -1000, 11795, 879, -1000, -1000, 13091, 13091, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, 340, 337, 335, 26516, + -1000, -1000, 804, 841, 1297, 661, 661, -1000, -1000, 26516, + -1000, -1000, -1000, -1000, 1487, 11795, -1000, 1095, -1000, 5204, + 1453, 1230, 26516, 1142, 1534, 14832, 26516, 1081, -1000, 459, + 1228, 1201, 1229, 1459, -1000, -1000, -1000, -1000, 1249, -1000, + 1247, -1000, -1000, -1000, -1000, -1000, 1003, 1493, 19165, 1075, + -1000, 1075, -1000, 376, -1000, -1000, -1000, -129, -128, -1000, + -1000, -1000, 1879, -1000, -1000, 1227, 13091, -1000, -1000, -1000, + 401, 401, -1000, -1000, -1000, -1000, -1000, -1000, 1031, -1000, + 1029, 1093, 1023, 35, -1000, 1194, 1386, 456, 456, -1000, + 731, -1000, 950, -1000, -1000, 26516, 26516, 1474, 1085, -1000, + 26516, -1000, -1000, 26516, -1000, -1000, 1312, 79, 1021, -1000, + -1000, -1000, 176, 26516, -1000, 966, 49, -1000, -1000, -1000, + -1000, -1000, -1000, 1144, -1000, -1000, -1000, 933, -1000, -175, + 950, 26516, 26516, 26516, -1000, 26516, -1000, -1000, 589, 589, + -1000, 13091, 1956, 1956, -1000, -1000, 908, -1000, 1453, -1000, + 908, 1157, 1157, -1000, 1157, 1159, -1000, 1157, 25, 1157, + 24, 908, 908, 2272, 2200, 2148, 1685, 1142, -161, -1000, + 661, 11795, 1208, 816, 1142, 1142, 1142, 1015, 838, -54, + -1000, -1000, -1000, 1461, 1473, 661, -1000, -1000, -1000, 1427, + 1082, 981, -1000, -1000, 9622, 1019, 1311, 373, 1015, 1483, + 26516, 11795, -1000, -1000, 11795, 1148, -1000, 11795, -1000, -1000, + -1000, 1483, 1483, 1075, -1000, -1000, 421, -1000, -1000, -1000, + -1000, -27, 1526, 1956, -1000, -1000, -54, 837, -54, 686, + -1000, 649, -1000, -1000, -231, -1000, -1000, 1134, 1248, -1000, + -1000, 1144, -1000, 26516, 26516, -1000, -1000, 165, -1000, 251, + 986, -1000, -190, -1000, -1000, 1442, 26516, -1000, -1000, 6988, + -1000, -1000, 1143, 1203, -1000, -1000, -1000, -1000, 1956, -1000, + 1408, -1000, -1000, 218, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 13091, 13091, 13091, 13091, 13091, 1453, 836, 661, + 13091, 13091, 16560, 18733, 18733, 16128, -54, -46, -1000, 11795, + 11795, 1418, -1000, 1142, -1000, 1126, 26516, 1142, 26516, -1000, + 1453, -1000, 661, 661, 26516, 661, 1453, -1000, 440, -1000, + -40, 401, -1000, 401, 916, 914, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1441, 1085, -1000, 162, 26516, -1000, + 176, -1000, -196, -197, 1092, 983, 1077, -1000, 455, 26516, + 26516, -1000, -1000, -1000, 591, 591, 591, 591, 195, 908, + -1000, 591, 591, 968, -1000, -1000, -1000, 968, 968, 409, + -282, -1000, 1355, 1351, 661, 1063, 1525, -1000, 1142, 1534, + 368, 981, -1000, -1000, 965, -1000, 552, 1417, -1000, 1415, + -1000, -1000, -1000, -1000, -1000, 1092, 1142, 1124, -1000, -1000, + -1000, 152, -1000, 6988, 4758, 959, -1000, -1000, -1000, -1000, + -1000, 908, 96, -182, -1000, -1000, -1000, 18301, -1000, -1000, + -1000, -1000, -46, 211, -1000, 1321, 1319, 1467, 26516, 981, + 26516, -1000, -1000, 831, -1000, -1000, 152, 12227, 26516, -1000, + -74, -1000, -1000, -1000, -1000, -1000, 1202, -1000, 1269, -170, + -187, -1000, -1000, 1331, 1333, 1333, 1351, 1466, 1341, 1338, + -1000, 830, 979, -1000, -1000, -1000, 591, 908, 931, 272, + -1000, -1000, -175, -1000, 1266, -1000, 1329, 742, -1000, -1000, + -1000, -1000, 828, -1000, 1462, 1460, -1000, -1000, -1000, 1226, + 75, -1000, -179, -1000, 673, -1000, -1000, -1000, 806, 802, + 1216, -1000, 1505, -1000, -185, -1000, -1000, -1000, -1000, -1000, + 1523, 347, 347, -188, -1000, -1000, -1000, 269, 634, -1000, + -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1748, 1746, 14, 89, 85, 1745, 1744, 1743, 1740, - 128, 125, 118, 1738, 1737, 1736, 1735, 1733, 1730, 1729, - 1728, 1727, 1726, 1724, 1723, 61, 110, 115, 1722, 1720, - 1719, 1718, 1715, 124, 121, 458, 1708, 122, 1706, 1703, - 1700, 1698, 1694, 1693, 1692, 1691, 1690, 1688, 1684, 1681, - 134, 1675, 1673, 7, 1672, 81, 1670, 1668, 1667, 1666, - 1664, 1662, 1661, 109, 1660, 46, 86, 48, 74, 1659, - 71, 793, 1658, 98, 117, 1657, 161, 1656, 45, 90, - 69, 1655, 43, 1654, 1650, 94, 1649, 1648, 1645, 72, - 1644, 1643, 2430, 1642, 68, 76, 21, 37, 1639, 1638, - 1637, 1636, 38, 1286, 1634, 1633, 26, 1629, 1628, 127, - 1627, 80, 31, 16, 19, 18, 1626, 79, 1625, 8, - 54, 32, 1624, 75, 1623, 1622, 1617, 1616, 33, 1613, - 73, 97, 24, 1611, 6, 10, 1608, 1607, 1606, 1605, - 1604, 1603, 4, 1602, 1601, 1600, 1599, 29, 1598, 11, - 23, 70, 111, 27, 9, 1596, 136, 1593, 25, 106, - 66, 104, 1592, 1591, 1589, 939, 1588, 49, 1587, 132, - 1586, 1585, 41, 1583, 442, 815, 1582, 1580, 1579, 59, - 1117, 2371, 13, 107, 1574, 1572, 1689, 57, 77, 22, - 1571, 1570, 1569, 119, 64, 51, 891, 44, 1567, 1566, - 1565, 1564, 1563, 1561, 1559, 246, 1556, 1555, 1554, 34, - 20, 100, 30, 1552, 1551, 1548, 1547, 1543, 63, 36, - 1541, 103, 102, 62, 116, 1540, 113, 84, 55, 1539, - 56, 1536, 1532, 1528, 1527, 42, 1526, 1525, 1524, 1523, - 99, 82, 67, 40, 35, 96, 1521, 39, 1520, 1519, - 83, 87, 1517, 17, 114, 12, 1515, 3, 0, 1512, - 5, 126, 1355, 112, 1507, 1506, 1, 1505, 2, 1504, - 1503, 78, 1498, 1495, 1488, 1483, 2988, 28, 105, 1479, - 120, + 0, 1805, 1801, 13, 86, 82, 1800, 1798, 1797, 1796, + 128, 127, 126, 1794, 1782, 1780, 1779, 1778, 1777, 1776, + 1775, 1774, 1771, 1770, 1768, 61, 110, 115, 1766, 1762, + 1761, 1760, 1759, 122, 121, 468, 1755, 119, 1750, 1747, + 1746, 1743, 1741, 1740, 1738, 1737, 1736, 1735, 1733, 1730, + 199, 1729, 1728, 7, 1726, 83, 1722, 1720, 1719, 1718, + 1715, 1714, 1712, 106, 1709, 46, 286, 48, 75, 1706, + 72, 770, 1700, 90, 116, 1698, 447, 1697, 42, 78, + 96, 1693, 40, 1692, 1691, 94, 1690, 1688, 1687, 69, + 1686, 1684, 2519, 1683, 67, 76, 17, 55, 1682, 1681, + 1680, 1679, 31, 1286, 1678, 1677, 21, 1676, 1675, 125, + 1673, 81, 25, 20, 19, 18, 1672, 77, 1670, 8, + 54, 32, 1668, 80, 1667, 1666, 1664, 1662, 33, 1661, + 73, 99, 24, 1660, 6, 10, 1659, 1658, 1657, 1656, + 1654, 1653, 4, 1652, 1650, 1649, 1648, 26, 1645, 9, + 23, 38, 71, 111, 29, 12, 1644, 120, 1643, 27, + 105, 68, 103, 1642, 1639, 1638, 939, 1637, 59, 1635, + 131, 1633, 1628, 44, 1627, 431, 762, 1626, 1625, 1623, + 64, 1117, 2383, 45, 104, 1621, 1617, 1689, 57, 74, + 22, 1614, 1613, 1611, 123, 49, 51, 896, 43, 1608, + 1607, 1605, 1604, 1603, 1602, 1601, 248, 1600, 1599, 1598, + 34, 16, 95, 30, 1597, 1596, 1593, 1592, 1591, 66, + 36, 1589, 101, 100, 62, 117, 1588, 112, 85, 70, + 1587, 56, 1586, 1585, 1582, 1579, 41, 1575, 1574, 1572, + 1571, 102, 84, 63, 37, 39, 98, 1570, 35, 1569, + 1568, 97, 87, 1566, 15, 113, 11, 1556, 3, 0, + 1555, 5, 109, 1388, 114, 1554, 1552, 1, 1551, 2, + 1550, 1549, 79, 1548, 1547, 1544, 1543, 2749, 28, 107, + 1541, 118, } var yyR1 = [...]int{ - 0, 274, 275, 275, 1, 1, 1, 1, 1, 1, + 0, 275, 276, 276, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 258, 258, 258, 261, 261, 21, 47, + 1, 1, 1, 259, 259, 259, 262, 262, 21, 47, 3, 3, 3, 3, 2, 2, 8, 9, 4, 5, 5, 10, 10, 57, 57, 11, 12, 12, 12, 12, - 278, 278, 87, 87, 85, 85, 86, 86, 151, 151, - 13, 14, 14, 161, 161, 160, 160, 160, 162, 162, - 162, 162, 196, 196, 15, 15, 15, 15, 15, 64, - 64, 260, 260, 259, 257, 257, 256, 256, 255, 23, - 24, 30, 31, 32, 262, 262, 231, 36, 36, 35, - 35, 35, 35, 37, 37, 34, 34, 33, 33, 233, - 233, 220, 220, 232, 232, 232, 232, 232, 232, 232, - 219, 198, 198, 198, 198, 201, 201, 199, 199, 199, - 199, 199, 199, 199, 199, 199, 200, 200, 200, 200, - 200, 202, 202, 202, 202, 202, 203, 203, 203, 203, - 203, 203, 203, 203, 203, 203, 203, 203, 203, 203, - 203, 204, 204, 204, 204, 204, 204, 204, 204, 218, - 218, 205, 205, 211, 211, 212, 212, 212, 214, 214, - 215, 215, 176, 176, 176, 207, 207, 208, 208, 213, - 213, 209, 209, 209, 210, 210, 210, 217, 217, 217, - 217, 217, 206, 206, 221, 247, 247, 246, 246, 242, - 242, 242, 242, 230, 230, 239, 239, 239, 239, 239, - 229, 229, 225, 225, 225, 226, 226, 227, 227, 224, - 224, 228, 228, 241, 241, 240, 222, 222, 223, 223, - 250, 250, 250, 250, 251, 267, 268, 266, 266, 266, - 266, 266, 55, 55, 55, 177, 177, 177, 237, 237, - 236, 236, 236, 238, 238, 235, 235, 235, 235, 235, - 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, - 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, - 235, 235, 235, 235, 171, 171, 171, 265, 265, 265, - 265, 265, 265, 264, 264, 264, 234, 234, 234, 263, - 263, 120, 120, 121, 121, 28, 28, 28, 28, 28, + 279, 279, 87, 87, 85, 85, 86, 86, 152, 152, + 13, 14, 14, 162, 162, 161, 161, 161, 163, 163, + 163, 163, 197, 197, 15, 15, 15, 15, 15, 64, + 64, 261, 261, 260, 258, 258, 257, 257, 256, 23, + 24, 30, 31, 32, 263, 263, 232, 36, 36, 35, + 35, 35, 35, 37, 37, 34, 34, 33, 33, 234, + 234, 221, 221, 233, 233, 233, 233, 233, 233, 233, + 220, 199, 199, 199, 199, 202, 202, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 201, 201, 201, 201, + 201, 203, 203, 203, 203, 203, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 205, 205, 205, 205, 205, 205, 205, 205, 219, + 219, 206, 206, 212, 212, 213, 213, 213, 215, 215, + 216, 216, 177, 177, 177, 208, 208, 209, 209, 214, + 214, 210, 210, 210, 211, 211, 211, 218, 218, 218, + 218, 218, 207, 207, 222, 248, 248, 247, 247, 243, + 243, 243, 243, 231, 231, 240, 240, 240, 240, 240, + 230, 230, 226, 226, 226, 227, 227, 228, 228, 225, + 225, 229, 229, 242, 242, 241, 223, 223, 224, 224, + 251, 251, 251, 251, 252, 268, 269, 267, 267, 267, + 267, 267, 55, 55, 55, 178, 178, 178, 238, 238, + 237, 237, 237, 239, 239, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 172, 172, 172, 266, 266, 266, + 266, 266, 266, 265, 265, 265, 235, 235, 235, 264, + 264, 120, 120, 121, 121, 28, 28, 28, 28, 28, 28, 27, 27, 27, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 29, 29, 26, 26, 26, 26, 26, 26, 26, 26, 26, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 216, 216, 216, 252, 252, 253, - 253, 17, 22, 22, 18, 18, 18, 18, 19, 19, + 16, 16, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 217, 217, 217, 253, 253, 254, + 254, 17, 22, 22, 18, 18, 18, 18, 19, 19, 38, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 168, - 168, 269, 269, 170, 170, 166, 166, 169, 169, 167, - 167, 167, 172, 172, 172, 173, 173, 273, 273, 273, - 40, 40, 42, 42, 43, 44, 44, 191, 191, 192, - 192, 45, 46, 56, 56, 56, 56, 56, 56, 58, + 39, 39, 39, 39, 39, 39, 39, 39, 39, 169, + 169, 270, 270, 171, 171, 167, 167, 170, 170, 168, + 168, 168, 173, 173, 173, 174, 174, 274, 274, 274, + 40, 40, 42, 42, 43, 44, 44, 192, 192, 193, + 193, 45, 46, 56, 56, 56, 56, 56, 56, 58, 58, 58, 7, 7, 7, 7, 52, 52, 52, 6, - 6, 41, 41, 48, 270, 270, 271, 272, 272, 272, - 272, 49, 20, 279, 50, 51, 51, 63, 63, 63, + 6, 41, 41, 48, 271, 271, 272, 273, 273, 273, + 273, 49, 20, 280, 50, 51, 51, 63, 63, 63, 59, 59, 59, 62, 62, 62, 67, 67, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 66, - 66, 68, 68, 68, 68, 184, 184, 184, 183, 183, + 66, 68, 68, 68, 68, 185, 185, 185, 184, 184, 77, 77, 78, 78, 79, 79, 80, 80, 80, 118, - 95, 95, 150, 150, 149, 149, 152, 152, 81, 81, - 81, 81, 82, 82, 83, 83, 84, 84, 190, 190, - 189, 189, 189, 188, 188, 88, 88, 88, 90, 89, - 89, 89, 89, 91, 91, 93, 93, 92, 92, 94, - 96, 96, 96, 96, 96, 97, 97, 76, 76, 76, - 76, 76, 76, 76, 76, 164, 164, 99, 99, 98, - 98, 98, 98, 98, 98, 98, 98, 98, 98, 110, - 110, 110, 110, 110, 110, 100, 100, 100, 100, 100, - 100, 100, 65, 65, 111, 111, 111, 117, 112, 112, + 95, 95, 150, 150, 149, 149, 151, 151, 151, 151, + 153, 153, 81, 81, 81, 81, 82, 82, 83, 83, + 84, 84, 191, 191, 190, 190, 190, 189, 189, 88, + 88, 88, 90, 89, 89, 89, 89, 91, 91, 93, + 93, 92, 92, 94, 96, 96, 96, 96, 96, 97, + 97, 76, 76, 76, 76, 76, 76, 76, 76, 165, + 165, 99, 99, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 110, 110, 110, 110, 110, 110, 100, + 100, 100, 100, 100, 100, 100, 65, 65, 111, 111, + 111, 117, 112, 112, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 107, 107, 107, 107, 105, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, - 106, 106, 106, 106, 106, 106, 106, 106, 280, 280, - 109, 108, 108, 108, 108, 108, 108, 108, 61, 61, - 61, 61, 61, 195, 195, 195, 197, 197, 197, 197, - 197, 197, 197, 197, 197, 197, 197, 197, 197, 124, - 124, 60, 60, 122, 122, 123, 125, 125, 119, 119, - 119, 102, 102, 102, 102, 102, 102, 102, 102, 104, - 104, 104, 126, 126, 127, 127, 128, 128, 129, 129, - 130, 131, 131, 131, 132, 132, 132, 132, 248, 248, - 248, 248, 248, 243, 243, 243, 243, 244, 244, 244, - 71, 71, 71, 71, 73, 73, 72, 72, 53, 53, - 54, 54, 54, 74, 74, 75, 75, 75, 75, 147, - 147, 147, 133, 133, 133, 133, 138, 138, 138, 134, - 134, 136, 136, 136, 137, 137, 137, 135, 141, 141, - 143, 143, 142, 142, 140, 140, 145, 145, 144, 144, - 139, 139, 101, 101, 101, 101, 101, 148, 148, 148, - 148, 153, 153, 113, 113, 115, 115, 114, 116, 154, - 154, 158, 155, 155, 159, 159, 159, 159, 159, 156, - 156, 157, 157, 185, 185, 185, 163, 163, 174, 174, - 175, 175, 165, 165, 178, 178, 178, 146, 146, 146, - 146, 249, 249, 245, 181, 181, 182, 182, 186, 186, - 187, 187, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, - 179, 179, 179, 179, 179, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 103, 103, 103, 103, 103, 103, 103, 103, 107, 107, + 107, 107, 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, + 106, 106, 281, 281, 109, 108, 108, 108, 108, 108, + 108, 108, 61, 61, 61, 61, 61, 196, 196, 196, + 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 124, 124, 60, 60, 122, 122, 123, + 125, 125, 119, 119, 119, 102, 102, 102, 102, 102, + 102, 102, 102, 104, 104, 104, 126, 126, 127, 127, + 128, 128, 129, 129, 130, 131, 131, 131, 132, 132, + 132, 132, 249, 249, 249, 249, 249, 244, 244, 244, + 244, 245, 245, 245, 71, 71, 71, 71, 73, 73, + 72, 72, 53, 53, 54, 54, 54, 74, 74, 75, + 75, 75, 75, 147, 147, 147, 133, 133, 133, 133, + 138, 138, 138, 134, 134, 136, 136, 136, 137, 137, + 137, 135, 141, 141, 143, 143, 142, 142, 140, 140, + 145, 145, 144, 144, 139, 139, 101, 101, 101, 101, + 101, 148, 148, 148, 148, 154, 154, 113, 113, 115, + 115, 114, 116, 155, 155, 159, 156, 156, 160, 160, + 160, 160, 160, 157, 157, 158, 158, 186, 186, 186, + 164, 164, 175, 175, 176, 176, 166, 166, 179, 179, + 179, 146, 146, 146, 146, 250, 250, 246, 182, 182, + 183, 183, 187, 187, 188, 188, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, @@ -4154,14 +4200,33 @@ var yyR1 = [...]int{ 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 180, 180, 180, 276, 277, 193, 194, 194, 194, + 180, 180, 180, 180, 180, 180, 180, 180, 180, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 277, 278, 194, + 195, 195, 195, } var yyR2 = [...]int{ @@ -4222,41 +4287,41 @@ var yyR2 = [...]int{ 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, 3, 5, 0, 1, 2, 1, 1, 0, 2, 1, 3, 1, 1, 1, 3, 3, 3, - 3, 7, 0, 3, 1, 3, 1, 3, 4, 4, - 4, 3, 2, 4, 0, 1, 0, 2, 0, 1, - 0, 1, 2, 1, 1, 1, 2, 2, 1, 2, - 3, 2, 3, 2, 2, 2, 1, 1, 3, 3, - 0, 5, 4, 5, 5, 0, 2, 1, 3, 3, - 3, 2, 3, 1, 2, 0, 3, 1, 1, 3, - 3, 4, 4, 5, 3, 4, 5, 6, 2, 1, - 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 0, 2, 1, 1, 1, 3, 1, 3, - 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, + 3, 7, 0, 3, 1, 3, 1, 1, 3, 3, + 1, 3, 4, 4, 4, 3, 2, 4, 0, 1, + 0, 2, 0, 1, 0, 1, 2, 1, 1, 1, + 2, 2, 1, 2, 3, 2, 3, 2, 2, 2, + 1, 1, 3, 3, 0, 5, 4, 5, 5, 0, + 2, 1, 3, 3, 3, 2, 3, 1, 2, 0, + 3, 1, 1, 3, 3, 4, 4, 5, 3, 4, + 5, 6, 2, 1, 2, 1, 2, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, + 1, 3, 1, 3, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, - 1, 1, 1, 1, 4, 5, 5, 6, 4, 4, - 6, 6, 6, 8, 8, 8, 8, 9, 8, 5, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 8, 8, 0, 2, - 3, 4, 4, 4, 4, 4, 4, 4, 0, 3, - 4, 7, 3, 1, 1, 1, 2, 3, 3, 1, - 2, 2, 1, 2, 1, 2, 2, 1, 2, 0, - 1, 0, 2, 1, 2, 4, 0, 2, 1, 3, - 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 2, 0, 3, 0, 2, 0, 3, 1, 3, - 2, 0, 1, 1, 0, 2, 4, 4, 0, 2, - 2, 1, 1, 3, 3, 3, 3, 3, 3, 3, - 0, 3, 3, 3, 0, 3, 1, 1, 0, 4, - 0, 1, 1, 0, 3, 1, 3, 2, 1, 0, - 2, 4, 0, 9, 3, 5, 0, 3, 3, 0, - 1, 0, 2, 2, 0, 2, 2, 2, 0, 3, - 0, 3, 0, 3, 0, 4, 0, 3, 0, 4, - 0, 1, 2, 1, 5, 4, 4, 1, 3, 3, - 5, 0, 5, 1, 3, 1, 2, 3, 1, 1, - 3, 3, 1, 3, 3, 3, 3, 3, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, - 0, 3, 0, 1, 0, 1, 1, 0, 1, 1, - 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, + 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 1, 1, 1, 1, 4, 5, + 5, 6, 4, 4, 6, 6, 6, 8, 8, 8, + 8, 9, 8, 5, 4, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 8, 8, 0, 2, 3, 4, 4, 4, 4, 4, + 4, 4, 0, 3, 4, 7, 3, 1, 1, 1, + 2, 3, 3, 1, 2, 2, 1, 2, 1, 2, + 2, 1, 2, 0, 1, 0, 2, 1, 2, 4, + 0, 2, 1, 3, 5, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 0, 3, 0, 2, + 0, 3, 1, 3, 2, 0, 1, 1, 0, 2, + 4, 4, 0, 2, 2, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 0, 3, 3, 3, 0, 3, + 1, 1, 0, 4, 0, 1, 1, 0, 3, 1, + 3, 2, 1, 0, 2, 4, 0, 9, 3, 5, + 0, 3, 3, 0, 1, 0, 2, 2, 0, 2, + 2, 2, 0, 3, 0, 3, 0, 3, 0, 4, + 0, 3, 0, 4, 0, 1, 2, 1, 5, 4, + 4, 1, 3, 3, 5, 0, 5, 1, 3, 1, + 2, 3, 1, 1, 3, 3, 1, 3, 3, 3, + 3, 3, 2, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 0, 2, 0, 3, 0, 1, 0, 1, + 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -4295,29 +4360,30 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, + 0, 1, 1, } var yyChk = [...]int{ - -1000, -274, -1, -3, -8, -9, -10, -11, -12, -13, + -1000, -275, -1, -3, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -38, -39, -40, -42, -43, -44, -45, -46, -6, -41, -20, -21, -47, -48, - -49, -4, -276, 6, 7, 8, -57, 10, 11, 31, + -49, -4, -277, 6, 7, 8, -57, 10, 11, 31, -23, -30, 152, -31, -24, 153, -32, 155, 154, 190, 156, 183, 70, 224, 225, 227, 228, 229, 230, -58, 188, 189, 158, 35, 41, 32, 33, 80, 9, 322, - 185, 184, 26, -275, 451, -63, 5, -128, 16, -3, - -50, -279, -50, -50, -50, -50, -50, -50, -231, -233, - 80, 125, 80, -64, 162, -146, -262, 106, 168, 171, + 185, 184, 26, -276, 451, -63, 5, -128, 16, -3, + -50, -280, -50, -50, -50, -50, -50, -50, -232, -234, + 80, 125, 80, -64, 162, -146, -263, 106, 168, 171, 172, 313, 161, -36, -35, -34, -33, -37, 30, -28, - -29, -254, -27, -26, 157, 154, 198, 101, 102, 190, + -29, -255, -27, -26, 157, 154, 198, 101, 102, 190, 191, 192, 156, 174, 189, 193, 188, 207, -25, 76, - 32, 335, 338, -238, 153, 159, 160, 323, 104, 103, - 71, 155, -235, 274, 428, -37, 430, 94, 96, 429, + 32, 335, 338, -239, 153, 159, 160, 323, 104, 103, + 71, 155, -236, 274, 428, -37, 430, 94, 96, 429, 40, 163, 431, 432, 433, 434, 173, 435, 436, 437, - 438, 444, 445, 446, 447, 105, 5, 162, -262, -71, - 284, 76, -261, -258, 83, 84, 85, 162, 162, 163, - 164, -262, 162, -92, -186, -258, -180, 332, 176, 366, + 438, 444, 445, 446, 447, 105, 5, 162, -263, -71, + 284, 76, -262, -259, 83, 84, 85, 162, 162, 163, + 164, -263, 162, -92, -187, -259, -181, 332, 176, 366, 367, 222, 76, 274, 428, 224, 238, 232, 259, 251, 333, 368, 177, 211, 249, 252, 300, 430, 369, 191, 296, 279, 287, 94, 227, 309, 443, 370, 441, 96, @@ -4342,23 +4408,23 @@ var yyChk = [...]int{ 418, 245, 246, 260, 233, 256, 226, 423, 202, 190, 419, 310, 215, 277, 340, 207, 339, 253, 250, 209, 420, 164, 203, 204, 421, 424, 293, 283, 294, 295, - 284, 210, 338, 248, 278, 162, -156, 279, 280, 281, - 292, 293, 298, 297, 201, -273, 301, 162, -166, 143, - 152, 289, -170, 290, 283, 284, 210, -269, -258, 433, - 448, 300, 252, 302, 426, 285, 291, 295, 294, -186, - 226, -191, 231, -181, -258, -180, 229, -92, -56, 422, - 156, -193, -193, -193, -112, -76, -98, 109, -103, 30, + 284, 210, 338, 248, 278, 162, -157, 279, 280, 281, + 292, 293, 298, 297, 201, -274, 301, 162, -167, 143, + 152, 289, -171, 290, 283, 284, 210, -270, -259, 433, + 448, 300, 252, 302, 426, 285, 291, 295, 294, -187, + 226, -192, 231, -182, -259, -181, 229, -92, -56, 422, + 156, -194, -194, -194, -112, -76, -98, 109, -103, 30, 24, -102, -99, -119, -116, -117, 143, 144, 146, 145, 147, 132, 133, 140, 110, 148, -107, -105, -106, -108, 87, 86, 95, 88, 89, 90, 91, 97, 98, 99, - -181, -186, -114, -276, 64, 65, 323, 324, 325, 326, + -182, -187, -114, -277, 64, 65, 323, 324, 325, 326, 331, 327, 112, 53, 318, 312, 321, 320, 319, 316, 317, 314, 315, 329, 330, 167, 313, 161, 138, 322, - -258, -180, 40, 282, 282, -5, -4, -276, 6, 21, - 22, -132, 18, 17, -277, 82, -59, -69, 59, 60, - -70, 22, 36, 63, 61, -51, -68, 134, -76, -186, - -68, -165, 166, -165, -165, -155, -196, 226, -159, 302, - 301, -182, -157, -181, -179, -156, 299, 157, 341, 108, + -259, -181, 40, 282, 282, -5, -4, -277, 6, 21, + 22, -132, 18, 17, -278, 82, -59, -69, 59, 60, + -70, 22, 36, 63, 61, -51, -68, 134, -76, -187, + -68, -166, 166, -166, -166, -156, -197, 226, -160, 302, + 301, -183, -158, -182, -180, -157, 299, 157, 341, 108, 23, 25, 111, 143, 17, 112, 159, 174, 142, 170, 323, 152, 68, 342, 314, 315, 312, 318, 325, 326, 313, 280, 30, 11, 344, 26, 184, 22, 36, 136, @@ -4372,266 +4438,267 @@ var yyChk = [...]int{ 281, 6, 328, 31, 183, 171, 63, 364, 162, 114, 329, 330, 165, 98, 5, 168, 33, 10, 70, 73, 319, 320, 321, 53, 335, 113, 13, 365, 306, 107, - 300, 252, -232, 125, -219, -223, -181, 178, -251, 174, - -92, -241, -240, -181, -71, -175, 167, 163, -175, 322, - -33, -34, -156, 142, 195, 81, 81, -223, -222, -221, - -263, 197, 178, -250, -239, 170, 179, -229, 171, 172, - -224, 163, 29, -263, -224, 169, 179, 197, 197, 105, + 300, 252, -233, 125, -220, -224, -182, 178, -252, 174, + -92, -242, -241, -182, -71, -176, 167, 163, -176, 322, + -33, -34, -157, 142, 195, 81, 81, -224, -223, -222, + -264, 197, 178, -251, -240, 170, 179, -230, 171, 172, + -225, 163, 29, -264, -225, 169, 179, 197, 197, 105, 197, 105, 197, 197, 197, 197, 197, 197, 197, 197, - 197, 194, -230, 117, -230, 339, 339, -235, -263, -263, - -263, 165, 34, 34, -178, -224, 165, 23, -230, -230, - -156, 142, -230, -230, -230, -230, 205, 205, -230, -230, - -230, -230, -230, -230, -230, -230, -230, -230, -230, -230, - -230, -230, -230, -92, -74, 212, 152, 154, 157, 72, - 117, -35, 207, -22, -92, -174, 167, -258, -174, -174, - -92, 149, -92, -172, 125, 13, -172, -172, -172, -172, - -172, 208, 296, 208, 296, 208, 209, 208, 209, 208, - -169, -168, 287, 288, 282, 286, -258, 313, 298, -258, - 201, 162, 202, 164, -225, 163, 34, 175, 209, 282, - 204, -172, -194, -276, -182, -194, -194, 31, 165, -181, - -52, -181, 87, -7, -3, -11, -10, -12, 117, 81, + 197, 194, -231, 117, -231, 339, 339, -236, -264, -264, + -264, 165, 34, 34, -179, -225, 165, 23, -231, -231, + -157, 142, -231, -231, -231, -231, 205, 205, -231, -231, + -231, -231, -231, -231, -231, -231, -231, -231, -231, -231, + -231, -231, -231, -92, -74, 212, 152, 154, 157, 72, + 117, -35, 207, -22, -92, -175, 167, -259, -175, -175, + -92, 149, -92, -173, 125, 13, -173, -173, -173, -173, + -173, 208, 296, 208, 296, 208, 209, 208, 209, 208, + -170, -169, 287, 288, 282, 286, -259, 313, 298, -259, + 201, 162, 202, 164, -226, 163, 34, 175, 209, 282, + 204, -173, -195, -277, -183, -195, -195, 31, 165, -182, + -52, -182, 87, -7, -3, -11, -10, -12, 117, 81, 108, 106, 107, 124, -76, -100, 127, 109, 125, 126, 111, 129, 128, 139, 132, 133, 134, 135, 136, 137, 138, 130, 131, 142, 117, 118, 119, 120, 121, 122, - 123, -164, -276, -117, -276, 150, 151, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -103, -276, 149, -2, - -112, -4, -276, -276, -276, -276, -276, -276, -276, -276, - -124, -76, -276, -280, -276, -280, -109, -276, -280, -109, - -280, -109, -280, -280, -109, -280, -109, -280, -280, -109, - -276, -276, -276, -276, -276, -276, -276, -193, -270, -271, + 123, -165, -277, -117, -277, 150, 151, -103, -103, -103, + -103, -103, -103, -103, -103, -103, -103, -277, 149, -2, + -112, -4, -277, -277, -277, -277, -277, -277, -277, -277, + -124, -76, -277, -281, -277, -281, -109, -277, -281, -109, + -281, -109, -281, -281, -109, -281, -109, -281, -281, -109, + -277, -277, -277, -277, -277, -277, -277, -194, -271, -272, -95, -92, -128, -3, -50, -147, 20, 32, -76, -129, -130, -76, -128, 55, -66, -68, -70, 59, 60, 93, - 12, -184, -183, 23, -181, 87, 149, 12, -93, 27, - -92, -78, -79, -80, -81, -95, -118, -276, 12, -85, - -86, -92, -94, -186, 81, 226, -159, -196, -161, -160, - 303, 305, 117, -185, -181, 87, 30, 82, 81, -92, - -198, -201, -203, -202, -204, -199, -200, 249, 250, 143, + 12, -185, -184, 23, -182, 87, 149, 12, -93, 27, + -92, -78, -79, -80, -81, -95, -118, -277, 12, -85, + -86, -92, -94, -187, 81, 226, -160, -197, -162, -161, + 303, 305, 117, -186, -182, 87, 30, 82, 81, -92, + -199, -202, -204, -203, -205, -200, -201, 249, 250, 143, 253, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 31, 186, 245, 246, 247, 248, 265, 266, 267, 268, 269, 270, 271, 272, 232, 251, 333, 233, 234, - 235, 236, 237, 238, 240, 241, 242, 243, 244, -261, - -258, 80, 82, 81, -205, 80, -74, -92, 109, -258, - -258, -230, -230, 194, -27, -26, -254, 16, -25, -26, - 157, 101, 102, 154, 80, -219, 80, -228, -261, -258, - 80, 29, 169, 168, -227, -224, -227, -228, -258, -119, - -181, -186, -258, 29, 29, -152, -181, -152, -152, 21, - -152, 21, -152, 21, 88, -181, -152, 21, -152, 21, - -152, 21, -152, 21, -152, 21, 30, 74, 75, 30, - 77, 78, 79, -119, -119, -219, -156, -92, -258, 88, - 88, -230, -230, 88, 87, 87, 87, -230, -230, 88, - 87, -258, 87, -264, 180, 221, 223, 88, 88, 88, - 88, 30, 87, -265, 30, 440, 439, 441, 442, 443, - 88, 30, 88, 30, 88, -181, 80, -73, 214, 117, + 235, 236, 237, 238, 240, 241, 242, 243, 244, -262, + -259, 80, 82, 81, -206, 80, -74, -92, 109, -259, + -259, -231, -231, 194, -27, -26, -255, 16, -25, -26, + 157, 101, 102, 154, 80, -220, 80, -229, -262, -259, + 80, 29, 169, 168, -228, -225, -228, -229, -259, -119, + -182, -187, -259, 29, 29, -153, -182, -153, -153, 21, + -153, 21, -153, 21, 88, -182, -153, 21, -153, 21, + -153, 21, -153, 21, -153, 21, 30, 74, 75, 30, + 77, 78, 79, -119, -119, -220, -157, -92, -259, 88, + 88, -231, -231, 88, 87, 87, 87, -231, -231, 88, + 87, -259, 87, -265, 180, 221, 223, 88, 88, 88, + 88, 30, 87, -266, 30, 440, 439, 441, 442, 443, + 88, 30, 88, 30, 88, -182, 80, -73, 214, 117, 203, 203, 162, 162, 216, -92, 215, 217, 218, 40, - 81, 165, -85, 24, 72, -87, -92, -258, -187, -186, - -179, 87, -76, -172, -92, -172, -92, -172, -172, -172, - -172, -167, 12, 127, -226, 12, 127, -167, -194, -194, - -92, -194, -194, -92, -194, -194, -226, -173, 125, 72, - -192, 229, 263, 423, 424, 425, -76, -76, -76, -76, + 81, 165, -85, 24, 72, -87, -92, -259, -188, -187, + -180, 87, -76, -173, -92, -173, -92, -173, -173, -173, + -173, -168, 12, 127, -227, 12, 127, -168, -195, -195, + -92, -195, -195, -92, -195, -195, -227, -174, 125, 72, + -193, 229, 263, 423, 424, 425, -76, -76, -76, -76, -110, 97, 109, 98, 99, -103, -111, -114, -117, 92, 127, 125, 126, 111, -103, -103, -103, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -103, -103, -103, -195, - -258, 87, 143, -258, -102, -102, -181, -67, 22, 36, - -66, -182, -187, -179, -63, -277, -277, -128, -66, -66, + -103, -103, -103, -103, -103, -103, -103, -103, -103, -196, + -259, 87, 143, -259, -102, -102, -182, -67, 22, 36, + -66, -183, -188, -180, -63, -278, -278, -128, -66, -66, -76, -76, -119, 87, -66, -119, 87, -66, -66, -62, - 22, 36, -122, -123, 113, -119, -277, -103, -181, -181, - -66, -67, -67, -66, -66, 81, -272, 305, 306, 427, - -189, 197, -188, 23, -186, 87, -132, -277, -133, 27, + 22, 36, -122, -123, 113, -119, -278, -103, -182, -182, + -66, -67, -67, -66, -66, 81, -273, 305, 306, 427, + -190, 197, -189, 23, -187, 87, -132, -278, -133, 27, 10, 127, 81, 19, 81, -131, 25, 26, -132, -104, - -181, 88, 91, -77, 81, 12, -70, -92, -183, 134, - -187, -92, -151, 197, -92, 31, 81, -88, -90, -89, - -91, 62, 66, 68, 63, 64, 65, 69, -190, 23, - -78, -3, -276, -92, -85, -278, 81, 12, 73, -278, - 81, 149, -159, -161, 81, 304, 306, 307, 72, 100, - -76, -210, 142, -237, -236, -235, -219, -221, -222, -223, - 82, -176, 97, 109, -214, 277, -205, -205, -205, -205, - -205, -209, -156, -209, -209, -209, 80, 80, -205, -205, - -205, -205, -211, 80, -211, -211, -212, 80, -212, -251, - -76, -247, -246, -242, -245, 173, 94, 335, 73, -240, - -131, 88, -73, 24, -249, -245, -258, 87, -258, 87, - 81, 17, -220, -219, -120, 221, -253, 197, -250, -241, - 80, 29, -227, -228, -228, 149, -258, 81, 27, 105, - 105, 105, 105, 335, 154, 31, -219, -120, -195, 165, - -195, -195, 87, 87, -171, 448, -85, 164, 220, -75, + -182, 88, 91, -77, 81, 12, -70, -92, -184, 134, + -188, -92, -152, 197, -92, 31, 81, -88, -90, -89, + -91, 62, 66, 68, 63, 64, 65, 69, -191, 23, + -78, -3, -277, -92, -85, -279, 81, 12, 73, -279, + 81, 149, -160, -162, 81, 304, 306, 307, 72, 100, + -76, -211, 142, -238, -237, -236, -220, -222, -223, -224, + 82, -177, 97, 109, -215, 277, -206, -206, -206, -206, + -206, -210, -157, -210, -210, -210, 80, 80, -206, -206, + -206, -206, -212, 80, -212, -212, -213, 80, -213, -252, + -76, -248, -247, -243, -246, 173, 94, 335, 73, -241, + -131, 88, -73, 24, -250, -246, -259, 87, -259, 87, + 81, 17, -221, -220, -120, 221, -254, 197, -251, -242, + 80, 29, -228, -229, -229, 149, -259, 81, 27, 105, + 105, 105, 105, 335, 154, 31, -220, -120, -196, 165, + -196, -196, 87, 87, -172, 448, -85, 164, 220, -75, 318, 87, 83, -92, -92, -92, -92, -92, 157, 154, - 205, -92, -92, -55, 182, 177, -92, 81, -55, -172, - -186, -186, -92, -172, -92, 87, -92, -181, 97, 98, - 99, -111, -103, -103, -103, -65, 187, 108, -277, -277, - -66, -66, -276, 149, -5, -132, -277, -277, 81, 73, - 23, 12, 12, -277, 12, 12, -277, -277, -66, -125, - -123, 115, -76, -277, -277, 81, 81, -277, -277, -277, - -277, -277, -271, 426, 306, -96, 70, 166, 71, -276, - -188, -147, 38, 46, 57, -76, -76, -130, -147, -163, + 205, -92, -92, -55, 182, 177, -92, 81, -55, -173, + -187, -187, -92, -173, -92, 87, -92, -182, 97, 98, + 99, -111, -103, -103, -103, -65, 187, 108, -278, -278, + -66, -66, -277, 149, -5, -132, -278, -278, 81, 73, + 23, 12, 12, -278, 12, 12, -278, -278, -66, -125, + -123, 115, -76, -278, -278, 81, 81, -278, -278, -278, + -278, -278, -272, 426, 306, -96, 70, 166, 71, -277, + -189, -147, 38, 46, 57, -76, -76, -130, -147, -164, 20, 12, 53, 53, -97, 13, -68, -78, -70, 149, - -97, -101, 31, 53, -3, -276, -276, -154, -158, -119, + -97, -101, 31, 53, -3, -277, -277, -155, -159, -119, -79, -80, -80, -79, -80, 62, 62, 62, 67, 62, - 67, 62, -89, -186, -277, -277, -3, -151, 73, -78, - -92, -78, -94, -186, 134, -160, -162, 308, 305, 311, - -258, 87, 81, -235, -223, -207, 30, 97, -215, 278, - -209, -209, -210, -258, 143, -210, -210, -210, -218, 87, - -218, 88, 88, 82, -248, -243, -244, 32, 76, -242, - -230, 87, 37, -181, 82, 164, 72, 16, -149, -181, - 81, 82, -121, 222, -119, 82, -181, 82, -149, -228, - -182, -181, -276, 162, 30, 30, -120, -121, -210, -258, - 450, 449, 82, -92, -72, 212, 219, 80, 84, -260, - 73, 203, 274, 203, 206, 165, -194, -92, -167, -167, - -65, 108, -103, -103, -277, -277, -67, -182, -128, -147, - -197, 143, 249, 186, 247, 243, 263, 254, 276, 245, - 277, -195, -197, -103, -103, -103, -103, 332, -128, 116, - -76, 114, -103, -103, 163, 163, 163, -152, 39, 87, - 87, 58, -92, -126, 14, -76, 134, -132, -153, 72, - -154, -113, -115, -114, -276, -148, -277, -181, -152, -97, + 67, 62, -89, -187, -278, -278, -3, -152, 73, -78, + -92, -78, -94, -187, 134, -161, -163, 308, 305, 311, + -259, 87, 81, -236, -224, -208, 30, 97, -216, 278, + -210, -210, -211, -259, 143, -211, -211, -211, -219, 87, + -219, 88, 88, 82, -249, -244, -245, 32, 76, -243, + -231, 87, 37, -182, 82, 164, 72, 16, -149, -182, + 81, 82, -121, 222, -119, 82, -182, 82, -149, -229, + -183, -182, -277, 162, 30, 30, -120, -121, -211, -259, + 450, 449, 82, -92, -72, 212, 219, 80, 84, -261, + 73, 203, 274, 203, 206, 165, -195, -92, -168, -168, + -65, 108, -103, -103, -278, -278, -67, -183, -128, -147, + -198, 143, 249, 186, 247, 243, 263, 254, 276, 245, + 277, -196, -198, -103, -103, -103, -103, 332, -128, 116, + -76, 114, -103, -103, 163, 163, 163, -153, 39, 87, + 87, 58, -92, -126, 14, -76, 134, -132, -154, 72, + -155, -113, -115, -114, -277, -148, -278, -182, -153, -97, 81, 117, -83, -82, 72, 73, -84, 72, -82, 62, - 62, -277, -97, -78, -97, -97, 149, 305, 309, 310, - -235, -208, 72, -103, -210, -210, 82, 81, 82, 81, - 82, 81, -177, 372, 109, -244, -243, -230, -230, 88, - -258, -92, -92, 17, 81, -219, -119, 53, -247, 82, - -252, -253, -92, -102, -121, -150, 80, 82, -257, 335, - -259, -258, -181, -181, -181, -92, -172, -172, -103, -277, - -132, -277, -205, -205, -205, -212, -205, 237, -205, 237, - -277, -277, 20, 20, 20, 20, -276, -60, 328, -76, - 81, 81, -276, -276, -276, -277, 87, -209, -127, 15, - 17, 28, -153, 81, -277, -277, 81, 53, 149, -277, - -128, -158, -76, -76, 80, -76, -128, -97, -213, 274, - 10, -209, 87, -209, 88, 88, 372, 30, 77, 78, - 79, 30, 74, 75, -150, -149, -181, 199, 181, -277, - 81, -216, 335, 338, 23, -149, -256, -255, -182, 80, - 73, -147, -209, -258, -103, -103, -103, -103, -103, -132, - 87, -103, -103, -149, -277, -149, -149, -189, -209, -135, - -140, -169, -76, -112, 29, -115, 53, -3, -181, -113, - -181, -132, -149, -132, -217, 169, 29, 168, -106, -210, - -210, 82, 82, 23, 200, -92, -253, 339, 339, -3, - 82, 81, 117, -149, -92, -277, -277, -277, -277, -61, - 127, 335, -277, -277, -277, -277, -277, -277, -96, -138, - 422, -141, 42, -142, 43, 10, -113, 149, 82, -206, - 94, 29, 29, -3, -276, 80, -53, 335, -255, -234, - -182, 87, 88, 82, -277, 333, 69, 336, -135, 47, - 255, -143, 51, -144, -139, 52, 17, -154, -181, 87, - -53, -103, 196, -149, -54, 211, 426, -260, 58, 334, - 337, -136, 49, -134, 48, -134, -142, 17, -145, 44, - 45, 87, -277, -277, 82, 174, -257, 58, -137, 50, - 72, 100, 87, 17, 17, -267, -268, 72, 213, 335, - 72, 100, 87, 87, -268, 72, 11, 10, 336, -266, - 182, 177, 180, 31, -266, 337, 176, 30, 97, + 62, -278, -97, -78, -97, -97, 149, 305, 309, 310, + -236, -209, 72, -103, -211, -211, 82, 81, 82, 81, + 82, 81, -178, 372, 109, -245, -244, -231, -231, 88, + -259, -92, -92, 17, 81, -220, -119, 53, -248, 82, + -253, -254, -92, -102, -121, -150, 80, 82, -258, 335, + -260, -259, -182, -182, -182, -92, -173, -173, -103, -278, + -132, -278, -206, -206, -206, -213, -206, 237, -206, 237, + -278, -278, 20, 20, 20, 20, -277, -60, 328, -76, + 81, 81, -277, -277, -277, -278, 87, -210, -127, 15, + 17, 28, -154, 81, -278, -278, 81, 53, 149, -278, + -128, -159, -76, -76, 80, -76, -128, -97, -214, 274, + 10, -210, 87, -210, 88, 88, 372, 30, 77, 78, + 79, 30, 74, 75, -150, -149, -182, 199, 181, -278, + 81, -217, 335, 338, 23, -149, -257, -256, -183, 80, + 73, -147, -210, -259, -103, -103, -103, -103, -103, -132, + 87, -103, -103, -151, -278, -182, 169, -151, -151, -190, + -210, -135, -140, -170, -76, -112, 29, -115, 53, -3, + -182, -113, -182, -132, -149, -132, -218, 169, 29, 168, + -106, -211, -211, 82, 82, 23, 200, -92, -254, 339, + 339, -3, 82, 81, 117, -149, -92, -278, -278, -278, + -278, -61, 127, 335, -278, -278, -278, 81, -278, -278, + -278, -96, -138, 422, -141, 42, -142, 43, 10, -113, + 149, 82, -207, 94, 29, 29, -3, -277, 80, -53, + 335, -256, -235, -183, 87, 88, 82, -278, 333, 69, + 336, -182, 169, -135, 47, 255, -143, 51, -144, -139, + 52, 17, -155, -182, 87, -53, -103, 196, -149, -54, + 211, 426, -261, 58, 334, 337, -136, 49, -134, 48, + -134, -142, 17, -145, 44, 45, 87, -278, -278, 82, + 174, -258, 58, -137, 50, 72, 100, 87, 17, 17, + -268, -269, 72, 213, 335, 72, 100, 87, 87, -269, + 72, 11, 10, 336, -267, 182, 177, 180, 31, -267, + 337, 176, 30, 97, } var yyDef = [...]int{ 32, -2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 786, 0, 523, 523, 523, 523, 523, 523, 523, - 0, 0, -2, -2, -2, 810, 36, 0, 0, 0, + 31, 790, 0, 523, 523, 523, 523, 523, 523, 523, + 0, 0, -2, -2, -2, 814, 36, 0, 0, 0, 0, -2, 481, 482, 0, 484, -2, 0, 0, 493, - 1305, 1305, 1305, 0, 0, 0, 0, 1303, 53, 54, - 499, 500, 501, 1, 3, 0, 527, 794, 0, 0, - -2, 525, 0, 0, 902, 902, 902, 0, 84, 85, - 0, 0, 0, 810, 900, 0, 900, 0, 908, 909, - 910, 104, 105, 88, -2, 109, 110, 0, 114, 367, + 1309, 1309, 1309, 0, 0, 0, 0, 1307, 53, 54, + 499, 500, 501, 1, 3, 0, 527, 798, 0, 0, + -2, 525, 0, 0, 906, 906, 906, 0, 84, 85, + 0, 0, 0, 814, 904, 0, 904, 0, 912, 913, + 914, 104, 105, 88, -2, 109, 110, 0, 114, 367, 328, 370, 326, 356, -2, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, 223, 223, 0, 0, -2, 319, 319, 319, 0, 0, 0, - 353, 904, 273, 223, 223, 0, 223, 223, 223, 223, + 353, 908, 273, 223, 223, 0, 223, 223, 223, 223, 0, 0, 223, 223, 223, 223, 223, 223, 223, 223, - 223, 223, 223, 223, 223, 223, 223, 0, 103, 823, - 0, 0, 113, 37, 33, 34, 35, 0, 898, 0, - 898, 898, 0, 419, 607, 918, 919, 1055, 1056, 1057, - 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, - 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, - 1078, 1079, 1080, 1081, 1082, 1083, 1084, 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, 1115, 1116, 1117, - 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, - 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, - 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, - 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, - 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, - 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, - 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, - 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, - 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, - 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, - 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, - 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, - 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, - 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, - 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, - 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, - 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, - 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, - 1298, 1299, 1300, 1301, 1302, 0, 472, 472, 472, 472, + 223, 223, 223, 223, 223, 223, 223, 0, 103, 827, + 0, 0, 113, 37, 33, 34, 35, 0, 902, 0, + 902, 902, 0, 419, 611, 922, 923, 1059, 1060, 1061, + 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, + 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, + 1082, 1083, 1084, 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, 1115, 1116, 1117, 1118, 1119, 1120, 1121, + 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, + 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, + 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, + 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, + 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, + 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, + 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, + 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, + 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, + 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, + 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, + 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, + 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, + 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, + 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, + 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, + 1302, 1303, 1304, 1305, 1306, 0, 472, 472, 472, 472, 472, 472, 0, 428, 0, 0, 0, 0, 0, 0, - 0, 444, 0, 447, 0, 0, 454, 472, 1306, 1306, - 1306, 889, 0, 478, 479, 466, 464, 461, 462, 480, - 483, 0, 488, 491, 914, 915, 0, 506, 0, 1126, - 498, 511, 512, 522, 38, 658, 617, 0, 623, 625, - 0, 660, 661, 662, 663, 664, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 690, 691, 692, 693, - 771, 772, 773, 774, 775, 776, 777, 778, 627, 628, - 768, 0, 878, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 759, 0, 728, 728, 728, 728, 728, 728, - 728, 728, 728, 0, 0, 0, 0, 0, 0, 0, - -2, -2, 1305, 0, 521, 786, 49, 0, 523, 528, - 529, 829, 0, 0, 786, 1304, 0, 0, -2, -2, + 0, 444, 0, 447, 0, 0, 454, 472, 1310, 1310, + 1310, 893, 0, 478, 479, 466, 464, 461, 462, 480, + 483, 0, 488, 491, 918, 919, 0, 506, 0, 1130, + 498, 511, 512, 522, 38, 662, 621, 0, 627, 629, + 0, 664, 665, 666, 667, 668, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 694, 695, 696, 697, + 775, 776, 777, 778, 779, 780, 781, 782, 631, 632, + 772, 0, 882, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 763, 0, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 0, 0, 0, 0, 0, 0, 0, + -2, -2, 1309, 0, 521, 790, 49, 0, 523, 528, + 529, 833, 0, 0, 790, 1308, 0, 0, -2, -2, 539, 545, 546, 547, 548, 524, 0, 551, 555, 0, - 0, 0, 903, 0, 0, 70, 0, 1274, 882, -2, - -2, 0, 0, 916, 917, 891, -2, 922, 923, 924, - 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, - 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, - 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, - 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, - 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, - 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, - 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, - 995, 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, - 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, - 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, - 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, - -2, 1073, 0, 0, 123, 124, 0, 36, 249, 0, - 119, 0, 243, 181, 823, 0, 0, 0, 0, 90, + 0, 0, 907, 0, 0, 70, 0, 1278, 886, -2, + -2, 0, 0, 920, 921, 895, -2, 926, 927, 928, + 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, + 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, + 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, + 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, + 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, + 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, + 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, + 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, + 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, + 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, + 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, + 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, + -2, 1077, 0, 0, 123, 124, 0, 36, 249, 0, + 119, 0, 243, 181, 827, 0, 0, 0, 0, 90, 111, 112, 223, 223, 0, 113, 113, 335, 336, 337, 0, 0, -2, 247, 0, 320, 0, 0, 237, 237, 241, 239, 240, 0, 0, 0, 0, 0, 0, 347, 0, 348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 224, 0, 365, 366, 274, 0, 0, - 0, 0, 345, 346, 0, 0, 905, 906, 0, 0, + 0, 0, 345, 346, 0, 0, 909, 910, 0, 0, 223, 223, 0, 0, 0, 0, 223, 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 100, 814, 0, 0, 0, 0, 0, + 0, 0, 0, 100, 818, 0, 0, 0, 0, 0, 0, -2, 0, 411, 0, 0, 0, 0, 0, 0, 418, 0, 420, 421, 0, 0, 422, 423, 424, 425, 426, 472, 0, 472, 0, 472, 472, 472, 472, 469, - 0, 469, 467, 468, 459, 460, 1306, 1306, 0, 1306, - 1306, 0, 1306, 1306, 0, 232, 233, 234, 475, 451, - 452, 455, 456, 1307, 1308, 457, 458, 890, 489, 492, + 0, 469, 467, 468, 459, 460, 1310, 1310, 0, 1310, + 1310, 0, 1310, 1310, 0, 232, 233, 234, 475, 451, + 452, 455, 456, 1311, 1312, 457, 458, 894, 489, 492, 509, 507, 508, 510, 502, 503, 504, 505, 0, 0, - 0, 0, 0, 0, 621, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 645, 646, 647, 648, 649, 650, - 651, 624, 0, 638, 0, 0, 0, 680, 681, 682, - 683, 684, 685, 686, 687, 688, 0, 536, 0, 0, - 0, 786, 0, 0, 0, 0, 0, 0, 0, 533, - 0, 760, 0, 711, 0, 712, 720, 0, 713, 721, - 714, 722, 715, 716, 723, 717, 724, 718, 719, 725, + 0, 0, 0, 0, 625, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 649, 650, 651, 652, 653, 654, + 655, 628, 0, 642, 0, 0, 0, 684, 685, 686, + 687, 688, 689, 690, 691, 692, 0, 536, 0, 0, + 0, 790, 0, 0, 0, 0, 0, 0, 0, 533, + 0, 764, 0, 715, 0, 716, 724, 0, 717, 725, + 718, 726, 719, 720, 727, 721, 728, 722, 723, 729, 0, 0, 0, 536, 536, 0, 0, 39, 513, 514, - 0, 590, 794, 0, 538, 832, 0, 0, 795, 787, - 788, 791, 794, 0, 560, 549, 540, 543, 544, 526, + 0, 594, 798, 0, 538, 836, 0, 0, 799, 791, + 792, 795, 798, 0, 560, 549, 540, 543, 544, 526, 0, 552, 556, 0, 558, 559, 0, 0, 68, 0, - 606, 0, 562, 564, 565, 566, 588, 0, 0, 0, - 0, 64, 66, 607, 0, 1274, 888, 0, 72, 73, - 0, 0, 0, 204, 893, 894, 895, -2, 230, 0, + 610, 0, 562, 564, 565, 566, 592, 0, 0, 0, + 0, 64, 66, 611, 0, 1278, 892, 0, 72, 73, + 0, 0, 0, 204, 897, 898, 899, -2, 230, 0, 192, 188, 132, 133, 134, 181, 136, 181, 181, 181, 181, 201, 201, 201, 201, 164, 165, 166, 167, 168, 0, 0, 151, 181, 181, 181, 181, 171, 172, 173, 174, 175, 176, 177, 178, 137, 138, 139, 140, 141, 142, 143, 144, 145, 183, 183, 183, 185, 185, 0, - 37, 0, 215, 0, 791, 0, 814, 99, 0, 911, + 37, 0, 215, 0, 795, 0, 818, 99, 0, 915, 102, 0, 0, 368, 329, 357, 369, 0, 332, 333, -2, 0, 0, 319, 0, 321, 0, 231, 0, -2, 0, 0, 0, 237, 241, 238, 241, 229, 242, 349, - 768, 0, 350, 351, 0, 383, 576, 0, 0, 0, + 772, 0, 350, 351, 0, 383, 580, 0, 0, 0, 0, 0, 389, 390, 391, 0, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 358, 359, 360, 361, 362, 363, 364, 0, 0, 321, 0, 354, 0, 275, @@ -4639,97 +4706,98 @@ var yyDef = [...]int{ 286, 287, 288, 289, 313, 314, 315, 290, 291, 292, 293, 294, 295, 296, 307, 308, 309, 310, 311, 312, 297, 298, 299, 300, 301, 304, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 811, 812, 813, 0, - 0, 0, 262, 899, 0, 262, 62, 417, 608, 920, - 921, 473, 474, 427, 445, 429, 448, 430, 432, 431, + 0, 0, 0, 0, 0, 0, 815, 816, 817, 0, + 0, 0, 262, 903, 0, 262, 62, 417, 612, 924, + 925, 473, 474, 427, 445, 429, 448, 430, 432, 431, 433, 472, 0, 0, 0, 235, 236, 472, 436, 437, 438, 439, 440, 441, 442, 443, 0, 450, 0, 0, - 0, 490, 494, 495, 496, 497, 659, 618, 619, 620, - 622, 639, 0, 641, 643, 629, 630, 654, 655, 656, - 0, 0, 0, 0, 652, 634, 0, 665, 666, 667, - 668, 669, 670, 671, 672, 673, 674, 675, 676, 679, - 743, 744, 745, 0, 677, 678, 689, 0, 0, 0, - 537, 769, 0, -2, 0, 657, 877, 794, 0, 0, - 0, 0, 662, 771, 0, 662, 771, 0, 0, 0, - 534, 535, 766, 763, 0, 0, 729, 0, 0, 0, + 0, 490, 494, 495, 496, 497, 663, 622, 623, 624, + 626, 643, 0, 645, 647, 633, 634, 658, 659, 660, + 0, 0, 0, 0, 656, 638, 0, 669, 670, 671, + 672, 673, 674, 675, 676, 677, 678, 679, 680, 683, + 747, 748, 749, 0, 681, 682, 693, 0, 0, 0, + 537, 773, 0, -2, 0, 661, 881, 798, 0, 0, + 0, 0, 666, 775, 0, 666, 775, 0, 0, 0, + 534, 535, 770, 767, 0, 0, 733, 0, 0, 0, 0, 0, 0, 0, 0, 0, 516, 517, 519, 0, - 610, 0, 591, 0, 593, 594, 829, 50, 40, 0, - 830, 0, 0, 0, 0, 790, 792, 793, 829, 0, - 779, 0, 0, 615, 0, 0, 541, 46, 557, 553, - 0, 615, 0, 0, 605, 0, 0, 0, 0, 0, - 0, 595, 0, 0, 598, 0, 0, 0, 0, 589, + 614, 0, 595, 0, 597, 598, 833, 50, 40, 0, + 834, 0, 0, 0, 0, 794, 796, 797, 833, 0, + 783, 0, 0, 619, 0, 0, 541, 46, 557, 553, + 0, 619, 0, 0, 609, 0, 0, 0, 0, 0, + 0, 599, 0, 0, 602, 0, 0, 0, 0, 593, 0, 0, 0, -2, 0, 0, 0, 60, 61, 0, - 0, 0, 883, 71, 0, 0, 76, 77, 884, 885, - 886, 887, 0, 106, -2, 270, 125, 127, 128, 129, + 0, 0, 887, 71, 0, 0, 76, 77, 888, 889, + 890, 891, 0, 106, -2, 270, 125, 127, 128, 129, 120, 195, 193, 0, 190, 189, 135, 201, 201, 158, 159, 204, 0, 204, 204, 204, 0, 0, 152, 153, 154, 155, 146, 0, 147, 148, 149, 0, 150, 248, - 0, 798, 216, 217, 219, 223, 0, 0, 0, 244, - 245, 0, 0, 901, 0, 912, 115, 116, 117, 118, + 0, 802, 216, 217, 219, 223, 0, 0, 0, 244, + 245, 0, 0, 905, 0, 916, 115, 116, 117, 118, 113, 0, 0, 121, 323, 0, 0, 0, 246, 0, 0, 225, 241, 226, 227, 0, 352, 0, 0, 385, 386, 387, 388, 0, 0, 0, 321, 323, 204, 0, - 277, 278, 283, 284, 302, 0, 0, 0, 0, 824, - 825, 0, 828, 91, 375, 377, 376, 380, 0, 0, - 0, 0, 412, 414, 263, 264, 1306, 0, 416, 434, - 470, 471, 469, 449, 469, 476, 453, 486, 640, 642, - 644, 631, 652, 635, 0, 632, 0, 0, 626, 694, - 0, 0, 536, 0, 786, 829, 698, 699, 0, 0, - 0, 0, 0, 736, 0, 0, 737, 0, 786, 0, - 764, 0, 0, 710, 730, 0, 0, 731, 732, 733, - 734, 735, 515, 518, 520, 570, 0, 0, 0, 0, - 592, 42, 0, 0, 0, 796, 797, 789, 41, 0, - 896, 897, 780, 781, 782, 0, 550, 561, 542, 0, - 794, 871, 0, 0, 863, 0, 0, 615, 879, 0, - 563, 584, 586, 0, 581, 596, 597, 599, 0, 601, - 0, 603, 604, 567, 568, 569, 0, 615, 0, 615, - 65, 615, 67, 0, 609, 74, 75, 0, 0, 81, + 277, 278, 283, 284, 302, 0, 0, 0, 0, 828, + 829, 0, 832, 91, 375, 377, 376, 380, 0, 0, + 0, 0, 412, 414, 263, 264, 1310, 0, 416, 434, + 470, 471, 469, 449, 469, 476, 453, 486, 644, 646, + 648, 635, 656, 639, 0, 636, 0, 0, 630, 698, + 0, 0, 536, 0, 790, 833, 702, 703, 0, 0, + 0, 0, 0, 740, 0, 0, 741, 0, 790, 0, + 768, 0, 0, 714, 734, 0, 0, 735, 736, 737, + 738, 739, 515, 518, 520, 570, 0, 0, 0, 0, + 596, 42, 0, 0, 0, 800, 801, 793, 41, 0, + 900, 901, 784, 785, 786, 0, 550, 561, 542, 0, + 798, 875, 0, 0, 867, 0, 0, 619, 883, 0, + 563, 588, 590, 0, 585, 600, 601, 603, 0, 605, + 0, 607, 608, 567, 568, 569, 0, 619, 0, 619, + 65, 619, 67, 0, 613, 74, 75, 0, 0, 81, 205, 206, 113, 272, 126, 197, 0, 194, 131, 191, 204, 204, 160, 202, 203, 161, 162, 163, 0, 179, - 0, 0, 0, 265, 86, 802, 801, 223, 223, 218, - 0, 221, 0, 913, 182, 0, 0, 0, 327, 574, + 0, 0, 0, 265, 86, 806, 805, 223, 223, 218, + 0, 221, 0, 917, 182, 0, 0, 0, 327, 574, 0, 338, 339, 0, 322, 382, 0, 215, 0, 228, - 769, 577, 0, 0, 340, 0, 323, 343, 344, 355, - 305, 306, 303, 572, 815, 816, 817, 0, 827, 94, + 773, 581, 0, 0, 340, 0, 323, 343, 344, 355, + 305, 306, 303, 572, 819, 820, 821, 0, 831, 94, 0, 0, 0, 0, 373, 0, 415, 63, 472, 472, - 633, 0, 653, 636, 695, 696, 0, 770, 794, 44, - 0, 181, 181, 749, 181, 185, 752, 181, 754, 181, - 757, 0, 0, 0, 0, 0, 0, 0, 761, 709, - 767, 0, 0, 0, 0, 0, 0, 0, 0, 201, - 834, 831, 43, 784, 0, 616, 554, 47, 51, 0, - 871, 862, 873, 875, 0, 0, 0, 867, 0, 786, - 0, 0, 578, 585, 0, 0, 579, 0, 580, 600, - 602, -2, 786, 615, 58, 59, 0, 78, 79, 80, + 637, 0, 657, 640, 699, 700, 0, 774, 798, 44, + 0, 181, 181, 753, 181, 185, 756, 181, 758, 181, + 761, 0, 0, 0, 0, 0, 0, 0, 765, 713, + 771, 0, 0, 0, 0, 0, 0, 0, 0, 201, + 838, 835, 43, 788, 0, 620, 554, 47, 51, 0, + 875, 866, 877, 879, 0, 0, 0, 871, 0, 790, + 0, 0, 582, 589, 0, 0, 583, 0, 584, 604, + 606, -2, 790, 619, 58, 59, 0, 78, 79, 80, 271, 199, 0, 196, 156, 157, 201, 0, 201, 0, - 186, 0, 254, 266, 0, 799, 800, 0, 0, 220, + 186, 0, 254, 266, 0, 803, 804, 0, 0, 220, 222, 572, 101, 0, 0, 122, 324, 0, 214, 0, - 0, 407, 404, 341, 342, 0, 0, 826, 374, 0, - 92, 93, 0, 0, 379, 413, 435, 446, 637, 697, - 829, 700, 746, 201, 750, 751, 753, 755, 756, 758, - 702, 701, 0, 0, 0, 0, 0, 794, 0, 765, - 0, 0, 0, 0, 0, 590, 201, 854, 48, 0, - 0, 0, 52, 0, 876, 0, 0, 0, 0, 69, - 794, 880, 881, 582, 0, 587, 794, 57, 207, 200, - 0, 204, 180, 204, 0, 0, 267, 803, 804, 805, - 806, 807, 808, 809, 0, 330, 575, 0, 0, 384, + 0, 407, 404, 341, 342, 0, 0, 830, 374, 0, + 92, 93, 0, 0, 379, 413, 435, 446, 641, 701, + 833, 704, 750, 201, 754, 755, 757, 759, 760, 762, + 706, 705, 0, 0, 0, 0, 0, 798, 0, 769, + 0, 0, 0, 0, 0, 594, 201, 858, 48, 0, + 0, 0, 52, 0, 880, 0, 0, 0, 0, 69, + 798, 884, 885, 586, 0, 591, 798, 57, 207, 200, + 0, 204, 180, 204, 0, 0, 267, 807, 808, 809, + 810, 811, 812, 813, 0, 330, 575, 0, 0, 384, 0, 392, 0, 0, 0, 0, 95, 96, 0, 0, - 0, 45, 747, 748, 0, 0, 0, 0, 738, 0, - 762, 0, 0, 0, 612, 0, 0, 610, 836, 835, - 848, 852, 785, 783, 0, 874, 0, 866, 869, 865, - 868, 55, 0, 56, 212, 0, 209, 211, 198, 169, - 170, 184, 187, 0, 0, 0, 408, 405, 406, 818, - 573, 0, 0, 0, 381, 703, 705, 704, 706, 0, - 0, 0, 708, 726, 727, 611, 613, 614, 571, 854, - 0, 847, 850, -2, 0, 0, 864, 0, 583, 130, - 0, 208, 210, 818, 0, 0, 371, 820, 97, 98, - 316, 317, 318, 91, 707, 0, 0, 0, 841, 839, - 839, 852, 0, 856, 0, 861, 0, 872, 870, 213, - 87, 0, 0, 0, 0, 821, 822, 94, 739, 0, - 742, 844, 0, 837, 840, 838, 849, 0, 855, 0, - 0, 853, 409, 410, 250, 0, 378, 740, 833, 0, - 842, 843, 851, 0, 0, 251, 252, 0, 819, 0, - 845, 846, 857, 859, 253, 0, 0, 0, 0, 255, - 257, 258, 0, 0, 256, 741, 259, 260, 261, + 0, 45, 751, 752, 0, 0, 0, 0, 742, 0, + 766, 0, 0, 0, 616, 576, 577, 0, 0, 614, + 840, 839, 852, 856, 789, 787, 0, 878, 0, 870, + 873, 869, 872, 55, 0, 56, 212, 0, 209, 211, + 198, 169, 170, 184, 187, 0, 0, 0, 408, 405, + 406, 822, 573, 0, 0, 0, 381, 707, 709, 708, + 710, 0, 0, 0, 712, 730, 731, 0, 615, 617, + 618, 571, 858, 0, 851, 854, -2, 0, 0, 868, + 0, 587, 130, 0, 208, 210, 822, 0, 0, 371, + 824, 97, 98, 316, 317, 318, 91, 711, 0, 0, + 0, 578, 579, 845, 843, 843, 856, 0, 860, 0, + 865, 0, 876, 874, 213, 87, 0, 0, 0, 0, + 825, 826, 94, 743, 0, 746, 848, 0, 841, 844, + 842, 853, 0, 859, 0, 0, 857, 409, 410, 250, + 0, 378, 744, 837, 0, 846, 847, 855, 0, 0, + 251, 252, 0, 823, 0, 849, 850, 861, 863, 253, + 0, 0, 0, 0, 255, 257, 258, 0, 0, 256, + 745, 259, 260, 261, } var yyTok1 = [...]int{ @@ -8474,167 +8542,191 @@ yydefault: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3021 { - yyVAL.partitions = Partitions{yyDollar[1].colIdent} + yyVAL.columns = Columns{yyDollar[1].colIdent} } case 577: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3025 { - yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) + yyVAL.columns = Columns{NewColIdent(string(yyDollar[1].bytes))} } case 578: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3029 + { + yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) + } + case 579: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3033 + { + yyVAL.columns = append(yyVAL.columns, NewColIdent(string(yyDollar[3].bytes))) + } + case 580: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3039 + { + yyVAL.partitions = Partitions{yyDollar[1].colIdent} + } + case 581: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3043 + { + yyVAL.partitions = append(yyVAL.partitions, yyDollar[3].colIdent) + } + case 582: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3038 +//line sql.y:3056 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].joinType, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 579: + case 583: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3042 +//line sql.y:3060 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].joinType, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 580: + case 584: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3046 +//line sql.y:3064 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].joinType, RightExpr: yyDollar[3].tableExpr, Condition: yyDollar[4].joinCondition} } - case 581: + case 585: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3050 +//line sql.y:3068 { yyVAL.tableExpr = &JoinTableExpr{LeftExpr: yyDollar[1].tableExpr, Join: yyDollar[2].joinType, RightExpr: yyDollar[3].tableExpr} } - case 582: + case 586: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3056 +//line sql.y:3074 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 583: + case 587: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3058 +//line sql.y:3076 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columns} } - case 584: + case 588: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3062 +//line sql.y:3080 { yyVAL.joinCondition = JoinCondition{} } - case 585: + case 589: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3064 +//line sql.y:3082 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 586: + case 590: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3068 +//line sql.y:3086 { yyVAL.joinCondition = JoinCondition{} } - case 587: + case 591: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3070 +//line sql.y:3088 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].expr} } - case 588: + case 592: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3073 +//line sql.y:3091 { yyVAL.empty = struct{}{} } - case 589: + case 593: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3075 +//line sql.y:3093 { yyVAL.empty = struct{}{} } - case 590: + case 594: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3078 +//line sql.y:3096 { yyVAL.tableIdent = NewTableIdent("") } - case 591: + case 595: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3082 +//line sql.y:3100 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 592: + case 596: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3086 +//line sql.y:3104 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 594: + case 598: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3093 +//line sql.y:3111 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 595: + case 599: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3099 +//line sql.y:3117 { yyVAL.joinType = NormalJoinType } - case 596: + case 600: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3103 +//line sql.y:3121 { yyVAL.joinType = NormalJoinType } - case 597: + case 601: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3107 +//line sql.y:3125 { yyVAL.joinType = NormalJoinType } - case 598: + case 602: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3113 +//line sql.y:3131 { yyVAL.joinType = StraightJoinType } - case 599: + case 603: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3119 +//line sql.y:3137 { yyVAL.joinType = LeftJoinType } - case 600: + case 604: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3123 +//line sql.y:3141 { yyVAL.joinType = LeftJoinType } - case 601: + case 605: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3127 +//line sql.y:3145 { yyVAL.joinType = RightJoinType } - case 602: + case 606: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3131 +//line sql.y:3149 { yyVAL.joinType = RightJoinType } - case 603: + case 607: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3137 +//line sql.y:3155 { yyVAL.joinType = NaturalJoinType } - case 604: + case 608: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3141 +//line sql.y:3159 { if yyDollar[2].joinType == LeftJoinType { yyVAL.joinType = NaturalLeftJoinType @@ -8642,489 +8734,489 @@ yydefault: yyVAL.joinType = NaturalRightJoinType } } - case 605: + case 609: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3151 +//line sql.y:3169 { yyVAL.tableName = yyDollar[2].tableName } - case 606: + case 610: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3155 +//line sql.y:3173 { yyVAL.tableName = yyDollar[1].tableName } - case 607: + case 611: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3161 +//line sql.y:3179 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 608: + case 612: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3165 +//line sql.y:3183 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } - case 609: + case 613: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3171 +//line sql.y:3189 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 610: + case 614: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3176 +//line sql.y:3194 { yyVAL.indexHints = nil } - case 611: + case 615: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3180 +//line sql.y:3198 { yyVAL.indexHints = &IndexHints{Type: UseOp, Indexes: yyDollar[4].columns} } - case 612: + case 616: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3184 +//line sql.y:3202 { yyVAL.indexHints = &IndexHints{Type: UseOp} } - case 613: + case 617: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3188 +//line sql.y:3206 { yyVAL.indexHints = &IndexHints{Type: IgnoreOp, Indexes: yyDollar[4].columns} } - case 614: + case 618: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3192 +//line sql.y:3210 { yyVAL.indexHints = &IndexHints{Type: ForceOp, Indexes: yyDollar[4].columns} } - case 615: + case 619: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3197 +//line sql.y:3215 { yyVAL.expr = nil } - case 616: + case 620: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3201 +//line sql.y:3219 { yyVAL.expr = yyDollar[2].expr } - case 617: + case 621: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3207 +//line sql.y:3225 { yyVAL.expr = yyDollar[1].expr } - case 618: + case 622: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3211 +//line sql.y:3229 { yyVAL.expr = &AndExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 619: + case 623: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3215 +//line sql.y:3233 { yyVAL.expr = &OrExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 620: + case 624: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3219 +//line sql.y:3237 { yyVAL.expr = &XorExpr{Left: yyDollar[1].expr, Right: yyDollar[3].expr} } - case 621: + case 625: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3223 +//line sql.y:3241 { yyVAL.expr = &NotExpr{Expr: yyDollar[2].expr} } - case 622: + case 626: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3227 +//line sql.y:3245 { yyVAL.expr = &IsExpr{Operator: yyDollar[3].isExprOperator, Expr: yyDollar[1].expr} } - case 623: + case 627: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3231 +//line sql.y:3249 { yyVAL.expr = yyDollar[1].expr } - case 624: + case 628: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3235 +//line sql.y:3253 { yyVAL.expr = &Default{ColName: yyDollar[2].str} } - case 625: + case 629: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3241 +//line sql.y:3259 { yyVAL.str = "" } - case 626: + case 630: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3245 +//line sql.y:3263 { yyVAL.str = string(yyDollar[2].colIdent.String()) } - case 627: + case 631: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3251 +//line sql.y:3269 { yyVAL.boolVal = BoolVal(true) } - case 628: + case 632: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3255 +//line sql.y:3273 { yyVAL.boolVal = BoolVal(false) } - case 629: + case 633: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3261 +//line sql.y:3279 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: yyDollar[2].comparisonExprOperator, Right: yyDollar[3].expr} } - case 630: + case 634: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3265 +//line sql.y:3283 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: InOp, Right: yyDollar[3].colTuple} } - case 631: + case 635: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3269 +//line sql.y:3287 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotInOp, Right: yyDollar[4].colTuple} } - case 632: + case 636: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3273 +//line sql.y:3291 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: LikeOp, Right: yyDollar[3].expr, Escape: yyDollar[4].expr} } - case 633: + case 637: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3277 +//line sql.y:3295 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotLikeOp, Right: yyDollar[4].expr, Escape: yyDollar[5].expr} } - case 634: + case 638: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3281 +//line sql.y:3299 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: RegexpOp, Right: yyDollar[3].expr} } - case 635: + case 639: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3285 +//line sql.y:3303 { yyVAL.expr = &ComparisonExpr{Left: yyDollar[1].expr, Operator: NotRegexpOp, Right: yyDollar[4].expr} } - case 636: + case 640: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3289 +//line sql.y:3307 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: BetweenOp, From: yyDollar[3].expr, To: yyDollar[5].expr} } - case 637: + case 641: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:3293 +//line sql.y:3311 { yyVAL.expr = &RangeCond{Left: yyDollar[1].expr, Operator: NotBetweenOp, From: yyDollar[4].expr, To: yyDollar[6].expr} } - case 638: + case 642: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3297 +//line sql.y:3315 { yyVAL.expr = &ExistsExpr{Subquery: yyDollar[2].subquery} } - case 639: + case 643: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3303 +//line sql.y:3321 { yyVAL.isExprOperator = IsNullOp } - case 640: + case 644: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3307 +//line sql.y:3325 { yyVAL.isExprOperator = IsNotNullOp } - case 641: + case 645: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3311 +//line sql.y:3329 { yyVAL.isExprOperator = IsTrueOp } - case 642: + case 646: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3315 +//line sql.y:3333 { yyVAL.isExprOperator = IsNotTrueOp } - case 643: + case 647: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3319 +//line sql.y:3337 { yyVAL.isExprOperator = IsFalseOp } - case 644: + case 648: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3323 +//line sql.y:3341 { yyVAL.isExprOperator = IsNotFalseOp } - case 645: + case 649: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3329 +//line sql.y:3347 { yyVAL.comparisonExprOperator = EqualOp } - case 646: + case 650: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3333 +//line sql.y:3351 { yyVAL.comparisonExprOperator = LessThanOp } - case 647: + case 651: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3337 +//line sql.y:3355 { yyVAL.comparisonExprOperator = GreaterThanOp } - case 648: + case 652: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3341 +//line sql.y:3359 { yyVAL.comparisonExprOperator = LessEqualOp } - case 649: + case 653: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3345 +//line sql.y:3363 { yyVAL.comparisonExprOperator = GreaterEqualOp } - case 650: + case 654: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3349 +//line sql.y:3367 { yyVAL.comparisonExprOperator = NotEqualOp } - case 651: + case 655: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3353 +//line sql.y:3371 { yyVAL.comparisonExprOperator = NullSafeEqualOp } - case 652: + case 656: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3358 +//line sql.y:3376 { yyVAL.expr = nil } - case 653: + case 657: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3362 +//line sql.y:3380 { yyVAL.expr = yyDollar[2].expr } - case 654: + case 658: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3368 +//line sql.y:3386 { yyVAL.colTuple = yyDollar[1].valTuple } - case 655: + case 659: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3372 +//line sql.y:3390 { yyVAL.colTuple = yyDollar[1].subquery } - case 656: + case 660: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3376 +//line sql.y:3394 { yyVAL.colTuple = ListArg(yyDollar[1].bytes) } - case 657: + case 661: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3382 +//line sql.y:3400 { yyVAL.subquery = &Subquery{yyDollar[2].selStmt} } - case 658: + case 662: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3388 +//line sql.y:3406 { yyVAL.exprs = Exprs{yyDollar[1].expr} } - case 659: + case 663: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3392 +//line sql.y:3410 { yyVAL.exprs = append(yyDollar[1].exprs, yyDollar[3].expr) } - case 660: + case 664: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3398 +//line sql.y:3416 { yyVAL.expr = yyDollar[1].expr } - case 661: + case 665: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3402 +//line sql.y:3420 { yyVAL.expr = yyDollar[1].boolVal } - case 662: + case 666: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3406 +//line sql.y:3424 { yyVAL.expr = yyDollar[1].colName } - case 663: + case 667: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3410 +//line sql.y:3428 { yyVAL.expr = yyDollar[1].expr } - case 664: + case 668: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3414 +//line sql.y:3432 { yyVAL.expr = yyDollar[1].subquery } - case 665: + case 669: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3418 +//line sql.y:3436 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitAndOp, Right: yyDollar[3].expr} } - case 666: + case 670: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3422 +//line sql.y:3440 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitOrOp, Right: yyDollar[3].expr} } - case 667: + case 671: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3426 +//line sql.y:3444 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: BitXorOp, Right: yyDollar[3].expr} } - case 668: + case 672: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3430 +//line sql.y:3448 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: PlusOp, Right: yyDollar[3].expr} } - case 669: + case 673: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3434 +//line sql.y:3452 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MinusOp, Right: yyDollar[3].expr} } - case 670: + case 674: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3438 +//line sql.y:3456 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: MultOp, Right: yyDollar[3].expr} } - case 671: + case 675: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3442 +//line sql.y:3460 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: DivOp, Right: yyDollar[3].expr} } - case 672: + case 676: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3446 +//line sql.y:3464 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: IntDivOp, Right: yyDollar[3].expr} } - case 673: + case 677: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3450 +//line sql.y:3468 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModOp, Right: yyDollar[3].expr} } - case 674: + case 678: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3454 +//line sql.y:3472 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ModOp, Right: yyDollar[3].expr} } - case 675: + case 679: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3458 +//line sql.y:3476 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftLeftOp, Right: yyDollar[3].expr} } - case 676: + case 680: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3462 +//line sql.y:3480 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].expr, Operator: ShiftRightOp, Right: yyDollar[3].expr} } - case 677: + case 681: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3466 +//line sql.y:3484 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONExtractOp, Right: yyDollar[3].expr} } - case 678: + case 682: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3470 +//line sql.y:3488 { yyVAL.expr = &BinaryExpr{Left: yyDollar[1].colName, Operator: JSONUnquoteExtractOp, Right: yyDollar[3].expr} } - case 679: + case 683: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3474 +//line sql.y:3492 { yyVAL.expr = &CollateExpr{Expr: yyDollar[1].expr, Charset: yyDollar[3].str} } - case 680: + case 684: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3478 +//line sql.y:3496 { yyVAL.expr = &UnaryExpr{Operator: BinaryOp, Expr: yyDollar[2].expr} } - case 681: + case 685: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3482 +//line sql.y:3500 { yyVAL.expr = &UnaryExpr{Operator: UBinaryOp, Expr: yyDollar[2].expr} } - case 682: + case 686: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3486 +//line sql.y:3504 { yyVAL.expr = &UnaryExpr{Operator: Utf8Op, Expr: yyDollar[2].expr} } - case 683: + case 687: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3490 +//line sql.y:3508 { yyVAL.expr = &UnaryExpr{Operator: Utf8mb4Op, Expr: yyDollar[2].expr} } - case 684: + case 688: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3494 +//line sql.y:3512 { yyVAL.expr = &UnaryExpr{Operator: Latin1Op, Expr: yyDollar[2].expr} } - case 685: + case 689: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3498 +//line sql.y:3516 { if num, ok := yyDollar[2].expr.(*Literal); ok && num.Type == IntVal { yyVAL.expr = num @@ -9132,9 +9224,9 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UPlusOp, Expr: yyDollar[2].expr} } } - case 686: + case 690: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3506 +//line sql.y:3524 { if num, ok := yyDollar[2].expr.(*Literal); ok && num.Type == IntVal { // Handle double negative @@ -9148,21 +9240,21 @@ yydefault: yyVAL.expr = &UnaryExpr{Operator: UMinusOp, Expr: yyDollar[2].expr} } } - case 687: + case 691: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3520 +//line sql.y:3538 { yyVAL.expr = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].expr} } - case 688: + case 692: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3524 +//line sql.y:3542 { yyVAL.expr = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].expr} } - case 689: + case 693: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3528 +//line sql.y:3546 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -9170,509 +9262,509 @@ yydefault: // will be non-trivial because of grammar conflicts. yyVAL.expr = &IntervalExpr{Expr: yyDollar[2].expr, Unit: yyDollar[3].colIdent.String()} } - case 694: + case 698: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3546 +//line sql.y:3564 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprs} } - case 695: + case 699: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3550 +//line sql.y:3568 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } - case 696: + case 700: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3554 +//line sql.y:3572 { yyVAL.expr = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprs} } - case 697: + case 701: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:3558 +//line sql.y:3576 { yyVAL.expr = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprs} } - case 698: + case 702: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3568 +//line sql.y:3586 { yyVAL.expr = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprs} } - case 699: + case 703: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3572 +//line sql.y:3590 { yyVAL.expr = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprs} } - case 700: + case 704: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:3576 +//line sql.y:3594 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } - case 701: + case 705: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:3580 +//line sql.y:3598 { yyVAL.expr = &ConvertExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].convertType} } - case 702: + case 706: yyDollar = yyS[yypt-6 : yypt+1] -//line sql.y:3584 +//line sql.y:3602 { yyVAL.expr = &ConvertUsingExpr{Expr: yyDollar[3].expr, Type: yyDollar[5].str} } - case 703: + case 707: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3588 +//line sql.y:3606 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 704: + case 708: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3592 +//line sql.y:3610 { yyVAL.expr = &SubstrExpr{Name: yyDollar[3].colName, From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 705: + case 709: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3596 +//line sql.y:3614 { yyVAL.expr = &SubstrExpr{StrVal: NewStrLiteral(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 706: + case 710: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3600 +//line sql.y:3618 { yyVAL.expr = &SubstrExpr{StrVal: NewStrLiteral(yyDollar[3].bytes), From: yyDollar[5].expr, To: yyDollar[7].expr} } - case 707: + case 711: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:3604 +//line sql.y:3622 { yyVAL.expr = &MatchExpr{Columns: yyDollar[3].selectExprs, Expr: yyDollar[7].expr, Option: yyDollar[8].matchExprOption} } - case 708: + case 712: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3608 +//line sql.y:3626 { yyVAL.expr = &GroupConcatExpr{Distinct: yyDollar[3].boolean, Exprs: yyDollar[4].selectExprs, OrderBy: yyDollar[5].orderBy, Separator: yyDollar[6].str, Limit: yyDollar[7].limit} } - case 709: + case 713: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3612 +//line sql.y:3630 { yyVAL.expr = &CaseExpr{Expr: yyDollar[2].expr, Whens: yyDollar[3].whens, Else: yyDollar[4].expr} } - case 710: + case 714: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3616 +//line sql.y:3634 { yyVAL.expr = &ValuesFuncExpr{Name: yyDollar[3].colName} } - case 711: + case 715: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3620 +//line sql.y:3638 { yyVAL.expr = &FuncExpr{Name: NewColIdent(string(yyDollar[1].bytes))} } - case 712: + case 716: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3630 +//line sql.y:3648 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_timestamp")} } - case 713: + case 717: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3634 +//line sql.y:3652 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_timestamp")} } - case 714: + case 718: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3638 +//line sql.y:3656 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_time")} } - case 715: + case 719: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3643 +//line sql.y:3661 { yyVAL.expr = &FuncExpr{Name: NewColIdent("utc_date")} } - case 716: + case 720: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3648 +//line sql.y:3666 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtime")} } - case 717: + case 721: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3653 +//line sql.y:3671 { yyVAL.expr = &FuncExpr{Name: NewColIdent("localtimestamp")} } - case 718: + case 722: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3659 +//line sql.y:3677 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_date")} } - case 719: + case 723: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3664 +//line sql.y:3682 { yyVAL.expr = &FuncExpr{Name: NewColIdent("current_time")} } - case 720: + case 724: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3669 +//line sql.y:3687 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].expr} } - case 721: + case 725: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3673 +//line sql.y:3691 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].expr} } - case 722: + case 726: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3677 +//line sql.y:3695 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].expr} } - case 723: + case 727: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3682 +//line sql.y:3700 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].expr} } - case 724: + case 728: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3687 +//line sql.y:3705 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].expr} } - case 725: + case 729: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3692 +//line sql.y:3710 { yyVAL.expr = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].expr} } - case 726: + case 730: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3696 +//line sql.y:3714 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 727: + case 731: yyDollar = yyS[yypt-8 : yypt+1] -//line sql.y:3700 +//line sql.y:3718 { yyVAL.expr = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].expr, Expr2: yyDollar[7].expr} } - case 730: + case 734: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3710 +//line sql.y:3728 { yyVAL.expr = yyDollar[2].expr } - case 731: + case 735: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3720 +//line sql.y:3738 { yyVAL.expr = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprs} } - case 732: + case 736: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3724 +//line sql.y:3742 { yyVAL.expr = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprs} } - case 733: + case 737: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3728 +//line sql.y:3746 { yyVAL.expr = &FuncExpr{Name: NewColIdent("schema"), Exprs: yyDollar[3].selectExprs} } - case 734: + case 738: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3732 +//line sql.y:3750 { yyVAL.expr = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprs} } - case 735: + case 739: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3736 +//line sql.y:3754 { yyVAL.expr = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprs} } - case 736: + case 740: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3740 +//line sql.y:3758 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } - case 737: + case 741: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3744 +//line sql.y:3762 { yyVAL.expr = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprs} } - case 738: + case 742: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3750 +//line sql.y:3768 { yyVAL.matchExprOption = NoOption } - case 739: + case 743: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3754 +//line sql.y:3772 { yyVAL.matchExprOption = BooleanModeOpt } - case 740: + case 744: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3758 +//line sql.y:3776 { yyVAL.matchExprOption = NaturalLanguageModeOpt } - case 741: + case 745: yyDollar = yyS[yypt-7 : yypt+1] -//line sql.y:3762 +//line sql.y:3780 { yyVAL.matchExprOption = NaturalLanguageModeWithQueryExpansionOpt } - case 742: + case 746: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3766 +//line sql.y:3784 { yyVAL.matchExprOption = QueryExpansionOpt } - case 743: + case 747: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3772 +//line sql.y:3790 { yyVAL.str = string(yyDollar[1].colIdent.String()) } - case 744: + case 748: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3776 +//line sql.y:3794 { yyVAL.str = string(yyDollar[1].bytes) } - case 745: + case 749: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3780 +//line sql.y:3798 { yyVAL.str = string(yyDollar[1].bytes) } - case 746: + case 750: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3786 +//line sql.y:3804 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } - case 747: + case 751: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3790 +//line sql.y:3808 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal, Charset: yyDollar[3].str, Operator: CharacterSetOp} } - case 748: + case 752: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3794 +//line sql.y:3812 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal, Charset: string(yyDollar[3].colIdent.String())} } - case 749: + case 753: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3798 +//line sql.y:3816 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 750: + case 754: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3802 +//line sql.y:3820 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } - case 751: + case 755: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3806 +//line sql.y:3824 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} yyVAL.convertType.Length = yyDollar[2].LengthScaleOption.Length yyVAL.convertType.Scale = yyDollar[2].LengthScaleOption.Scale } - case 752: + case 756: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3812 +//line sql.y:3830 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 753: + case 757: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3816 +//line sql.y:3834 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } - case 754: + case 758: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3820 +//line sql.y:3838 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 755: + case 759: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3824 +//line sql.y:3842 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 756: + case 760: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3828 +//line sql.y:3846 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes), Length: yyDollar[2].literal} } - case 757: + case 761: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3832 +//line sql.y:3850 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 758: + case 762: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3836 +//line sql.y:3854 { yyVAL.convertType = &ConvertType{Type: string(yyDollar[1].bytes)} } - case 759: + case 763: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3841 +//line sql.y:3859 { yyVAL.expr = nil } - case 760: + case 764: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3845 +//line sql.y:3863 { yyVAL.expr = yyDollar[1].expr } - case 761: + case 765: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3850 +//line sql.y:3868 { yyVAL.str = string("") } - case 762: + case 766: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3854 +//line sql.y:3872 { yyVAL.str = " separator '" + string(yyDollar[2].bytes) + "'" } - case 763: + case 767: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3860 +//line sql.y:3878 { yyVAL.whens = []*When{yyDollar[1].when} } - case 764: + case 768: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3864 +//line sql.y:3882 { yyVAL.whens = append(yyDollar[1].whens, yyDollar[2].when) } - case 765: + case 769: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3870 +//line sql.y:3888 { yyVAL.when = &When{Cond: yyDollar[2].expr, Val: yyDollar[4].expr} } - case 766: + case 770: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3875 +//line sql.y:3893 { yyVAL.expr = nil } - case 767: + case 771: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3879 +//line sql.y:3897 { yyVAL.expr = yyDollar[2].expr } - case 768: + case 772: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3885 +//line sql.y:3903 { yyVAL.colName = &ColName{Name: yyDollar[1].colIdent} } - case 769: + case 773: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3889 +//line sql.y:3907 { yyVAL.colName = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } - case 770: + case 774: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:3893 +//line sql.y:3911 { yyVAL.colName = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } - case 771: + case 775: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3899 +//line sql.y:3917 { yyVAL.expr = NewStrLiteral(yyDollar[1].bytes) } - case 772: + case 776: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3903 +//line sql.y:3921 { yyVAL.expr = NewHexLiteral(yyDollar[1].bytes) } - case 773: + case 777: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3907 +//line sql.y:3925 { yyVAL.expr = NewBitLiteral(yyDollar[1].bytes) } - case 774: + case 778: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3911 +//line sql.y:3929 { yyVAL.expr = NewIntLiteral(yyDollar[1].bytes) } - case 775: + case 779: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3915 +//line sql.y:3933 { yyVAL.expr = NewFloatLiteral(yyDollar[1].bytes) } - case 776: + case 780: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3919 +//line sql.y:3937 { yyVAL.expr = NewHexNumLiteral(yyDollar[1].bytes) } - case 777: + case 781: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3923 +//line sql.y:3941 { yyVAL.expr = NewArgument(yyDollar[1].bytes) } - case 778: + case 782: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3927 +//line sql.y:3945 { yyVAL.expr = &NullVal{} } - case 779: + case 783: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3933 +//line sql.y:3951 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -9681,597 +9773,597 @@ yydefault: } yyVAL.expr = NewIntLiteral([]byte("1")) } - case 780: + case 784: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3942 +//line sql.y:3960 { yyVAL.expr = NewIntLiteral(yyDollar[1].bytes) } - case 781: + case 785: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3946 +//line sql.y:3964 { yyVAL.expr = NewArgument(yyDollar[1].bytes) } - case 782: + case 786: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3951 +//line sql.y:3969 { yyVAL.exprs = nil } - case 783: + case 787: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3955 +//line sql.y:3973 { yyVAL.exprs = yyDollar[3].exprs } - case 784: + case 788: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3960 +//line sql.y:3978 { yyVAL.expr = nil } - case 785: + case 789: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3964 +//line sql.y:3982 { yyVAL.expr = yyDollar[2].expr } - case 786: + case 790: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3969 +//line sql.y:3987 { yyVAL.orderBy = nil } - case 787: + case 791: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3973 +//line sql.y:3991 { yyVAL.orderBy = yyDollar[3].orderBy } - case 788: + case 792: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3979 +//line sql.y:3997 { yyVAL.orderBy = OrderBy{yyDollar[1].order} } - case 789: + case 793: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3983 +//line sql.y:4001 { yyVAL.orderBy = append(yyDollar[1].orderBy, yyDollar[3].order) } - case 790: + case 794: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3989 +//line sql.y:4007 { yyVAL.order = &Order{Expr: yyDollar[1].expr, Direction: yyDollar[2].orderDirection} } - case 791: + case 795: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3994 +//line sql.y:4012 { yyVAL.orderDirection = AscOrder } - case 792: + case 796: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3998 +//line sql.y:4016 { yyVAL.orderDirection = AscOrder } - case 793: + case 797: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4002 +//line sql.y:4020 { yyVAL.orderDirection = DescOrder } - case 794: + case 798: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4007 +//line sql.y:4025 { yyVAL.limit = nil } - case 795: + case 799: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4011 +//line sql.y:4029 { yyVAL.limit = &Limit{Rowcount: yyDollar[2].expr} } - case 796: + case 800: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4015 +//line sql.y:4033 { yyVAL.limit = &Limit{Offset: yyDollar[2].expr, Rowcount: yyDollar[4].expr} } - case 797: + case 801: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4019 +//line sql.y:4037 { yyVAL.limit = &Limit{Offset: yyDollar[4].expr, Rowcount: yyDollar[2].expr} } - case 798: + case 802: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4024 +//line sql.y:4042 { yyVAL.indexOptions = nil } - case 799: + case 803: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4028 +//line sql.y:4046 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption, yyDollar[2].indexOption} } - case 800: + case 804: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4032 +//line sql.y:4050 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption, yyDollar[2].indexOption} } - case 801: + case 805: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4036 +//line sql.y:4054 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } - case 802: + case 806: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4040 +//line sql.y:4058 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } - case 803: + case 807: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4047 +//line sql.y:4065 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 804: + case 808: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4051 +//line sql.y:4069 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 805: + case 809: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4055 +//line sql.y:4073 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 806: + case 810: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4059 +//line sql.y:4077 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 807: + case 811: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4065 +//line sql.y:4083 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 808: + case 812: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4069 +//line sql.y:4087 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 809: + case 813: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4073 +//line sql.y:4091 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[3].bytes)} } - case 810: + case 814: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4078 +//line sql.y:4096 { yyVAL.str = "" } - case 811: + case 815: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4082 +//line sql.y:4100 { yyVAL.str = string(yyDollar[3].bytes) } - case 812: + case 816: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4086 +//line sql.y:4104 { yyVAL.str = string(yyDollar[3].bytes) } - case 813: + case 817: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4090 +//line sql.y:4108 { yyVAL.str = string(yyDollar[3].bytes) } - case 814: + case 818: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4095 +//line sql.y:4113 { yyVAL.str = "" } - case 815: + case 819: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4099 +//line sql.y:4117 { yyVAL.str = yyDollar[3].str } - case 816: + case 820: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4105 +//line sql.y:4123 { yyVAL.str = string(yyDollar[1].bytes) } - case 817: + case 821: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4109 +//line sql.y:4127 { yyVAL.str = string(yyDollar[1].bytes) } - case 818: + case 822: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4114 +//line sql.y:4132 { yyVAL.str = "" } - case 819: + case 823: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4118 +//line sql.y:4136 { yyVAL.str = yyDollar[2].str } - case 820: + case 824: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4123 +//line sql.y:4141 { yyVAL.str = "cascaded" } - case 821: + case 825: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4127 +//line sql.y:4145 { yyVAL.str = string(yyDollar[1].bytes) } - case 822: + case 826: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4131 +//line sql.y:4149 { yyVAL.str = string(yyDollar[1].bytes) } - case 823: + case 827: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4136 +//line sql.y:4154 { yyVAL.str = "" } - case 824: + case 828: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4140 +//line sql.y:4158 { yyVAL.str = yyDollar[3].str } - case 825: + case 829: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4146 +//line sql.y:4164 { yyVAL.str = string(yyDollar[1].bytes) } - case 826: + case 830: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4150 +//line sql.y:4168 { yyVAL.str = string(yyDollar[1].bytes) } - case 827: + case 831: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4154 +//line sql.y:4172 { yyVAL.str = "'" + string(yyDollar[1].bytes) + "'@" + string(yyDollar[2].bytes) } - case 828: + case 832: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4158 +//line sql.y:4176 { yyVAL.str = string(yyDollar[1].bytes) } - case 829: + case 833: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4163 +//line sql.y:4181 { yyVAL.lock = NoLock } - case 830: + case 834: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4167 +//line sql.y:4185 { yyVAL.lock = ForUpdateLock } - case 831: + case 835: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4171 +//line sql.y:4189 { yyVAL.lock = ShareModeLock } - case 832: + case 836: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4176 +//line sql.y:4194 { yyVAL.selectInto = nil } - case 833: + case 837: yyDollar = yyS[yypt-9 : yypt+1] -//line sql.y:4180 +//line sql.y:4198 { yyVAL.selectInto = &SelectInto{Type: IntoOutfileS3, FileName: string(yyDollar[4].bytes), Charset: yyDollar[5].str, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } - case 834: + case 838: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4184 +//line sql.y:4202 { yyVAL.selectInto = &SelectInto{Type: IntoDumpfile, FileName: string(yyDollar[3].bytes), Charset: "", FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } - case 835: + case 839: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4188 +//line sql.y:4206 { yyVAL.selectInto = &SelectInto{Type: IntoOutfile, FileName: string(yyDollar[3].bytes), Charset: yyDollar[4].str, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } - case 836: + case 840: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4193 +//line sql.y:4211 { yyVAL.str = "" } - case 837: + case 841: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4197 +//line sql.y:4215 { yyVAL.str = " format csv" + yyDollar[3].str } - case 838: + case 842: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4201 +//line sql.y:4219 { yyVAL.str = " format text" + yyDollar[3].str } - case 839: + case 843: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4206 +//line sql.y:4224 { yyVAL.str = "" } - case 840: + case 844: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4210 +//line sql.y:4228 { yyVAL.str = " header" } - case 841: + case 845: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4215 +//line sql.y:4233 { yyVAL.str = "" } - case 842: + case 846: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4219 +//line sql.y:4237 { yyVAL.str = " manifest on" } - case 843: + case 847: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4223 +//line sql.y:4241 { yyVAL.str = " manifest off" } - case 844: + case 848: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4228 +//line sql.y:4246 { yyVAL.str = "" } - case 845: + case 849: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4232 +//line sql.y:4250 { yyVAL.str = " overwrite on" } - case 846: + case 850: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4236 +//line sql.y:4254 { yyVAL.str = " overwrite off" } - case 847: + case 851: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4242 +//line sql.y:4260 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 848: + case 852: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4247 +//line sql.y:4265 { yyVAL.str = "" } - case 849: + case 853: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4251 +//line sql.y:4269 { yyVAL.str = " lines" + yyDollar[2].str + yyDollar[3].str } - case 850: + case 854: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4256 +//line sql.y:4274 { yyVAL.str = "" } - case 851: + case 855: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4260 +//line sql.y:4278 { yyVAL.str = " starting by '" + string(yyDollar[3].bytes) + "'" } - case 852: + case 856: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4265 +//line sql.y:4283 { yyVAL.str = "" } - case 853: + case 857: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4269 +//line sql.y:4287 { yyVAL.str = " terminated by '" + string(yyDollar[3].bytes) + "'" } - case 854: + case 858: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4274 +//line sql.y:4292 { yyVAL.str = "" } - case 855: + case 859: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4278 +//line sql.y:4296 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str + yyDollar[3].str + yyDollar[4].str } - case 856: + case 860: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4283 +//line sql.y:4301 { yyVAL.str = "" } - case 857: + case 861: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4287 +//line sql.y:4305 { yyVAL.str = " escaped by '" + string(yyDollar[3].bytes) + "'" } - case 858: + case 862: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4292 +//line sql.y:4310 { yyVAL.str = "" } - case 859: + case 863: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4296 +//line sql.y:4314 { yyVAL.str = yyDollar[1].str + " enclosed by '" + string(yyDollar[4].bytes) + "'" } - case 860: + case 864: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4301 +//line sql.y:4319 { yyVAL.str = "" } - case 861: + case 865: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4305 +//line sql.y:4323 { yyVAL.str = " optionally" } - case 862: + case 866: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4318 +//line sql.y:4336 { yyVAL.ins = &Insert{Rows: yyDollar[2].values} } - case 863: + case 867: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4322 +//line sql.y:4340 { yyVAL.ins = &Insert{Rows: yyDollar[1].selStmt} } - case 864: + case 868: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4326 +//line sql.y:4344 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[5].values} } - case 865: + case 869: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4330 +//line sql.y:4348 { yyVAL.ins = &Insert{Rows: yyDollar[4].values} } - case 866: + case 870: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4334 +//line sql.y:4352 { yyVAL.ins = &Insert{Columns: yyDollar[2].columns, Rows: yyDollar[4].selStmt} } - case 867: + case 871: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4340 +//line sql.y:4358 { yyVAL.columns = Columns{yyDollar[1].colIdent} } - case 868: + case 872: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4344 +//line sql.y:4362 { yyVAL.columns = Columns{yyDollar[3].colIdent} } - case 869: + case 873: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4348 +//line sql.y:4366 { yyVAL.columns = append(yyVAL.columns, yyDollar[3].colIdent) } - case 870: + case 874: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4352 +//line sql.y:4370 { yyVAL.columns = append(yyVAL.columns, yyDollar[5].colIdent) } - case 871: + case 875: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4357 +//line sql.y:4375 { yyVAL.updateExprs = nil } - case 872: + case 876: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4361 +//line sql.y:4379 { yyVAL.updateExprs = yyDollar[5].updateExprs } - case 873: + case 877: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4367 +//line sql.y:4385 { yyVAL.values = Values{yyDollar[1].valTuple} } - case 874: + case 878: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4371 +//line sql.y:4389 { yyVAL.values = append(yyDollar[1].values, yyDollar[3].valTuple) } - case 875: + case 879: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4377 +//line sql.y:4395 { yyVAL.valTuple = yyDollar[1].valTuple } - case 876: + case 880: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4381 +//line sql.y:4399 { yyVAL.valTuple = ValTuple{} } - case 877: + case 881: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4387 +//line sql.y:4405 { yyVAL.valTuple = ValTuple(yyDollar[2].exprs) } - case 878: + case 882: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4393 +//line sql.y:4411 { if len(yyDollar[1].valTuple) == 1 { yyVAL.expr = yyDollar[1].valTuple[0] @@ -10279,259 +10371,259 @@ yydefault: yyVAL.expr = yyDollar[1].valTuple } } - case 879: + case 883: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4403 +//line sql.y:4421 { yyVAL.updateExprs = UpdateExprs{yyDollar[1].updateExpr} } - case 880: + case 884: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4407 +//line sql.y:4425 { yyVAL.updateExprs = append(yyDollar[1].updateExprs, yyDollar[3].updateExpr) } - case 881: + case 885: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4413 +//line sql.y:4431 { yyVAL.updateExpr = &UpdateExpr{Name: yyDollar[1].colName, Expr: yyDollar[3].expr} } - case 882: + case 886: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4419 +//line sql.y:4437 { yyVAL.setExprs = SetExprs{yyDollar[1].setExpr} } - case 883: + case 887: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4423 +//line sql.y:4441 { yyVAL.setExprs = append(yyDollar[1].setExprs, yyDollar[3].setExpr) } - case 884: + case 888: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4429 +//line sql.y:4447 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral([]byte("on"))} } - case 885: + case 889: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4433 +//line sql.y:4451 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral([]byte("off"))} } - case 886: + case 890: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4437 +//line sql.y:4455 { yyVAL.setExpr = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: yyDollar[3].expr} } - case 887: + case 891: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4441 +//line sql.y:4459 { yyVAL.setExpr = &SetExpr{Name: NewColIdent(string(yyDollar[1].bytes)), Scope: ImplicitScope, Expr: yyDollar[2].expr} } - case 888: + case 892: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4445 +//line sql.y:4463 { yyDollar[2].setExpr.Scope = yyDollar[1].scope yyVAL.setExpr = yyDollar[2].setExpr } - case 890: + case 894: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4453 +//line sql.y:4471 { yyVAL.bytes = []byte("charset") } - case 893: + case 897: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4463 +//line sql.y:4481 { yyVAL.expr = NewStrLiteral([]byte(yyDollar[1].colIdent.String())) } - case 894: + case 898: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4467 +//line sql.y:4485 { yyVAL.expr = NewStrLiteral(yyDollar[1].bytes) } - case 895: + case 899: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4471 +//line sql.y:4489 { yyVAL.expr = &Default{} } - case 898: + case 902: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4480 +//line sql.y:4498 { yyVAL.boolean = false } - case 899: + case 903: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4482 +//line sql.y:4500 { yyVAL.boolean = true } - case 900: + case 904: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4485 +//line sql.y:4503 { yyVAL.boolean = false } - case 901: + case 905: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4487 +//line sql.y:4505 { yyVAL.boolean = true } - case 902: + case 906: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4490 +//line sql.y:4508 { yyVAL.ignore = false } - case 903: + case 907: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4492 +//line sql.y:4510 { yyVAL.ignore = true } - case 904: + case 908: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4495 +//line sql.y:4513 { yyVAL.empty = struct{}{} } - case 905: + case 909: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4497 +//line sql.y:4515 { yyVAL.empty = struct{}{} } - case 906: + case 910: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4499 +//line sql.y:4517 { yyVAL.empty = struct{}{} } - case 907: + case 911: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4502 +//line sql.y:4520 { yyVAL.str = "" } - case 908: + case 912: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4504 +//line sql.y:4522 { yyVAL.str = string(yyDollar[1].bytes) } - case 909: + case 913: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4506 +//line sql.y:4524 { yyVAL.str = string(yyDollar[1].bytes) } - case 910: + case 914: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4508 +//line sql.y:4526 { yyVAL.str = string(yyDollar[1].bytes) } - case 911: + case 915: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4511 +//line sql.y:4529 { yyVAL.indexOptions = nil } - case 912: + case 916: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4513 +//line sql.y:4531 { yyVAL.indexOptions = []*IndexOption{yyDollar[1].indexOption} } - case 913: + case 917: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4517 +//line sql.y:4535 { yyVAL.indexOption = &IndexOption{Name: string(yyDollar[1].bytes), String: string(yyDollar[2].colIdent.String())} } - case 914: + case 918: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4523 +//line sql.y:4541 { yyVAL.colIdent = yyDollar[1].colIdent } - case 915: + case 919: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4527 +//line sql.y:4545 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 917: + case 921: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4534 +//line sql.y:4552 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].bytes)) } - case 918: + case 922: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4540 +//line sql.y:4558 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].colIdent.String())) } - case 919: + case 923: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4544 +//line sql.y:4562 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 921: + case 925: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4551 +//line sql.y:4569 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].bytes)) } - case 1303: + case 1307: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4957 +//line sql.y:4975 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 1304: + case 1308: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4966 +//line sql.y:4984 { decNesting(yylex) } - case 1305: + case 1309: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4971 +//line sql.y:4989 { skipToEnd(yylex) } - case 1306: + case 1310: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4976 +//line sql.y:4994 { skipToEnd(yylex) } - case 1307: + case 1311: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4980 +//line sql.y:4998 { skipToEnd(yylex) } - case 1308: + case 1312: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4984 +//line sql.y:5002 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 1ceec18a43e..8aaa1351165 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -329,7 +329,7 @@ func skipToEnd(yylex interface{}) { %type header_opt export_options manifest_opt overwrite_opt format_opt optionally_opt %type fields_opt lines_opt terminated_by_opt starting_by_opt enclosed_by_opt escaped_by_opt constraint_opt %type lock_opt -%type ins_column_list column_list column_list_opt +%type ins_column_list column_list column_list_opt index_list %type opt_partition_clause partition_list %type on_dup_opt %type update_list @@ -3016,6 +3016,24 @@ column_list: $$ = append($$, $3) } +index_list: + sql_id + { + $$ = Columns{$1} + } +| PRIMARY + { + $$ = Columns{NewColIdent(string($1))} + } +| index_list ',' sql_id + { + $$ = append($$, $3) + } +| index_list ',' PRIMARY + { + $$ = append($$, NewColIdent(string($3))) + } + partition_list: sql_id { @@ -3176,7 +3194,7 @@ index_hint_list: { $$ = nil } -| USE INDEX openb column_list closeb +| USE INDEX openb index_list closeb { $$ = &IndexHints{Type: UseOp, Indexes: $4} } @@ -3184,11 +3202,11 @@ index_hint_list: { $$ = &IndexHints{Type: UseOp} } -| IGNORE INDEX openb column_list closeb +| IGNORE INDEX openb index_list closeb { $$ = &IndexHints{Type: IgnoreOp, Indexes: $4} } -| FORCE INDEX openb column_list closeb +| FORCE INDEX openb index_list closeb { $$ = &IndexHints{Type: ForceOp, Indexes: $4} } From 86281107b90cb9cf2c48536e946e749df007bd70 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 20 May 2021 16:29:15 +0530 Subject: [PATCH 166/310] added failing test Signed-off-by: GuptaManan100 --- go/vt/sqlparser/parse_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index e4862c8b666..96a23114341 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -1744,6 +1744,9 @@ var ( output: "select schema() from dual", }, { input: "select title from video as v where match(v.title, v.tag) against ('DEMO' in boolean mode)", + }, { + input: "SELECT id FROM blog_posts USE INDEX (PRIMARY) WHERE id = 10", + output: "select id from blog_posts use index (`PRIMARY`) where id = 10", }, { input: "select name, group_concat(score) from t group by name", output: "select `name`, group_concat(score) from t group by `name`", From 0a80f8e19f0cce7955f7b3766bde306e8d581414 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 20 May 2021 16:37:19 +0530 Subject: [PATCH 167/310] allow PRIMARY to be passed to index lists as well Signed-off-by: GuptaManan100 --- go/vt/sqlparser/sql.go | 6173 ++++++++++++++++++++-------------------- go/vt/sqlparser/sql.y | 26 +- 2 files changed, 3157 insertions(+), 3042 deletions(-) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index 2cce7934e64..c6b79430f96 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -988,7 +988,7 @@ var yyExca = [...]int{ 1, -1, -2, 0, -1, 44, - 164, 934, + 164, 938, -2, 91, -1, 45, 1, 112, @@ -1026,11 +1026,11 @@ var yyExca = [...]int{ 312, 118, -2, 335, -1, 579, - 150, 955, - -2, 951, + 150, 959, + -2, 955, -1, 580, - 150, 956, - -2, 952, + 150, 960, + -2, 956, -1, 599, 56, 565, -2, 577, @@ -1038,17 +1038,17 @@ var yyExca = [...]int{ 56, 566, -2, 578, -1, 621, - 118, 1299, + 118, 1303, -2, 84, -1, 622, - 118, 1181, + 118, 1185, -2, 85, -1, 628, - 118, 1231, - -2, 928, + 118, 1235, + -2, 932, -1, 766, - 118, 1118, - -2, 925, + 118, 1122, + -2, 929, -1, 799, 176, 38, 181, 38, @@ -1070,8 +1070,8 @@ var yyExca = [...]int{ 181, 39, -2, 243, -1, 1420, - 150, 960, - -2, 954, + 150, 964, + -2, 958, -1, 1512, 74, 66, 82, 66, @@ -1081,560 +1081,675 @@ var yyExca = [...]int{ 474, 270, -2, 118, -1, 1945, - 5, 821, - 18, 821, - 20, 821, - 32, 821, - 83, 821, + 5, 825, + 18, 825, + 20, 825, + 32, 825, + 83, 825, -2, 604, - -1, 2157, - 46, 896, - -2, 890, + -1, 2160, + 46, 900, + -2, 894, } const yyPrivate = 57344 -const yyLast = 28297 +const yyLast = 28950 var yyAct = [...]int{ - 579, 2242, 2186, 1858, 2231, 2170, 1997, 2208, 1746, 1548, - 2158, 522, 2086, 939, 551, 2108, 1925, 1827, 1021, 1530, - 1713, 1926, 1994, 537, 1457, 1597, 1068, 1747, 1922, 1563, - 1831, 1733, 83, 3, 520, 892, 1183, 1811, 1568, 1812, - 829, 769, 1509, 1075, 1937, 147, 1884, 1223, 1673, 180, - 1406, 1414, 180, 1810, 485, 180, 1647, 1570, 1595, 1320, - 501, 1804, 180, 1112, 794, 133, 1105, 1498, 626, 1096, - 180, 1491, 1073, 1205, 1078, 919, 601, 81, 1459, 1095, - 1098, 1060, 524, 1440, 513, 586, 1383, 957, 33, 776, - 1102, 1182, 501, 1295, 807, 501, 180, 501, 777, 1559, - 781, 773, 800, 795, 79, 623, 1212, 1474, 796, 1111, - 1514, 1085, 1325, 886, 1417, 797, 110, 1172, 937, 150, - 111, 1549, 1197, 116, 1180, 1109, 117, 508, 871, 8, - 7, 6, 78, 1177, 1034, 1850, 1849, 1626, 1282, 1872, - 2110, 1873, 1454, 1455, 1372, 1037, 182, 183, 184, 1371, - 1370, 1369, 1368, 1367, 511, 1360, 512, 2200, 1711, 770, - 592, 608, 612, 2154, 1971, 112, 2065, 958, 587, 118, - 2132, 2131, 833, 180, 2081, 460, 831, 2082, 2248, 832, - 2205, 610, 84, 2241, 834, 80, 2181, 2234, 1998, 845, - 846, 509, 849, 850, 851, 852, 1614, 1663, 855, 856, + 579, 2247, 2236, 1997, 2191, 1858, 2213, 2173, 1746, 1827, + 2161, 2110, 2086, 551, 1925, 1713, 1548, 2102, 1021, 939, + 1530, 1926, 1994, 537, 1457, 1597, 1922, 1733, 1068, 1747, + 592, 1831, 83, 3, 520, 892, 1563, 1812, 769, 1568, + 829, 147, 522, 1811, 517, 1183, 1937, 1810, 1320, 180, + 1673, 1647, 180, 1884, 485, 180, 1595, 1075, 626, 1205, + 501, 1509, 180, 1414, 1570, 133, 1112, 1804, 1105, 1406, + 180, 794, 1491, 1078, 1498, 919, 1098, 601, 1095, 1073, + 1459, 1060, 1440, 33, 513, 586, 1096, 524, 1383, 957, + 1102, 81, 501, 1182, 807, 501, 180, 501, 776, 1212, + 781, 800, 773, 797, 795, 796, 1295, 1111, 1559, 1474, + 1514, 623, 777, 1085, 79, 1325, 886, 110, 1223, 150, + 1172, 1549, 1109, 1197, 116, 937, 111, 1180, 871, 1034, + 78, 8, 508, 7, 6, 1177, 1037, 1850, 1849, 1626, + 117, 2112, 1872, 1873, 84, 1372, 182, 183, 184, 1454, + 1455, 1371, 1370, 1369, 1368, 1367, 511, 1282, 512, 1360, + 608, 612, 2205, 587, 1711, 112, 770, 2157, 1971, 2065, + 118, 2134, 2133, 180, 2081, 460, 831, 2082, 2253, 833, + 834, 86, 87, 88, 89, 90, 91, 832, 2210, 845, + 846, 2246, 849, 850, 851, 852, 509, 2184, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, - 867, 868, 869, 627, 958, 811, 2204, 620, 171, 86, - 87, 88, 89, 90, 91, 1901, 788, 2029, 786, 112, - 787, 2180, 1712, 968, 789, 1633, 810, 1951, 926, 1632, - 928, 842, 1871, 113, 177, 135, 1661, 514, 107, 1524, - 453, 454, 1184, 489, 155, 835, 836, 837, 564, 1515, - 570, 571, 568, 569, 1456, 567, 566, 565, 1777, 1952, - 1953, 1776, 847, 1573, 1778, 572, 573, 925, 927, 911, - 968, 1525, 1526, 912, 35, 145, 785, 72, 39, 40, - 134, 1113, 905, 1114, 899, 900, 935, 583, 112, 582, - 1794, 171, 182, 183, 184, 105, 488, 848, 152, 1542, - 153, 790, 956, 2020, 1860, 122, 123, 144, 143, 170, - 1361, 1362, 1363, 2018, 499, 1359, 113, 503, 964, 104, - 107, 172, 497, 585, 877, 2183, 1832, 155, 1596, 2144, - 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, - 991, 984, 897, 1572, 994, 1854, 898, 899, 900, 71, - 1306, 1304, 1305, 1855, 1301, 1629, 1296, 139, 120, 146, - 127, 119, 1272, 140, 141, 964, 872, 913, 156, 934, - 924, 2233, 2201, 923, 929, 107, 906, 99, 161, 128, - 1861, 152, 102, 153, 176, 101, 100, 916, 917, 922, - 932, 918, 170, 131, 129, 124, 125, 126, 130, 1641, - 106, 914, 915, 121, 1273, 1308, 1274, 1309, 1302, 1310, - 1862, 881, 132, 489, 1863, 1298, 854, 489, 853, 1885, - 2128, 2076, 1598, 1492, 1300, 818, 816, 827, 1970, 826, - 825, 824, 105, 823, 822, 809, 821, 820, 809, 815, - 517, 791, 180, 1191, 885, 828, 2246, 180, 175, 1515, - 180, 156, 2077, 109, 963, 960, 961, 962, 967, 969, - 966, 161, 965, 1887, 878, 1299, 488, 489, 930, 959, - 488, 1631, 2249, 1646, 774, 2220, 501, 501, 501, 803, - 774, 774, 106, 802, 148, 772, 909, 895, 1864, 901, - 902, 903, 904, 931, 501, 501, 2179, 1211, 1210, 1791, - 1786, 963, 960, 961, 962, 967, 969, 966, 887, 965, - 936, 1181, 614, 1620, 1662, 1574, 959, 2171, 819, 817, - 488, 1714, 1716, 1313, 944, 1889, 838, 1893, 950, 1888, - 1820, 1886, 1628, 809, 1910, 1909, 1891, 106, 142, 2184, - 1908, 784, 783, 1787, 782, 1890, 1649, 933, 2145, 1443, - 136, 1648, 1842, 137, 884, 1616, 780, 459, 1892, 1894, - 1284, 1283, 1285, 1286, 1287, 1789, 451, 148, 1784, 1640, - 1649, 808, 1639, 180, 808, 1648, 2165, 812, 802, 2049, - 1785, 802, 805, 806, 809, 774, 1950, 813, 1738, 799, - 803, 1681, 1004, 896, 2244, 941, 942, 2245, 809, 2243, - 1531, 501, 73, 1606, 180, 814, 180, 180, 798, 501, - 1692, 1066, 1006, 1007, 1520, 501, 1089, 908, 1715, 1019, - 1065, 1689, 623, 890, 994, 953, 951, 952, 888, 910, - 1773, 1022, 880, 595, 984, 1390, 844, 994, 1470, 894, - 1792, 1790, 809, 876, 1355, 974, 2136, 830, 1094, 1388, - 1389, 1387, 94, 1061, 149, 154, 151, 157, 158, 159, - 160, 162, 163, 164, 165, 972, 973, 971, 1079, 808, - 166, 167, 168, 169, 1935, 920, 802, 805, 806, 1615, - 774, 1326, 971, 974, 799, 803, 1297, 1580, 975, 1036, - 1039, 1041, 1043, 1044, 1046, 1048, 1049, 95, 974, 1058, - 1115, 1040, 1042, 1077, 1045, 1047, 954, 1050, 983, 982, - 992, 993, 985, 986, 987, 988, 989, 990, 991, 984, - 808, 879, 994, 873, 514, 874, 812, 802, 875, 1903, - 627, 973, 971, 1032, 808, 1441, 813, 149, 154, 151, - 157, 158, 159, 160, 162, 163, 164, 165, 974, 1006, - 1007, 1788, 893, 166, 167, 168, 169, 1613, 1611, 180, - 1006, 1007, 1067, 1173, 818, 1071, 1074, 816, 1674, 972, - 973, 971, 1955, 1185, 1186, 1187, 1608, 1905, 808, 1608, - 843, 987, 988, 989, 990, 991, 984, 974, 501, 994, - 1207, 921, 182, 183, 184, 1082, 1408, 1327, 1216, 1441, - 1612, 1699, 1220, 1610, 174, 501, 501, 2235, 501, 1291, - 501, 501, 1217, 501, 501, 501, 501, 501, 501, 2250, - 1189, 1190, 182, 183, 184, 2064, 1799, 71, 501, 1203, - 1289, 1110, 180, 1256, 613, 2236, 2063, 1251, 1252, 1386, - 985, 986, 987, 988, 989, 990, 991, 984, 1269, 1196, - 994, 1279, 1409, 1225, 1976, 1226, 1808, 1228, 1230, 501, - 2225, 1234, 1236, 1238, 1240, 1242, 1807, 180, 1290, 1253, - 1577, 1215, 1472, 1292, 1378, 1380, 1381, 180, 1259, 1260, - 1277, 180, 1800, 1276, 1265, 1266, 1379, 2251, 2226, 1288, - 1213, 1213, 1275, 1687, 1666, 1667, 1668, 180, 1179, 1267, - 1188, 1686, 779, 1214, 180, 1193, 1194, 1206, 1912, 1192, - 1278, 180, 180, 180, 180, 180, 180, 180, 180, 180, - 501, 501, 501, 618, 615, 616, 972, 973, 971, 1261, - 1258, 1330, 182, 183, 184, 1471, 1780, 2229, 1334, 1257, - 1336, 1337, 1338, 1339, 974, 1341, 1232, 180, 2032, 1322, - 1254, 182, 183, 184, 596, 1590, 1913, 2228, 2227, 1356, - 972, 973, 971, 1328, 1329, 596, 1008, 1009, 1010, 1011, - 1012, 1013, 1014, 1015, 1016, 1017, 2216, 1333, 974, 1475, - 1476, 2214, 1384, 2099, 1340, 1407, 2061, 788, 1314, 2037, - 112, 787, 1319, 1958, 1410, 983, 982, 992, 993, 985, - 986, 987, 988, 989, 990, 991, 984, 1914, 501, 994, - 1332, 983, 982, 992, 993, 985, 986, 987, 988, 989, - 990, 991, 984, 1418, 1688, 994, 182, 183, 184, 1429, - 1432, 1411, 1412, 1809, 1817, 1442, 1805, 1366, 1351, 1352, - 1353, 1657, 501, 501, 182, 183, 184, 1624, 1588, 1623, - 1385, 1323, 1280, 180, 1268, 1264, 1424, 972, 973, 971, - 1263, 972, 973, 971, 1262, 1064, 1324, 501, 1857, 1419, - 1983, 2219, 1464, 2126, 180, 974, 2125, 501, 1420, 974, - 1923, 180, 1996, 180, 1022, 80, 182, 183, 184, 1934, - 1270, 180, 180, 1418, 1983, 2177, 1448, 1449, 501, 1983, - 2166, 501, 1983, 596, 1983, 2134, 2079, 596, 972, 973, - 971, 623, 501, 1834, 623, 1421, 540, 539, 542, 543, - 544, 545, 1819, 1510, 1516, 541, 974, 546, 1425, 1426, - 1608, 596, 1431, 1434, 1435, 1550, 1551, 1552, 1734, 1489, - 2047, 596, 1373, 1374, 1375, 1376, 1485, 1516, 1420, 1983, - 1988, 1968, 1967, 1535, 1964, 1965, 1534, 1609, 1447, 1964, - 1963, 1450, 1451, 596, 1483, 596, 35, 501, 1515, 1851, - 1734, 180, 1176, 1836, 82, 501, 1538, 1829, 1830, 180, - 1587, 1589, 1513, 1495, 596, 35, 1517, 1539, 1487, 970, - 596, 1565, 1934, 501, 1519, 1176, 1175, 1427, 1428, 501, - 1121, 1120, 1571, 1216, 1518, 1216, 2044, 1495, 1522, 1517, - 1741, 1494, 1608, 1607, 2115, 1537, 1465, 1515, 970, 627, - 1536, 1767, 627, 1521, 1484, 2135, 1477, 1983, 1966, 1515, - 1495, 2066, 1523, 1742, 1594, 514, 35, 1704, 1703, 1934, - 1483, 71, 589, 501, 1483, 1407, 1608, 1591, 1473, 1452, - 1407, 1407, 1543, 1364, 1544, 1545, 1546, 1547, 1561, 1562, - 71, 1814, 1495, 1578, 1566, 1575, 580, 1583, 1584, 1585, - 1555, 1556, 1557, 1558, 1312, 1576, 1604, 1107, 1605, 2067, - 2068, 2069, 1247, 2169, 1617, 180, 811, 1529, 1600, 180, - 180, 180, 180, 180, 1483, 1619, 1213, 793, 1566, 1599, - 1621, 1622, 1618, 180, 180, 180, 180, 810, 1603, 792, - 180, 71, 71, 2088, 1995, 181, 180, 71, 181, 2055, - 1178, 181, 1564, 180, 1856, 1601, 502, 1560, 181, 2031, - 1248, 1249, 1250, 1944, 1554, 1553, 181, 1294, 1208, 1204, - 1174, 96, 177, 2070, 1938, 1939, 1567, 1859, 180, 501, - 2089, 1184, 2238, 2232, 1652, 1653, 1941, 1923, 502, 1655, - 1825, 502, 181, 502, 1813, 1824, 1656, 1244, 1823, 1581, - 1357, 1315, 1943, 1755, 1754, 1627, 983, 982, 992, 993, - 985, 986, 987, 988, 989, 990, 991, 984, 2071, 2072, - 994, 1760, 1384, 1504, 1505, 1644, 983, 982, 992, 993, - 985, 986, 987, 988, 989, 990, 991, 984, 2222, 1814, - 994, 1758, 1245, 1246, 1756, 2203, 1759, 1382, 1915, 1757, - 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, - 1401, 1402, 1403, 1404, 1405, 1723, 1076, 2188, 2048, 181, - 1986, 1732, 1660, 180, 1731, 2187, 1500, 1503, 1504, 1505, - 1501, 180, 1502, 1506, 2159, 2161, 1938, 1939, 2224, 2207, - 1385, 2209, 2191, 2162, 1669, 992, 993, 985, 986, 987, - 988, 989, 990, 991, 984, 180, 98, 994, 2156, 1444, - 1311, 581, 1720, 1818, 1437, 840, 180, 180, 180, 180, - 180, 103, 606, 602, 1727, 1721, 1748, 1682, 180, 1438, - 587, 839, 180, 1722, 1069, 180, 180, 2007, 603, 180, - 180, 180, 1739, 1698, 1743, 1813, 1070, 1736, 1870, 943, - 1678, 1679, 1779, 1061, 1710, 1844, 1843, 452, 113, 1718, - 2113, 1080, 1081, 605, 1765, 604, 1726, 1960, 1959, 173, - 1798, 1696, 455, 1602, 1795, 1796, 1222, 1768, 1735, 1221, - 1209, 1770, 1737, 2042, 1475, 1476, 1750, 1751, 1797, 1753, - 1801, 1802, 1803, 1468, 1761, 1749, 1821, 1318, 1752, 1782, - 1422, 1423, 180, 2127, 1766, 1683, 1771, 1774, 2083, 1322, - 1730, 1508, 1307, 501, 590, 591, 1665, 593, 1729, 501, - 1783, 2215, 501, 2213, 1216, 2212, 1571, 2192, 1833, 501, - 2190, 2041, 1982, 1816, 1592, 594, 1806, 82, 1918, 1837, - 1839, 1848, 2040, 1700, 606, 602, 1466, 1815, 1734, 180, - 1500, 1503, 1504, 1505, 1501, 1693, 1502, 1506, 1690, 1847, - 603, 2240, 2239, 589, 1090, 1083, 2240, 180, 2163, 1846, - 1957, 1469, 80, 1724, 1725, 1074, 85, 1196, 77, 1, - 472, 1453, 1059, 599, 600, 605, 1419, 604, 484, 2230, - 1281, 1271, 1999, 2085, 1989, 1420, 1845, 1838, 1569, 801, - 138, 1532, 501, 1533, 2173, 93, 767, 92, 1407, 804, - 907, 1593, 2080, 1793, 1541, 1881, 1127, 1125, 1126, 1866, - 1124, 1865, 1129, 1128, 1123, 1358, 498, 1507, 178, 1116, - 1883, 1084, 841, 462, 1969, 1354, 1625, 468, 501, 1874, - 1002, 1728, 1775, 624, 617, 1929, 1882, 1868, 181, 180, - 1869, 2185, 1880, 181, 2155, 1896, 181, 2157, 1895, 501, - 1902, 2109, 2160, 2153, 2223, 501, 501, 2206, 1540, 1467, - 1924, 1072, 1881, 1748, 2039, 1917, 1697, 1927, 1031, 1439, - 1099, 523, 502, 502, 502, 1911, 1463, 1377, 180, 538, - 535, 536, 1478, 1740, 976, 521, 515, 1091, 1933, 1499, - 502, 502, 982, 992, 993, 985, 986, 987, 988, 989, - 990, 991, 984, 1932, 1497, 994, 1496, 1942, 1946, 1316, - 1948, 1103, 1949, 1940, 1936, 1097, 1482, 1630, 1853, 955, - 1947, 598, 510, 97, 1436, 1961, 1962, 2026, 2143, 1977, - 1664, 180, 2028, 597, 180, 180, 180, 1954, 61, 38, - 501, 505, 2199, 946, 607, 32, 31, 30, 29, 1670, - 1671, 1672, 28, 180, 1985, 23, 22, 21, 20, 19, - 1973, 1972, 25, 18, 1974, 1975, 17, 16, 108, 181, - 2000, 501, 501, 501, 48, 180, 45, 1990, 43, 115, - 114, 1984, 46, 1571, 2008, 1987, 1993, 42, 882, 1992, - 27, 1904, 26, 15, 14, 13, 12, 502, 11, 10, - 181, 9, 181, 181, 5, 502, 4, 949, 24, 1020, - 1921, 502, 2, 0, 2005, 2006, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1919, 0, 0, 2016, - 0, 0, 0, 2038, 0, 0, 983, 982, 992, 993, - 985, 986, 987, 988, 989, 990, 991, 984, 0, 0, - 994, 0, 0, 0, 0, 0, 1748, 0, 0, 0, - 0, 0, 0, 2043, 0, 0, 0, 0, 0, 0, - 0, 0, 2052, 0, 0, 0, 0, 0, 0, 0, - 1676, 0, 0, 2060, 1677, 2062, 0, 2051, 0, 2058, - 0, 2059, 0, 501, 501, 1684, 1685, 0, 0, 0, - 2057, 1691, 0, 0, 1694, 1695, 501, 0, 0, 501, - 2074, 2073, 1701, 0, 1702, 0, 0, 1705, 1706, 1707, - 1708, 1709, 2087, 2084, 0, 2092, 0, 0, 0, 2013, - 2014, 0, 2015, 1719, 2091, 2017, 0, 2019, 0, 0, - 0, 0, 0, 0, 501, 501, 501, 180, 2090, 0, - 0, 0, 0, 2011, 0, 181, 0, 2107, 501, 0, - 501, 2102, 2104, 2105, 0, 0, 501, 0, 0, 1927, - 2112, 2106, 0, 1927, 0, 2118, 2114, 0, 0, 1763, - 1764, 0, 0, 2121, 502, 0, 0, 0, 180, 2116, - 2123, 0, 2124, 0, 0, 0, 0, 2030, 0, 501, - 180, 502, 502, 0, 502, 0, 502, 502, 0, 502, - 502, 502, 502, 502, 502, 2130, 2137, 0, 0, 0, - 514, 0, 0, 0, 502, 0, 2133, 2053, 181, 0, - 2054, 0, 0, 2056, 0, 1876, 1877, 2152, 0, 0, - 1927, 0, 2164, 0, 0, 0, 501, 501, 0, 0, - 1897, 1898, 0, 1899, 1900, 502, 0, 0, 2172, 2087, - 2174, 0, 0, 181, 1906, 1907, 0, 0, 0, 0, - 2167, 0, 0, 181, 550, 2025, 501, 181, 2189, 2182, - 501, 0, 2193, 2195, 0, 1748, 0, 0, 0, 0, - 0, 2202, 0, 181, 0, 0, 0, 2198, 2211, 2098, - 181, 0, 2210, 182, 183, 184, 0, 181, 181, 181, - 181, 181, 181, 181, 181, 181, 502, 502, 502, 2221, - 0, 0, 2120, 179, 0, 0, 458, 0, 2122, 496, - 0, 171, 2111, 514, 0, 0, 458, 0, 0, 0, - 0, 2024, 0, 181, 458, 2237, 0, 1956, 1878, 1879, - 0, 0, 2247, 0, 0, 0, 113, 0, 0, 0, - 0, 611, 611, 477, 0, 0, 0, 155, 0, 0, - 458, 0, 476, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 474, 983, 982, 992, 993, 985, 986, - 987, 988, 989, 990, 991, 984, 0, 0, 994, 0, - 0, 0, 0, 0, 502, 0, 0, 0, 1781, 0, - 0, 0, 0, 0, 1930, 0, 0, 0, 0, 0, - 0, 152, 471, 153, 0, 2023, 0, 0, 0, 0, - 0, 483, 170, 0, 0, 1945, 2009, 0, 502, 502, - 0, 0, 0, 0, 0, 0, 0, 458, 0, 181, - 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, - 991, 984, 0, 502, 994, 0, 0, 0, 0, 0, - 181, 0, 0, 502, 0, 0, 0, 181, 489, 181, - 0, 0, 0, 0, 0, 0, 0, 181, 181, 0, - 0, 156, 0, 0, 502, 0, 0, 502, 0, 0, - 0, 161, 0, 0, 0, 461, 463, 464, 502, 480, - 482, 490, 0, 0, 0, 478, 479, 491, 465, 466, - 495, 494, 481, 0, 470, 467, 469, 475, 0, 0, - 0, 488, 473, 492, 983, 982, 992, 993, 985, 986, + 867, 868, 869, 627, 620, 811, 958, 1184, 80, 2239, + 1998, 1614, 2209, 2183, 810, 1663, 1901, 788, 2029, 112, + 786, 1633, 1712, 177, 789, 1632, 787, 1951, 1573, 1952, + 1953, 842, 958, 835, 836, 837, 1525, 1526, 785, 1871, + 2146, 983, 982, 992, 993, 985, 986, 987, 988, 989, + 990, 991, 984, 1661, 107, 994, 453, 454, 1113, 848, + 1114, 1456, 847, 1524, 171, 926, 564, 928, 570, 571, + 568, 569, 968, 567, 566, 565, 912, 1515, 489, 790, + 899, 900, 35, 572, 573, 72, 39, 40, 112, 113, + 1777, 905, 911, 1776, 583, 582, 1778, 1794, 968, 935, + 155, 1542, 171, 1860, 925, 927, 2188, 2020, 1572, 107, + 172, 105, 2018, 1826, 1361, 1362, 1363, 499, 1359, 503, + 104, 182, 183, 184, 877, 497, 585, 113, 897, 135, + 1443, 488, 898, 899, 900, 1306, 1304, 1305, 155, 1832, + 1854, 1781, 1596, 1629, 1301, 1308, 1272, 1309, 1855, 1310, + 1296, 956, 918, 2238, 152, 872, 153, 71, 916, 917, + 914, 915, 932, 881, 1863, 170, 1641, 964, 854, 145, + 913, 1300, 853, 176, 134, 489, 107, 2206, 99, 1861, + 1862, 1298, 934, 102, 2130, 906, 101, 100, 1273, 2076, + 1274, 818, 152, 964, 153, 489, 1598, 1492, 1302, 1199, + 1200, 144, 143, 170, 816, 827, 1417, 924, 826, 825, + 923, 929, 1299, 824, 595, 823, 106, 822, 821, 820, + 815, 791, 1191, 828, 156, 1515, 922, 2077, 488, 109, + 774, 2254, 1970, 105, 161, 803, 774, 175, 2225, 1646, + 772, 909, 180, 774, 885, 1211, 1210, 180, 488, 802, + 180, 139, 1201, 146, 614, 1198, 887, 140, 141, 2147, + 1714, 1716, 156, 1181, 878, 1910, 1864, 1631, 930, 1620, + 1313, 106, 161, 944, 838, 1820, 501, 501, 501, 1885, + 1574, 809, 1628, 1909, 819, 809, 1908, 895, 2182, 901, + 902, 903, 904, 931, 501, 501, 489, 817, 784, 783, + 1773, 782, 1842, 963, 960, 961, 962, 967, 969, 966, + 936, 965, 809, 884, 780, 459, 451, 2251, 959, 2168, + 2189, 1640, 1649, 1887, 1639, 2049, 1616, 1648, 950, 963, + 960, 961, 962, 967, 969, 966, 1649, 965, 106, 844, + 148, 1648, 1662, 1950, 959, 809, 1738, 933, 1681, 488, + 2174, 1006, 1007, 1606, 1520, 1089, 1019, 1715, 876, 890, + 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, + 1531, 984, 908, 180, 994, 994, 1470, 1355, 148, 1284, + 1283, 1285, 1286, 1287, 910, 1889, 920, 1893, 974, 1888, + 888, 1886, 1791, 1786, 896, 809, 1891, 1004, 2138, 830, + 1935, 501, 941, 942, 180, 1890, 180, 180, 880, 501, + 73, 1066, 182, 183, 184, 501, 1408, 808, 1892, 1894, + 1326, 808, 1692, 812, 802, 1297, 1022, 953, 623, 951, + 952, 894, 142, 813, 1065, 809, 1787, 1115, 873, 954, + 874, 1689, 879, 875, 136, 973, 971, 137, 808, 1061, + 1615, 814, 94, 1903, 1441, 802, 805, 806, 1789, 774, + 1580, 1784, 974, 799, 803, 2249, 1613, 1094, 2250, 1079, + 2248, 1611, 1409, 1785, 818, 182, 183, 184, 971, 1799, + 1472, 808, 798, 843, 1036, 1039, 1041, 1043, 1044, 1046, + 1048, 1049, 1040, 1042, 974, 1045, 1047, 95, 1050, 816, + 1475, 1476, 921, 1441, 1058, 1699, 1082, 1390, 1608, 2240, + 149, 154, 151, 157, 158, 159, 160, 162, 163, 164, + 165, 1388, 1389, 1387, 1067, 1955, 166, 167, 168, 169, + 627, 808, 1612, 1792, 1790, 1800, 1327, 2241, 802, 805, + 806, 2255, 774, 1471, 893, 2234, 799, 803, 149, 154, + 151, 157, 158, 159, 160, 162, 163, 164, 165, 180, + 174, 1006, 1007, 1173, 166, 167, 168, 169, 972, 973, + 971, 808, 2064, 1185, 1186, 1187, 2230, 812, 802, 1608, + 1006, 1007, 972, 973, 971, 71, 974, 813, 501, 2063, + 1207, 987, 988, 989, 990, 991, 984, 1386, 1216, 994, + 974, 1110, 1220, 1610, 2231, 501, 501, 1976, 501, 2256, + 501, 501, 1912, 501, 501, 501, 501, 501, 501, 1687, + 1189, 1190, 1378, 1380, 1381, 1808, 1203, 1686, 501, 1666, + 1667, 1668, 180, 1256, 1379, 985, 986, 987, 988, 989, + 990, 991, 984, 1217, 1788, 994, 1291, 1809, 1269, 1196, + 1289, 1807, 972, 973, 971, 1577, 2026, 1215, 779, 501, + 1913, 613, 972, 973, 971, 1292, 1253, 180, 1251, 1252, + 974, 972, 973, 971, 972, 973, 971, 180, 1259, 1260, + 974, 180, 1905, 1277, 1265, 1266, 1276, 1279, 610, 974, + 1213, 1213, 974, 618, 1275, 1267, 1214, 180, 1179, 1261, + 1258, 1257, 1232, 1188, 180, 1290, 1193, 1194, 1857, 1288, + 1206, 180, 180, 180, 180, 180, 180, 180, 180, 180, + 501, 501, 501, 1192, 1225, 2233, 1226, 2232, 1228, 1230, + 2221, 1330, 1234, 1236, 1238, 1240, 1242, 2219, 1334, 1322, + 1336, 1337, 1338, 1339, 2099, 1341, 1278, 180, 2061, 1688, + 1254, 615, 616, 2037, 514, 1958, 182, 183, 184, 1356, + 1780, 1914, 1817, 1328, 1329, 983, 982, 992, 993, 985, + 986, 987, 988, 989, 990, 991, 984, 1333, 1805, 994, + 1657, 1384, 1624, 1623, 1340, 1407, 1323, 1280, 788, 1268, + 112, 1314, 1264, 1263, 1410, 1319, 1262, 787, 540, 539, + 542, 543, 544, 545, 1064, 1077, 596, 541, 501, 546, + 2128, 1382, 2127, 1332, 1391, 1392, 1393, 1394, 1395, 1396, + 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1418, + 35, 1411, 1412, 972, 973, 971, 1996, 1366, 182, 183, + 184, 1834, 501, 501, 1819, 1351, 1352, 1353, 182, 183, + 184, 974, 1590, 180, 80, 1385, 1983, 2224, 1419, 1539, + 1429, 1432, 1983, 2180, 1983, 2169, 1442, 501, 1420, 1934, + 1424, 82, 1464, 1444, 180, 2151, 596, 501, 2117, 1022, + 1734, 180, 1734, 180, 1983, 2136, 1465, 2079, 596, 1608, + 596, 180, 180, 182, 183, 184, 1477, 1588, 501, 1418, + 1484, 501, 182, 183, 184, 71, 1270, 1516, 1448, 1449, + 2047, 596, 501, 1983, 1988, 1968, 1967, 623, 1964, 1965, + 623, 1964, 1963, 1510, 1516, 1421, 1483, 596, 1489, 1515, + 1851, 2172, 596, 1176, 1836, 1829, 1830, 1483, 1420, 1495, + 596, 1494, 1550, 1551, 1552, 970, 596, 1485, 35, 1495, + 1535, 1934, 1534, 1609, 983, 982, 992, 993, 985, 986, + 987, 988, 989, 990, 991, 984, 1767, 501, 994, 1517, + 1483, 180, 2044, 1741, 1515, 501, 2066, 1519, 35, 180, + 1587, 1589, 1513, 1538, 1176, 1175, 1517, 1121, 1120, 970, + 1487, 1923, 1495, 501, 1515, 2137, 1742, 1983, 1565, 501, + 1934, 1966, 1495, 1216, 1518, 1216, 1522, 1523, 1608, 1704, + 1703, 1571, 589, 1607, 1674, 1483, 1537, 1536, 1608, 627, + 1521, 1591, 627, 71, 2067, 2068, 2069, 1473, 1814, 1452, + 1364, 1594, 992, 993, 985, 986, 987, 988, 989, 990, + 991, 984, 1312, 501, 994, 1407, 1107, 793, 792, 71, + 1407, 1407, 2088, 71, 1543, 1995, 1544, 1545, 1546, 1547, + 2055, 1178, 1604, 1247, 1605, 1566, 580, 1561, 1562, 1583, + 1584, 1585, 1555, 1556, 1557, 1558, 1578, 1576, 1564, 1575, + 1856, 1617, 1601, 1560, 1554, 180, 811, 71, 2070, 180, + 180, 180, 180, 180, 1553, 810, 1213, 1600, 1599, 1566, + 1618, 1603, 1294, 180, 180, 180, 180, 1208, 1204, 1174, + 180, 1248, 1249, 1250, 1619, 181, 180, 96, 181, 1621, + 1622, 181, 1813, 180, 1244, 177, 502, 1859, 181, 2089, + 596, 1184, 2243, 2071, 2072, 2237, 181, 982, 992, 993, + 985, 986, 987, 988, 989, 990, 991, 984, 180, 501, + 994, 1422, 1423, 1941, 1652, 1653, 1938, 1939, 502, 1655, + 2032, 502, 181, 502, 1923, 1825, 1656, 1814, 1824, 1245, + 1246, 1823, 1581, 1357, 1315, 1627, 983, 982, 992, 993, + 985, 986, 987, 988, 989, 990, 991, 984, 1758, 1756, + 994, 1384, 1944, 1759, 1757, 1644, 1760, 1466, 1504, 1505, + 1943, 1755, 1754, 2227, 2208, 975, 1915, 983, 982, 992, + 993, 985, 986, 987, 988, 989, 990, 991, 984, 1723, + 1076, 994, 2048, 1670, 1671, 1672, 1986, 1732, 2162, 2164, + 1425, 1426, 1731, 2229, 1431, 1434, 1435, 2165, 2193, 181, + 98, 514, 2212, 180, 1660, 1683, 2192, 2214, 2196, 1721, + 1032, 180, 1500, 1503, 1504, 1505, 1501, 1722, 1502, 1506, + 1447, 2159, 1311, 1450, 1451, 1385, 1669, 1500, 1503, 1504, + 1505, 1501, 103, 1502, 1506, 180, 581, 1938, 1939, 1818, + 840, 839, 1071, 1074, 1720, 1437, 180, 180, 180, 180, + 180, 452, 1069, 2007, 1813, 587, 1727, 1682, 180, 1870, + 1438, 943, 180, 1844, 1070, 180, 180, 1843, 1739, 180, + 180, 180, 1698, 113, 1743, 2115, 1960, 606, 602, 1061, + 173, 1959, 1779, 455, 1710, 1468, 1602, 1748, 1222, 1221, + 1209, 1718, 2042, 603, 1765, 1821, 1736, 1475, 1476, 1318, + 1798, 2129, 2083, 1726, 1508, 590, 591, 1735, 1307, 1665, + 593, 1795, 1796, 1737, 2220, 2218, 1080, 1081, 605, 1797, + 604, 1801, 1802, 1803, 1749, 1782, 1768, 1752, 2217, 1322, + 1770, 1761, 180, 1750, 1751, 1766, 1753, 1730, 1771, 2197, + 1774, 2195, 82, 501, 2041, 1729, 1982, 1592, 594, 501, + 2040, 1918, 501, 1734, 1216, 2245, 2244, 1783, 1693, 501, + 80, 1837, 1690, 1816, 1090, 1571, 1083, 2245, 2166, 606, + 602, 1848, 1806, 1957, 1469, 589, 1839, 85, 77, 180, + 1, 472, 1453, 1059, 1815, 603, 484, 2235, 1281, 1833, + 1847, 1271, 1999, 2085, 1989, 1569, 801, 180, 138, 1532, + 1846, 1533, 2176, 93, 767, 1419, 92, 1196, 599, 600, + 605, 804, 604, 1838, 907, 1420, 1593, 2080, 1793, 1541, + 1127, 1125, 1126, 1124, 1845, 1129, 1128, 1123, 1358, 498, + 1507, 178, 501, 1116, 1084, 841, 462, 1969, 1407, 1354, + 1625, 468, 1002, 1866, 1728, 1775, 1865, 624, 617, 1929, + 2190, 1881, 2158, 2160, 2111, 2163, 2156, 2228, 2211, 1540, + 1467, 1072, 1883, 2039, 1917, 1697, 1031, 1439, 501, 1876, + 1877, 1874, 1099, 523, 1463, 1377, 538, 1868, 181, 180, + 1869, 535, 536, 181, 1897, 1898, 181, 1899, 1900, 501, + 1882, 1478, 1896, 1740, 1880, 501, 501, 976, 1906, 1907, + 1924, 1676, 521, 515, 1902, 1677, 1927, 1895, 1881, 1091, + 1499, 1497, 502, 502, 502, 1496, 1684, 1685, 180, 1316, + 1921, 1103, 1691, 1940, 1933, 1694, 1695, 1936, 1097, 1482, + 502, 502, 1630, 1701, 1748, 1702, 1853, 955, 1705, 1706, + 1707, 1708, 1709, 1324, 1946, 598, 1948, 510, 1949, 1942, + 97, 1436, 2145, 1664, 1719, 2028, 597, 61, 38, 505, + 2204, 946, 607, 32, 31, 30, 1961, 1962, 29, 1977, + 28, 180, 23, 1954, 180, 180, 180, 22, 21, 1947, + 501, 1956, 1678, 1679, 20, 19, 1911, 25, 18, 17, + 16, 108, 48, 180, 45, 43, 115, 114, 46, 1972, + 1763, 1764, 42, 1696, 1974, 1975, 1973, 882, 27, 181, + 2000, 501, 501, 501, 1932, 180, 26, 1990, 1984, 1373, + 1374, 1375, 1376, 15, 2008, 1985, 1987, 1993, 14, 1992, + 13, 12, 1571, 11, 10, 9, 5, 502, 4, 949, + 181, 550, 181, 181, 24, 502, 1020, 2, 0, 0, + 0, 502, 0, 0, 2005, 2006, 0, 0, 0, 0, + 0, 0, 0, 2011, 0, 0, 0, 0, 0, 0, + 2009, 0, 0, 0, 1427, 1428, 2016, 0, 0, 0, + 2038, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 179, 0, 0, 458, 0, 0, 496, 0, 0, 0, + 0, 2043, 0, 458, 0, 0, 0, 0, 0, 0, + 0, 458, 514, 0, 2052, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2058, 0, 1748, 611, 611, + 2060, 2059, 2062, 501, 501, 0, 0, 458, 0, 0, + 0, 2051, 2074, 0, 0, 0, 501, 0, 0, 501, + 0, 2073, 0, 0, 2057, 2084, 0, 0, 0, 0, + 0, 0, 0, 0, 1529, 2092, 0, 0, 2087, 1878, + 1879, 2013, 2014, 0, 2015, 0, 0, 2017, 0, 2019, + 0, 2091, 0, 0, 501, 501, 501, 180, 0, 0, + 2090, 0, 0, 0, 0, 181, 0, 0, 501, 0, + 501, 0, 2106, 2107, 2109, 0, 501, 0, 1927, 2098, + 2114, 2108, 1927, 2120, 458, 2123, 2116, 0, 2093, 2094, + 2095, 2096, 2097, 1567, 502, 0, 2100, 2101, 180, 2118, + 0, 2125, 2122, 2126, 0, 1930, 0, 0, 2124, 501, + 180, 502, 502, 0, 502, 0, 502, 502, 2139, 502, + 502, 502, 502, 502, 502, 2132, 1945, 0, 0, 0, + 0, 0, 0, 0, 502, 0, 2135, 0, 181, 0, + 0, 0, 0, 0, 2155, 0, 0, 0, 0, 0, + 0, 1927, 2167, 0, 0, 0, 0, 0, 501, 501, + 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, + 2175, 0, 501, 181, 0, 0, 0, 2087, 2177, 0, + 0, 0, 2170, 181, 0, 2025, 0, 181, 2187, 501, + 0, 2194, 0, 501, 0, 2198, 0, 0, 2200, 0, + 0, 0, 2203, 181, 0, 0, 2207, 0, 0, 0, + 181, 0, 0, 0, 0, 2216, 2215, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 502, 502, 502, 1748, + 2031, 2226, 0, 0, 0, 171, 2201, 0, 0, 0, + 0, 2010, 0, 0, 0, 2012, 0, 0, 0, 0, + 0, 0, 0, 181, 0, 0, 2021, 2022, 2242, 0, + 113, 0, 0, 0, 0, 0, 0, 2252, 0, 0, + 0, 155, 2036, 0, 0, 0, 0, 983, 982, 992, + 993, 985, 986, 987, 988, 989, 990, 991, 984, 2045, + 2046, 994, 0, 2050, 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, 991, 984, 0, 0, 994, 0, - 2010, 0, 0, 0, 2012, 0, 0, 0, 0, 0, - 0, 0, 0, 502, 0, 2021, 2022, 181, 0, 0, - 0, 502, 0, 0, 0, 181, 0, 0, 0, 0, - 0, 2036, 0, 0, 2093, 2094, 2095, 2096, 2097, 502, - 0, 0, 2100, 2101, 0, 502, 0, 0, 2045, 2046, - 0, 978, 2050, 981, 0, 0, 0, 148, 0, 995, + 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 152, 0, 153, 0, 0, + 0, 0, 0, 0, 0, 0, 170, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 502, 502, + 2078, 0, 0, 0, 0, 0, 0, 0, 0, 181, + 1700, 0, 0, 458, 0, 0, 0, 0, 458, 0, + 0, 458, 0, 502, 0, 0, 0, 0, 0, 0, + 181, 0, 0, 502, 0, 0, 0, 181, 0, 181, + 1724, 1725, 1074, 0, 2103, 156, 0, 181, 181, 0, + 0, 0, 0, 0, 502, 161, 0, 502, 0, 0, + 0, 978, 0, 981, 0, 0, 0, 0, 502, 995, 996, 997, 998, 999, 1000, 1001, 0, 979, 980, 977, 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, - 991, 984, 0, 549, 994, 0, 0, 0, 0, 502, - 1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 493, 0, 2078, + 991, 984, 0, 0, 994, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2141, 2142, 2143, 2144, 2024, 2148, + 0, 2149, 2150, 2152, 0, 0, 0, 2153, 2154, 0, + 0, 0, 0, 502, 0, 0, 0, 181, 0, 0, + 0, 502, 0, 0, 0, 181, 0, 0, 0, 0, + 0, 0, 0, 0, 458, 0, 0, 0, 0, 502, + 0, 0, 0, 0, 0, 502, 2181, 0, 0, 1875, + 611, 148, 552, 34, 0, 0, 0, 0, 0, 0, + 0, 2023, 0, 0, 0, 458, 0, 458, 1106, 983, + 982, 992, 993, 985, 986, 987, 988, 989, 990, 991, + 984, 0, 0, 994, 0, 0, 0, 34, 0, 502, 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, - 991, 984, 0, 0, 994, 486, 0, 0, 0, 0, - 0, 181, 0, 0, 0, 181, 181, 181, 181, 181, - 487, 0, 0, 500, 0, 0, 0, 0, 0, 181, - 181, 181, 181, 2103, 1144, 0, 181, 0, 0, 0, - 0, 0, 181, 0, 0, 0, 0, 0, 0, 181, - 0, 0, 0, 0, 0, 625, 458, 1675, 771, 2196, - 778, 458, 0, 0, 458, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 181, 502, 0, 983, 982, 992, + 991, 984, 2222, 2223, 994, 0, 0, 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, 991, 984, 0, - 0, 994, 0, 2139, 2140, 2141, 2142, 0, 2146, 0, - 2147, 2148, 2149, 0, 2150, 2151, 0, 149, 154, 151, - 157, 158, 159, 160, 162, 163, 164, 165, 0, 0, - 0, 0, 0, 166, 167, 168, 169, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2178, 0, 0, 0, 1132, 0, 0, - 0, 0, 0, 0, 35, 36, 37, 72, 39, 40, + 0, 994, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 181, 588, 0, 0, 181, 181, 181, 181, 181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, - 0, 0, 0, 0, 76, 0, 0, 181, 0, 41, - 67, 68, 0, 65, 69, 0, 0, 458, 0, 0, - 66, 1145, 0, 0, 0, 0, 2217, 2218, 0, 0, - 0, 181, 0, 611, 0, 0, 0, 0, 0, 0, - 0, 0, 181, 181, 181, 181, 181, 0, 458, 54, - 458, 1106, 0, 0, 181, 0, 0, 0, 181, 71, - 0, 181, 181, 0, 0, 181, 181, 181, 0, 0, - 0, 0, 1158, 1161, 1162, 1163, 1164, 1165, 1166, 0, - 1167, 1168, 1169, 1170, 1171, 1146, 1147, 1148, 1149, 1130, - 1131, 1159, 0, 1133, 0, 1134, 1135, 1136, 1137, 1138, - 1139, 1140, 1141, 1142, 1143, 1150, 1151, 1152, 1153, 1154, - 1155, 1156, 1157, 0, 0, 0, 0, 0, 0, 0, + 181, 181, 181, 0, 0, 0, 181, 0, 1904, 0, + 0, 0, 181, 0, 0, 0, 0, 0, 0, 181, + 983, 982, 992, 993, 985, 986, 987, 988, 989, 990, + 991, 984, 0, 0, 994, 1675, 0, 0, 0, 0, + 0, 0, 0, 1919, 181, 502, 0, 0, 0, 0, + 0, 0, 0, 549, 0, 983, 982, 992, 993, 985, + 986, 987, 988, 989, 990, 991, 984, 0, 0, 994, + 458, 149, 154, 151, 157, 158, 159, 160, 162, 163, + 164, 165, 0, 0, 0, 0, 0, 166, 167, 168, + 169, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1219, 500, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1219, 1219, 181, + 0, 0, 0, 458, 0, 625, 0, 181, 771, 0, + 778, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 181, 0, 0, 0, 0, 0, 0, 458, 0, + 0, 0, 181, 181, 181, 181, 181, 0, 458, 0, + 0, 0, 1321, 0, 181, 0, 0, 0, 181, 0, + 0, 181, 181, 0, 0, 181, 181, 181, 458, 0, + 0, 0, 0, 0, 2030, 458, 0, 0, 0, 0, + 0, 0, 1342, 1343, 458, 458, 458, 458, 458, 458, + 458, 0, 0, 0, 0, 0, 0, 514, 0, 0, + 0, 0, 0, 0, 2053, 0, 0, 2054, 0, 0, + 2056, 0, 0, 0, 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 0, - 0, 44, 47, 50, 49, 52, 0, 64, 0, 502, - 70, 0, 0, 0, 0, 502, 0, 0, 502, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 502, + 0, 0, 0, 0, 0, 502, 0, 0, 502, 0, 0, 0, 0, 0, 0, 502, 0, 0, 0, 0, - 0, 0, 0, 53, 75, 74, 0, 0, 62, 63, - 51, 0, 0, 0, 0, 181, 0, 0, 1160, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 181, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 458, 0, 0, 0, 0, 0, 55, - 56, 0, 57, 58, 59, 60, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 502, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1219, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 502, 0, 0, 0, 0, 0, - 1219, 1219, 0, 0, 0, 181, 458, 0, 0, 625, - 625, 625, 0, 0, 0, 502, 0, 0, 0, 0, - 0, 502, 502, 0, 0, 0, 0, 945, 947, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 458, 73, 0, 181, 0, 0, 0, 0, 0, - 0, 458, 0, 0, 0, 1321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 458, 0, 0, 0, 0, 0, 0, 458, 0, - 0, 0, 0, 0, 0, 1342, 1343, 458, 458, 458, - 458, 458, 458, 458, 0, 0, 0, 181, 0, 0, - 181, 181, 181, 0, 0, 0, 502, 0, 0, 0, + 0, 0, 0, 0, 0, 181, 0, 0, 0, 0, + 611, 1321, 0, 0, 0, 611, 611, 0, 0, 611, + 611, 611, 0, 181, 0, 1219, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, + 514, 0, 0, 0, 0, 611, 611, 611, 611, 611, + 0, 0, 0, 0, 1461, 0, 0, 0, 502, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 458, 0, 0, 938, 938, + 938, 1321, 458, 0, 458, 0, 0, 0, 0, 0, + 0, 0, 458, 458, 502, 0, 0, 0, 34, 0, + 0, 0, 0, 0, 0, 181, 0, 0, 0, 0, + 0, 1003, 1005, 0, 0, 502, 0, 0, 0, 0, + 0, 502, 502, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1018, 0, 181, 0, 1023, 1024, 1025, 1026, + 1027, 1028, 1029, 1030, 0, 1033, 1035, 1038, 1038, 1038, + 1035, 1038, 1038, 1035, 1038, 1051, 1052, 1053, 1054, 1055, + 1056, 1057, 458, 0, 0, 0, 0, 1063, 0, 0, + 1586, 34, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 181, 0, 0, + 181, 181, 181, 0, 0, 0, 502, 0, 1100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, - 0, 458, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1062, 1087, 0, 0, 502, 502, 502, - 0, 181, 625, 0, 0, 0, 0, 0, 1117, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 625, + 625, 625, 0, 0, 0, 0, 0, 502, 502, 502, + 0, 181, 0, 0, 0, 0, 0, 945, 947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 611, 1321, 457, 0, 0, 611, 611, - 0, 0, 611, 611, 611, 504, 0, 0, 1219, 0, - 0, 0, 0, 584, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 611, 611, - 611, 611, 611, 0, 0, 0, 0, 1461, 0, 775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 458, 552, - 34, 0, 0, 0, 1321, 458, 0, 458, 0, 502, - 502, 0, 0, 0, 0, 458, 458, 0, 0, 0, + 0, 0, 0, 0, 0, 1062, 458, 0, 0, 0, + 458, 458, 458, 458, 458, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 458, 458, 458, 458, 0, 0, + 0, 1650, 0, 0, 0, 0, 0, 458, 0, 0, + 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 457, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 504, 0, 458, + 0, 0, 0, 0, 1087, 584, 0, 0, 0, 502, + 502, 0, 625, 0, 0, 0, 0, 0, 1117, 0, 0, 0, 502, 0, 0, 502, 0, 0, 0, 0, - 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, + 0, 775, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 870, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 611, 611, 0, 502, 502, 502, 181, 0, 0, 0, 0, 0, 0, - 0, 771, 0, 0, 502, 0, 502, 0, 0, 588, - 0, 0, 502, 0, 1218, 0, 0, 0, 1224, 1224, - 0, 1224, 0, 1224, 1224, 458, 1233, 1224, 1224, 1224, - 1224, 1224, 0, 1586, 181, 0, 0, 0, 0, 1218, - 1218, 771, 0, 0, 0, 502, 181, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 502, 0, 502, 0, 611, 0, + 0, 0, 502, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, + 0, 0, 1461, 0, 181, 0, 0, 0, 870, 0, + 0, 0, 0, 0, 0, 502, 181, 0, 0, 0, + 0, 0, 0, 0, 0, 611, 458, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1219, 458, 458, 458, + 458, 458, 0, 0, 0, 0, 0, 0, 0, 1762, + 0, 0, 0, 458, 0, 0, 458, 458, 0, 0, + 458, 1772, 1321, 0, 502, 502, 0, 0, 0, 0, + 0, 0, 938, 938, 938, 0, 0, 0, 502, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 771, 0, 0, 0, 502, 0, 0, 0, 502, + 0, 0, 0, 0, 1218, 0, 0, 0, 1224, 1224, + 0, 1224, 0, 1224, 1224, 0, 1233, 1224, 1224, 1224, + 1224, 1224, 0, 458, 0, 0, 0, 0, 0, 1218, + 1218, 771, 0, 0, 0, 0, 0, 0, 1219, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1321, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1293, 0, 0, 0, 0, 0, 0, 0, + 458, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 502, 502, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 502, 0, 0, 0, 502, 0, 0, 0, - 0, 0, 0, 625, 625, 625, 0, 0, 0, 458, - 0, 0, 0, 458, 458, 458, 458, 458, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 458, 458, 458, - 458, 0, 0, 0, 1650, 0, 0, 0, 0, 0, - 458, 0, 0, 0, 0, 0, 0, 458, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 458, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1413, 0, 625, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1218, 0, 0, + 0, 0, 611, 625, 625, 625, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 171, 0, + 0, 0, 0, 1511, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 113, 0, 135, 0, 0, 0, 0, + 458, 0, 0, 0, 155, 0, 0, 0, 0, 0, + 0, 0, 0, 1219, 0, 0, 0, 883, 0, 0, + 0, 0, 889, 0, 0, 891, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 145, 0, 0, 0, 458, + 134, 1413, 0, 625, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1218, 152, 0, + 153, 0, 0, 0, 0, 122, 123, 144, 143, 170, 0, 0, 0, 0, 0, 1445, 1446, 0, 0, 0, - 611, 611, 0, 0, 0, 883, 0, 0, 0, 0, - 889, 0, 0, 891, 0, 0, 0, 0, 0, 0, - 1479, 611, 0, 0, 0, 0, 0, 0, 0, 0, - 1087, 0, 0, 625, 0, 0, 0, 458, 0, 0, - 0, 0, 0, 0, 0, 1461, 0, 0, 0, 0, - 0, 625, 0, 0, 625, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 771, 0, 0, 611, 458, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1219, - 458, 458, 458, 458, 458, 0, 0, 0, 0, 0, - 0, 0, 1762, 0, 0, 0, 458, 0, 0, 458, - 458, 0, 0, 458, 1772, 1321, 0, 0, 0, 0, - 0, 171, 0, 0, 0, 0, 0, 0, 0, 0, - 778, 0, 1826, 0, 0, 0, 0, 0, 1582, 0, - 0, 0, 0, 0, 0, 0, 113, 0, 135, 0, - 0, 0, 0, 0, 0, 0, 771, 155, 0, 0, - 0, 0, 778, 0, 0, 938, 938, 938, 0, 0, - 0, 0, 0, 0, 0, 0, 458, 1093, 0, 0, - 1104, 0, 0, 0, 0, 34, 0, 0, 145, 0, - 0, 1219, 0, 134, 0, 0, 0, 0, 1003, 1005, - 0, 1321, 0, 0, 0, 0, 771, 0, 0, 0, - 0, 152, 0, 153, 0, 0, 0, 0, 1199, 1200, - 144, 143, 170, 458, 0, 0, 0, 0, 0, 1018, - 0, 0, 0, 1023, 1024, 1025, 1026, 1027, 1028, 1029, - 1030, 458, 1033, 1035, 1038, 1038, 1038, 1035, 1038, 1038, - 1035, 1038, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 0, - 0, 0, 0, 0, 1063, 0, 0, 0, 34, 0, - 139, 1201, 146, 171, 1198, 611, 140, 141, 0, 0, - 0, 156, 0, 0, 1195, 0, 0, 0, 0, 0, - 0, 161, 0, 0, 0, 1100, 0, 0, 113, 0, - 135, 0, 0, 0, 0, 0, 0, 0, 0, 155, - 0, 0, 1659, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 458, 0, 0, 0, 0, 0, 0, - 0, 0, 1122, 0, 0, 0, 1219, 0, 0, 0, - 145, 0, 0, 0, 0, 134, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 458, 152, 0, 153, 0, 0, 0, 0, - 1199, 1200, 144, 143, 170, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 148, 0, 0, - 0, 0, 0, 0, 0, 1255, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 458, 0, 0, 458, 458, - 458, 0, 139, 1201, 146, 0, 1198, 1219, 140, 141, - 0, 0, 0, 156, 0, 0, 0, 458, 0, 0, - 1303, 0, 0, 161, 0, 0, 0, 0, 1218, 0, - 1317, 142, 0, 0, 0, 0, 0, 0, 0, 458, - 0, 0, 0, 136, 0, 0, 137, 0, 0, 0, - 1331, 0, 0, 0, 0, 0, 0, 1335, 0, 0, - 0, 0, 0, 0, 0, 0, 1344, 1345, 1346, 1347, - 1348, 1349, 1350, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1104, 0, 0, 0, 0, 0, 0, 0, 0, 1219, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1828, 0, 0, 148, - 1218, 0, 1835, 0, 0, 1828, 0, 0, 0, 0, - 625, 0, 1840, 0, 0, 0, 0, 149, 154, 151, - 157, 158, 159, 160, 162, 163, 164, 165, 0, 0, - 0, 0, 0, 166, 167, 168, 169, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 142, 0, 0, 0, 0, 0, 938, - 938, 938, 0, 0, 0, 136, 0, 0, 137, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1461, 0, 0, 0, 625, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1486, 0, 0, - 0, 0, 0, 0, 1490, 0, 1493, 0, 0, 0, - 0, 0, 0, 0, 0, 1512, 0, 0, 0, 0, - 0, 1224, 458, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 458, 0, 0, 0, 0, 0, - 0, 0, 625, 0, 0, 1218, 0, 0, 1931, 1224, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 149, - 154, 151, 157, 158, 159, 160, 162, 163, 164, 165, - 0, 0, 0, 0, 0, 166, 167, 168, 169, 0, - 0, 0, 0, 0, 1579, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1219, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1511, 0, 0, 771, 0, 0, 1218, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2001, 2002, 2003, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1104, 0, - 0, 0, 1634, 1635, 1636, 1637, 1638, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1642, 1643, 1104, 1645, - 0, 0, 0, 0, 0, 0, 0, 0, 1218, 1651, - 0, 0, 0, 0, 0, 0, 1654, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 458, 0, 0, 458, 458, 458, 0, 0, + 1479, 0, 0, 0, 1219, 0, 0, 0, 0, 0, + 1087, 0, 0, 625, 458, 0, 0, 139, 120, 146, + 127, 119, 0, 140, 141, 0, 0, 0, 156, 0, + 0, 625, 0, 0, 625, 0, 458, 0, 161, 128, + 0, 0, 0, 0, 0, 771, 0, 0, 0, 0, + 0, 0, 0, 131, 129, 124, 125, 126, 130, 0, + 0, 0, 0, 121, 0, 0, 0, 0, 0, 0, + 0, 0, 132, 0, 0, 0, 0, 0, 0, 1093, + 0, 0, 1104, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 778, 0, 0, 0, 0, 0, 1219, 0, 1582, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 171, 771, 0, 0, 0, + 0, 0, 778, 0, 0, 0, 1195, 0, 0, 0, + 0, 0, 0, 0, 148, 0, 0, 0, 0, 0, + 113, 0, 135, 0, 0, 0, 0, 0, 0, 0, + 0, 155, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 771, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1680, 145, 0, 588, 0, 0, 134, 142, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1461, 0, + 136, 0, 0, 137, 0, 152, 0, 153, 0, 0, + 0, 0, 1199, 1200, 144, 143, 170, 0, 182, 183, + 184, 1717, 0, 0, 1122, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 458, + 0, 0, 0, 0, 0, 0, 0, 1100, 0, 0, + 0, 458, 0, 0, 1744, 1745, 0, 0, 1100, 1100, + 1100, 1100, 1100, 0, 139, 1201, 146, 0, 1198, 0, + 140, 141, 1659, 0, 1511, 156, 0, 1100, 477, 0, + 0, 1100, 0, 0, 0, 161, 0, 476, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1255, 474, 0, + 0, 0, 0, 0, 149, 154, 151, 157, 158, 159, + 160, 162, 163, 164, 165, 0, 0, 0, 0, 0, + 166, 167, 168, 169, 0, 0, 0, 0, 1219, 0, + 0, 0, 1303, 0, 0, 0, 0, 471, 0, 0, + 0, 0, 1317, 0, 0, 0, 483, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1331, 0, 0, 0, 0, 0, 0, 1335, + 0, 0, 1841, 0, 0, 0, 0, 0, 1344, 1345, + 1346, 1347, 1348, 1349, 1350, 0, 0, 0, 0, 0, + 0, 148, 0, 489, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1218, 0, + 0, 0, 1104, 0, 0, 0, 0, 0, 0, 0, + 461, 463, 464, 0, 480, 482, 490, 0, 0, 0, + 478, 479, 491, 465, 466, 495, 494, 481, 0, 470, + 467, 469, 475, 0, 0, 142, 488, 473, 492, 0, + 0, 0, 0, 0, 0, 0, 0, 136, 0, 0, + 137, 0, 0, 0, 0, 0, 0, 0, 1144, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1928, 1828, 34, 0, 0, + 1218, 0, 1835, 0, 0, 1828, 0, 0, 0, 0, + 625, 0, 1840, 0, 0, 0, 0, 0, 0, 0, + 1100, 0, 0, 0, 0, 0, 0, 0, 0, 1486, + 0, 0, 0, 0, 0, 0, 1490, 0, 1493, 0, + 0, 0, 0, 0, 0, 0, 0, 1512, 0, 0, + 0, 149, 154, 151, 157, 158, 159, 160, 162, 163, + 164, 165, 493, 0, 0, 0, 0, 166, 167, 168, + 169, 1132, 0, 0, 0, 0, 0, 0, 0, 0, + 486, 0, 0, 0, 0, 625, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 487, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1145, 0, 0, 0, 0, + 0, 1224, 0, 0, 0, 0, 1579, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1658, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1828, 2075, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1828, + 0, 0, 625, 0, 0, 1218, 0, 0, 1931, 1224, + 0, 0, 0, 0, 2027, 0, 0, 0, 0, 0, + 0, 2033, 2034, 2035, 0, 0, 1158, 1161, 1162, 1163, + 1164, 1165, 1166, 0, 1167, 1168, 1169, 1170, 1171, 1146, + 1147, 1148, 1149, 1130, 1131, 1159, 0, 1133, 0, 1134, + 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1150, + 1151, 1152, 1153, 1154, 1155, 1156, 1157, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 771, 0, 0, 1218, 0, 0, 0, + 1104, 0, 0, 0, 1634, 1635, 1636, 1637, 1638, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1642, 1643, + 1104, 1645, 0, 0, 2001, 2002, 2003, 0, 0, 0, + 0, 1651, 1160, 0, 0, 0, 0, 0, 1654, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1928, 0, 34, + 0, 1928, 0, 1658, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, + 36, 37, 72, 39, 40, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 34, 0, 1218, 76, + 0, 0, 0, 0, 41, 67, 68, 0, 65, 69, + 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1928, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 34, 2171, 54, 0, 1828, 2075, 0, 0, + 0, 0, 0, 0, 71, 0, 0, 0, 0, 1828, 0, 0, 625, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1828, 1828, 1828, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2117, 0, 2119, 0, 0, 0, 0, 0, 1828, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 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, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1769, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 625, - 625, 0, 0, 0, 0, 0, 0, 0, 1680, 0, - 0, 588, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1218, 0, 2194, - 0, 0, 0, 1828, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1717, 0, - 0, 0, 0, 0, 0, 1822, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1100, 0, 0, 0, 0, 0, - 0, 1744, 1745, 0, 0, 1100, 1100, 1100, 1100, 1100, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1511, 1852, 0, 1100, 0, 0, 0, 1100, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1867, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1841, - 0, 0, 1916, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2104, 2104, 2104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2119, 0, 2121, 0, 0, 0, 0, 0, 1828, + 0, 1769, 0, 0, 0, 0, 44, 47, 50, 49, + 52, 0, 64, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1978, 0, 0, 1979, 1980, 1981, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1991, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1928, 0, 34, 0, 0, 0, 2004, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1100, 0, 0, + 0, 0, 1828, 0, 0, 0, 0, 0, 53, 75, + 74, 0, 0, 62, 63, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1822, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 625, 625, 0, 55, 56, 0, 57, 58, 59, + 60, 0, 0, 0, 0, 2185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1218, 0, 2199, 0, 1852, 0, 1828, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1867, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2027, 0, 0, 0, 0, 0, 0, 2033, 2034, - 2035, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2129, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1978, 0, 0, 1979, + 1980, 1981, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1991, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2004, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1928, 0, 34, 0, 1928, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1928, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 750, 737, 34, 2168, 686, + 0, 0, 0, 0, 0, 0, 0, 0, 750, 737, + 0, 0, 686, 753, 657, 675, 762, 677, 680, 720, + 636, 699, 327, 672, 0, 661, 632, 668, 633, 659, + 688, 237, 692, 656, 739, 702, 752, 285, 0, 638, + 662, 341, 722, 379, 223, 294, 292, 407, 247, 240, + 236, 222, 269, 300, 339, 397, 333, 759, 289, 709, + 0, 388, 312, 0, 0, 0, 690, 742, 697, 733, + 685, 721, 646, 708, 754, 673, 717, 755, 275, 221, + 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, + 0, 2178, 2179, 0, 0, 0, 0, 0, 212, 0, + 219, 714, 749, 670, 716, 233, 273, 239, 232, 404, + 719, 765, 631, 711, 0, 634, 637, 761, 745, 665, + 666, 0, 0, 0, 0, 0, 0, 0, 689, 698, + 730, 683, 0, 0, 0, 0, 0, 0, 0, 0, + 663, 0, 707, 0, 0, 0, 642, 635, 0, 0, + 0, 0, 687, 2131, 0, 0, 645, 0, 664, 731, + 0, 629, 259, 639, 313, 2140, 735, 744, 684, 435, + 748, 682, 681, 751, 726, 643, 741, 676, 284, 641, + 281, 186, 201, 0, 674, 323, 362, 368, 740, 660, + 669, 224, 667, 366, 337, 421, 208, 249, 359, 342, + 364, 706, 724, 365, 290, 409, 354, 419, 436, 437, + 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, + 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, + 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, + 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, + 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, + 432, 197, 940, 431, 319, 408, 416, 308, 299, 196, + 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, + 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, + 655, 736, 403, 441, 446, 0, 355, 211, 256, 244, + 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, + 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, + 728, 764, 336, 367, 214, 423, 387, 650, 654, 648, + 649, 700, 701, 651, 756, 757, 758, 732, 644, 0, + 652, 653, 0, 738, 746, 747, 705, 185, 198, 287, + 760, 356, 252, 448, 430, 426, 630, 647, 230, 658, + 0, 0, 671, 678, 679, 691, 693, 694, 695, 696, + 704, 712, 713, 715, 723, 725, 727, 729, 734, 743, + 763, 187, 188, 199, 207, 217, 229, 242, 250, 260, + 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, + 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, + 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, + 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, + 391, 395, 410, 411, 422, 434, 438, 261, 418, 439, + 0, 295, 703, 710, 297, 246, 263, 272, 718, 429, + 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, + 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, + 378, 398, 399, 400, 402, 309, 234, 750, 737, 0, + 0, 686, 753, 657, 675, 762, 677, 680, 720, 636, + 699, 327, 672, 0, 661, 632, 668, 633, 659, 688, + 237, 692, 656, 739, 702, 752, 285, 0, 638, 662, + 341, 722, 379, 223, 294, 292, 407, 247, 240, 236, + 222, 269, 300, 339, 397, 333, 759, 289, 709, 0, + 388, 312, 0, 0, 0, 690, 742, 697, 733, 685, + 721, 646, 708, 754, 673, 717, 755, 275, 221, 190, + 324, 389, 251, 0, 0, 0, 182, 183, 184, 0, + 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, + 714, 749, 670, 716, 233, 273, 239, 232, 404, 719, + 765, 631, 711, 0, 634, 637, 761, 745, 665, 666, + 0, 0, 0, 0, 0, 0, 0, 689, 698, 730, + 683, 0, 0, 0, 0, 0, 0, 1920, 0, 663, + 0, 707, 0, 0, 0, 642, 635, 0, 0, 0, + 0, 687, 0, 0, 0, 645, 0, 664, 731, 0, + 629, 259, 639, 313, 0, 735, 744, 684, 435, 748, + 682, 681, 751, 726, 643, 741, 676, 284, 641, 281, + 186, 201, 0, 674, 323, 362, 368, 740, 660, 669, + 224, 667, 366, 337, 421, 208, 249, 359, 342, 364, + 706, 724, 365, 290, 409, 354, 419, 436, 437, 231, + 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, + 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, + 200, 374, 216, 193, 396, 417, 213, 377, 0, 0, + 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, + 235, 255, 226, 326, 412, 413, 225, 449, 204, 432, + 197, 940, 431, 319, 408, 416, 308, 299, 196, 414, + 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, + 314, 316, 0, 191, 0, 390, 425, 450, 210, 655, + 736, 403, 441, 446, 0, 355, 211, 256, 244, 351, + 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, + 420, 248, 428, 318, 205, 268, 386, 282, 291, 728, + 764, 336, 367, 214, 423, 387, 650, 654, 648, 649, + 700, 701, 651, 756, 757, 758, 732, 644, 0, 652, + 653, 0, 738, 746, 747, 705, 185, 198, 287, 760, + 356, 252, 448, 430, 426, 630, 647, 230, 658, 0, + 0, 671, 678, 679, 691, 693, 694, 695, 696, 704, + 712, 713, 715, 723, 725, 727, 729, 734, 743, 763, + 187, 188, 199, 207, 217, 229, 242, 250, 260, 264, + 267, 270, 271, 274, 279, 296, 301, 302, 303, 304, + 320, 321, 322, 325, 328, 329, 332, 334, 335, 338, + 344, 345, 346, 347, 348, 350, 357, 361, 369, 370, + 371, 372, 373, 375, 376, 380, 381, 382, 383, 391, + 395, 410, 411, 422, 434, 438, 261, 418, 439, 0, + 295, 703, 710, 297, 246, 263, 272, 718, 429, 392, + 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, + 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, + 398, 399, 400, 402, 309, 234, 750, 737, 0, 0, + 686, 753, 657, 675, 762, 677, 680, 720, 636, 699, + 327, 672, 0, 661, 632, 668, 633, 659, 688, 237, + 692, 656, 739, 702, 752, 285, 0, 638, 662, 341, + 722, 379, 223, 294, 292, 407, 247, 240, 236, 222, + 269, 300, 339, 397, 333, 759, 289, 709, 0, 388, + 312, 0, 0, 0, 690, 742, 697, 733, 685, 721, + 646, 708, 754, 673, 717, 755, 275, 221, 190, 324, + 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, + 0, 0, 0, 0, 0, 0, 212, 0, 219, 714, + 749, 670, 716, 233, 273, 239, 232, 404, 719, 765, + 631, 711, 0, 634, 637, 761, 745, 665, 666, 0, + 0, 0, 0, 0, 0, 0, 689, 698, 730, 683, + 0, 0, 0, 0, 0, 0, 1773, 0, 663, 0, + 707, 0, 0, 0, 642, 635, 0, 0, 0, 0, + 687, 0, 0, 0, 645, 0, 664, 731, 0, 629, + 259, 639, 313, 0, 735, 744, 684, 435, 748, 682, + 681, 751, 726, 643, 741, 676, 284, 641, 281, 186, + 201, 0, 674, 323, 362, 368, 740, 660, 669, 224, + 667, 366, 337, 421, 208, 249, 359, 342, 364, 706, + 724, 365, 290, 409, 354, 419, 436, 437, 231, 317, + 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, + 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, + 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, + 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, + 255, 226, 326, 412, 413, 225, 449, 204, 432, 197, + 940, 431, 319, 408, 416, 308, 299, 196, 414, 306, + 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, + 316, 0, 191, 0, 390, 425, 450, 210, 655, 736, + 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, + 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, + 248, 428, 318, 205, 268, 386, 282, 291, 728, 764, + 336, 367, 214, 423, 387, 650, 654, 648, 649, 700, + 701, 651, 756, 757, 758, 732, 644, 0, 652, 653, + 0, 738, 746, 747, 705, 185, 198, 287, 760, 356, + 252, 448, 430, 426, 630, 647, 230, 658, 0, 0, + 671, 678, 679, 691, 693, 694, 695, 696, 704, 712, + 713, 715, 723, 725, 727, 729, 734, 743, 763, 187, + 188, 199, 207, 217, 229, 242, 250, 260, 264, 267, + 270, 271, 274, 279, 296, 301, 302, 303, 304, 320, + 321, 322, 325, 328, 329, 332, 334, 335, 338, 344, + 345, 346, 347, 348, 350, 357, 361, 369, 370, 371, + 372, 373, 375, 376, 380, 381, 382, 383, 391, 395, + 410, 411, 422, 434, 438, 261, 418, 439, 0, 295, + 703, 710, 297, 246, 263, 272, 718, 429, 392, 203, + 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, + 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, + 399, 400, 402, 309, 234, 750, 737, 0, 0, 686, 753, 657, 675, 762, 677, 680, 720, 636, 699, 327, 672, 0, 661, 632, 668, 633, 659, 688, 237, 692, 656, 739, 702, 752, 285, 0, 638, 662, 341, 722, @@ -1642,12 +1757,12 @@ var yyAct = [...]int{ 300, 339, 397, 333, 759, 289, 709, 0, 388, 312, 0, 0, 0, 690, 742, 697, 733, 685, 721, 646, 708, 754, 673, 717, 755, 275, 221, 190, 324, 389, - 251, 0, 0, 0, 182, 183, 184, 0, 2175, 2176, + 251, 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 714, 749, 670, 716, 233, 273, 239, 232, 404, 719, 765, 631, 711, 0, 634, 637, 761, 745, 665, 666, 0, 0, 0, 0, 0, 0, 0, 689, 698, 730, 683, 0, - 0, 0, 0, 0, 0, 0, 0, 663, 0, 707, + 0, 0, 0, 0, 0, 1488, 0, 663, 0, 707, 0, 0, 0, 642, 635, 0, 0, 0, 0, 687, 0, 0, 0, 645, 0, 664, 731, 0, 629, 259, 639, 313, 0, 735, 744, 684, 435, 748, 682, 681, @@ -1689,12 +1804,12 @@ var yyAct = [...]int{ 339, 397, 333, 759, 289, 709, 0, 388, 312, 0, 0, 0, 690, 742, 697, 733, 685, 721, 646, 708, 754, 673, 717, 755, 275, 221, 190, 324, 389, 251, - 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 71, 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 714, 749, 670, 716, 233, 273, 239, 232, 404, 719, 765, 631, 711, 0, 634, 637, 761, 745, 665, 666, 0, 0, 0, 0, 0, 0, 0, 689, 698, 730, 683, 0, 0, - 0, 0, 0, 0, 1920, 0, 663, 0, 707, 0, + 0, 0, 0, 0, 0, 0, 663, 0, 707, 0, 0, 0, 642, 635, 0, 0, 0, 0, 687, 0, 0, 0, 645, 0, 664, 731, 0, 629, 259, 639, 313, 0, 735, 744, 684, 435, 748, 682, 681, 751, @@ -1741,7 +1856,7 @@ var yyAct = [...]int{ 233, 273, 239, 232, 404, 719, 765, 631, 711, 0, 634, 637, 761, 745, 665, 666, 0, 0, 0, 0, 0, 0, 0, 689, 698, 730, 683, 0, 0, 0, - 0, 0, 0, 1773, 0, 663, 0, 707, 0, 0, + 0, 0, 0, 0, 0, 663, 0, 707, 0, 0, 0, 642, 635, 0, 0, 0, 0, 687, 0, 0, 0, 645, 0, 664, 731, 0, 629, 259, 639, 313, 0, 735, 744, 684, 435, 748, 682, 681, 751, 726, @@ -1788,7 +1903,7 @@ var yyAct = [...]int{ 273, 239, 232, 404, 719, 765, 631, 711, 0, 634, 637, 761, 745, 665, 666, 0, 0, 0, 0, 0, 0, 0, 689, 698, 730, 683, 0, 0, 0, 0, - 0, 0, 1488, 0, 663, 0, 707, 0, 0, 0, + 0, 0, 0, 0, 663, 0, 707, 0, 0, 0, 642, 635, 0, 0, 0, 0, 687, 0, 0, 0, 645, 0, 664, 731, 0, 629, 259, 639, 313, 0, 735, 744, 684, 435, 748, 682, 681, 751, 726, 643, @@ -1800,13 +1915,13 @@ var yyAct = [...]int{ 384, 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, 412, - 413, 225, 449, 204, 432, 197, 940, 431, 319, 408, + 413, 225, 449, 204, 432, 197, 640, 431, 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, 655, 736, 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, - 445, 209, 349, 262, 330, 420, 248, 428, 318, 205, - 268, 386, 282, 291, 728, 764, 336, 367, 214, 423, + 445, 209, 349, 262, 330, 420, 248, 428, 628, 766, + 622, 621, 282, 291, 728, 764, 336, 367, 214, 423, 387, 650, 654, 648, 649, 700, 701, 651, 756, 757, 758, 732, 644, 0, 652, 653, 0, 738, 746, 747, 705, 185, 198, 287, 760, 356, 252, 448, 430, 426, @@ -1829,7 +1944,7 @@ var yyAct = [...]int{ 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 759, 289, 709, 0, 388, 312, 0, 0, 0, 690, 742, 697, 733, 685, 721, 646, 708, 754, 673, 717, - 755, 275, 221, 190, 324, 389, 251, 71, 0, 0, + 755, 275, 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 714, 749, 670, 716, 233, 273, 239, 232, 404, 719, 765, 631, 711, 0, 634, 637, @@ -1844,16 +1959,16 @@ var yyAct = [...]int{ 249, 359, 342, 364, 706, 724, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, - 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, + 257, 189, 288, 444, 200, 374, 216, 193, 396, 1108, 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, - 225, 449, 204, 432, 197, 940, 431, 319, 408, 416, + 225, 449, 204, 432, 197, 640, 431, 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, 655, 736, 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, - 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, - 386, 282, 291, 728, 764, 336, 367, 214, 423, 387, + 209, 349, 262, 330, 420, 248, 428, 628, 766, 622, + 621, 282, 291, 728, 764, 336, 367, 214, 423, 387, 650, 654, 648, 649, 700, 701, 651, 756, 757, 758, 732, 644, 0, 652, 653, 0, 738, 746, 747, 705, 185, 198, 287, 760, 356, 252, 448, 430, 426, 630, @@ -1891,15 +2006,15 @@ var yyAct = [...]int{ 359, 342, 364, 706, 724, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, 257, - 189, 288, 444, 200, 374, 216, 193, 396, 417, 213, + 189, 288, 444, 200, 374, 216, 193, 396, 619, 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, 225, - 449, 204, 432, 197, 940, 431, 319, 408, 416, 308, + 449, 204, 432, 197, 640, 431, 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, 655, 736, 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, 209, - 349, 262, 330, 420, 248, 428, 318, 205, 268, 386, + 349, 262, 330, 420, 248, 428, 628, 766, 622, 621, 282, 291, 728, 764, 336, 367, 214, 423, 387, 650, 654, 648, 649, 700, 701, 651, 756, 757, 758, 732, 644, 0, 652, 653, 0, 738, 746, 747, 705, 185, @@ -1915,424 +2030,9 @@ var yyAct = [...]int{ 418, 439, 0, 295, 703, 710, 297, 246, 263, 272, 718, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, - 360, 215, 378, 398, 399, 400, 402, 309, 234, 750, - 737, 0, 0, 686, 753, 657, 675, 762, 677, 680, - 720, 636, 699, 327, 672, 0, 661, 632, 668, 633, - 659, 688, 237, 692, 656, 739, 702, 752, 285, 0, - 638, 662, 341, 722, 379, 223, 294, 292, 407, 247, - 240, 236, 222, 269, 300, 339, 397, 333, 759, 289, - 709, 0, 388, 312, 0, 0, 0, 690, 742, 697, - 733, 685, 721, 646, 708, 754, 673, 717, 755, 275, - 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, - 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, - 0, 219, 714, 749, 670, 716, 233, 273, 239, 232, - 404, 719, 765, 631, 711, 0, 634, 637, 761, 745, - 665, 666, 0, 0, 0, 0, 0, 0, 0, 689, - 698, 730, 683, 0, 0, 0, 0, 0, 0, 0, - 0, 663, 0, 707, 0, 0, 0, 642, 635, 0, - 0, 0, 0, 687, 0, 0, 0, 645, 0, 664, - 731, 0, 629, 259, 639, 313, 0, 735, 744, 684, - 435, 748, 682, 681, 751, 726, 643, 741, 676, 284, - 641, 281, 186, 201, 0, 674, 323, 362, 368, 740, - 660, 669, 224, 667, 366, 337, 421, 208, 249, 359, - 342, 364, 706, 724, 365, 290, 409, 354, 419, 436, - 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, - 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, - 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, - 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, - 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, - 204, 432, 197, 640, 431, 319, 408, 416, 308, 299, - 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, - 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, - 210, 655, 736, 403, 441, 446, 0, 355, 211, 256, - 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, - 262, 330, 420, 248, 428, 628, 766, 622, 621, 282, - 291, 728, 764, 336, 367, 214, 423, 387, 650, 654, - 648, 649, 700, 701, 651, 756, 757, 758, 732, 644, - 0, 652, 653, 0, 738, 746, 747, 705, 185, 198, - 287, 760, 356, 252, 448, 430, 426, 630, 647, 230, - 658, 0, 0, 671, 678, 679, 691, 693, 694, 695, - 696, 704, 712, 713, 715, 723, 725, 727, 729, 734, - 743, 763, 187, 188, 199, 207, 217, 229, 242, 250, - 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, - 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, - 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, - 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, - 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, - 439, 0, 295, 703, 710, 297, 246, 263, 272, 718, - 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, - 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, - 215, 378, 398, 399, 400, 402, 309, 234, 750, 737, - 0, 0, 686, 753, 657, 675, 762, 677, 680, 720, - 636, 699, 327, 672, 0, 661, 632, 668, 633, 659, - 688, 237, 692, 656, 739, 702, 752, 285, 0, 638, - 662, 341, 722, 379, 223, 294, 292, 407, 247, 240, - 236, 222, 269, 300, 339, 397, 333, 759, 289, 709, - 0, 388, 312, 0, 0, 0, 690, 742, 697, 733, - 685, 721, 646, 708, 754, 673, 717, 755, 275, 221, - 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, - 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, - 219, 714, 749, 670, 716, 233, 273, 239, 232, 404, - 719, 765, 631, 711, 0, 634, 637, 761, 745, 665, - 666, 0, 0, 0, 0, 0, 0, 0, 689, 698, - 730, 683, 0, 0, 0, 0, 0, 0, 0, 0, - 663, 0, 707, 0, 0, 0, 642, 635, 0, 0, - 0, 0, 687, 0, 0, 0, 645, 0, 664, 731, - 0, 629, 259, 639, 313, 0, 735, 744, 684, 435, - 748, 682, 681, 751, 726, 643, 741, 676, 284, 641, - 281, 186, 201, 0, 674, 323, 362, 368, 740, 660, - 669, 224, 667, 366, 337, 421, 208, 249, 359, 342, - 364, 706, 724, 365, 290, 409, 354, 419, 436, 437, - 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, - 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, - 444, 200, 374, 216, 193, 396, 1108, 213, 377, 0, - 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, - 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, - 432, 197, 640, 431, 319, 408, 416, 308, 299, 196, - 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, - 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, - 655, 736, 403, 441, 446, 0, 355, 211, 256, 244, - 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, - 330, 420, 248, 428, 628, 766, 622, 621, 282, 291, - 728, 764, 336, 367, 214, 423, 387, 650, 654, 648, - 649, 700, 701, 651, 756, 757, 758, 732, 644, 0, - 652, 653, 0, 738, 746, 747, 705, 185, 198, 287, - 760, 356, 252, 448, 430, 426, 630, 647, 230, 658, - 0, 0, 671, 678, 679, 691, 693, 694, 695, 696, - 704, 712, 713, 715, 723, 725, 727, 729, 734, 743, - 763, 187, 188, 199, 207, 217, 229, 242, 250, 260, - 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, - 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, - 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, - 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, - 391, 395, 410, 411, 422, 434, 438, 261, 418, 439, - 0, 295, 703, 710, 297, 246, 263, 272, 718, 429, - 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, - 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, - 378, 398, 399, 400, 402, 309, 234, 750, 737, 0, - 0, 686, 753, 657, 675, 762, 677, 680, 720, 636, - 699, 327, 672, 0, 661, 632, 668, 633, 659, 688, - 237, 692, 656, 739, 702, 752, 285, 0, 638, 662, - 341, 722, 379, 223, 294, 292, 407, 247, 240, 236, - 222, 269, 300, 339, 397, 333, 759, 289, 709, 0, - 388, 312, 0, 0, 0, 690, 742, 697, 733, 685, - 721, 646, 708, 754, 673, 717, 755, 275, 221, 190, - 324, 389, 251, 0, 0, 0, 182, 183, 184, 0, - 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, - 714, 749, 670, 716, 233, 273, 239, 232, 404, 719, - 765, 631, 711, 0, 634, 637, 761, 745, 665, 666, - 0, 0, 0, 0, 0, 0, 0, 689, 698, 730, - 683, 0, 0, 0, 0, 0, 0, 0, 0, 663, - 0, 707, 0, 0, 0, 642, 635, 0, 0, 0, - 0, 687, 0, 0, 0, 645, 0, 664, 731, 0, - 629, 259, 639, 313, 0, 735, 744, 684, 435, 748, - 682, 681, 751, 726, 643, 741, 676, 284, 641, 281, - 186, 201, 0, 674, 323, 362, 368, 740, 660, 669, - 224, 667, 366, 337, 421, 208, 249, 359, 342, 364, - 706, 724, 365, 290, 409, 354, 419, 436, 437, 231, - 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, - 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, - 200, 374, 216, 193, 396, 619, 213, 377, 0, 0, - 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, - 235, 255, 226, 326, 412, 413, 225, 449, 204, 432, - 197, 640, 431, 319, 408, 416, 308, 299, 196, 414, - 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, - 314, 316, 0, 191, 0, 390, 425, 450, 210, 655, - 736, 403, 441, 446, 0, 355, 211, 256, 244, 351, - 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, - 420, 248, 428, 628, 766, 622, 621, 282, 291, 728, - 764, 336, 367, 214, 423, 387, 650, 654, 648, 649, - 700, 701, 651, 756, 757, 758, 732, 644, 0, 652, - 653, 0, 738, 746, 747, 705, 185, 198, 287, 760, - 356, 252, 448, 430, 426, 630, 647, 230, 658, 0, - 0, 671, 678, 679, 691, 693, 694, 695, 696, 704, - 712, 713, 715, 723, 725, 727, 729, 734, 743, 763, - 187, 188, 199, 207, 217, 229, 242, 250, 260, 264, - 267, 270, 271, 274, 279, 296, 301, 302, 303, 304, - 320, 321, 322, 325, 328, 329, 332, 334, 335, 338, - 344, 345, 346, 347, 348, 350, 357, 361, 369, 370, - 371, 372, 373, 375, 376, 380, 381, 382, 383, 391, - 395, 410, 411, 422, 434, 438, 261, 418, 439, 0, - 295, 703, 710, 297, 246, 263, 272, 718, 429, 392, - 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, - 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, - 398, 399, 400, 402, 309, 234, 327, 0, 0, 1415, - 0, 519, 0, 0, 0, 237, 0, 518, 0, 0, - 0, 285, 0, 0, 1416, 341, 0, 379, 223, 294, - 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, - 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, - 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, - 0, 0, 275, 221, 190, 324, 389, 251, 71, 0, - 0, 182, 183, 184, 540, 539, 542, 543, 544, 545, - 0, 0, 212, 541, 219, 546, 547, 548, 0, 233, - 273, 239, 232, 404, 0, 0, 0, 516, 533, 0, - 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 530, 531, 609, 0, 0, 0, 577, 0, 532, 0, - 0, 525, 526, 528, 527, 529, 534, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, - 576, 0, 0, 435, 0, 0, 574, 0, 0, 0, - 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, - 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, - 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, - 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, - 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, - 384, 257, 189, 288, 444, 200, 374, 216, 193, 396, - 417, 213, 377, 0, 0, 0, 195, 415, 393, 307, - 277, 278, 194, 0, 358, 235, 255, 226, 326, 412, - 413, 225, 449, 204, 432, 197, 0, 431, 319, 408, - 416, 308, 299, 196, 414, 306, 298, 283, 245, 265, - 352, 293, 353, 266, 315, 314, 316, 0, 191, 0, - 390, 425, 450, 210, 0, 0, 403, 441, 446, 0, - 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, - 445, 209, 349, 262, 330, 420, 248, 428, 318, 205, - 268, 386, 282, 291, 0, 0, 336, 367, 214, 423, - 387, 564, 575, 570, 571, 568, 569, 563, 567, 566, - 565, 578, 555, 556, 557, 558, 560, 0, 572, 573, - 559, 185, 198, 287, 0, 356, 252, 448, 430, 426, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 188, 199, 207, 217, - 229, 242, 250, 260, 264, 267, 270, 271, 274, 279, - 296, 301, 302, 303, 304, 320, 321, 322, 325, 328, - 329, 332, 334, 335, 338, 344, 345, 346, 347, 348, - 350, 357, 361, 369, 370, 371, 372, 373, 375, 376, - 380, 381, 382, 383, 391, 395, 410, 411, 422, 434, - 438, 261, 418, 439, 0, 295, 0, 0, 297, 246, - 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, - 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, - 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, - 234, 327, 0, 0, 0, 0, 519, 0, 0, 0, - 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, - 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, - 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, - 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, - 0, 0, 0, 0, 0, 1527, 0, 275, 221, 190, - 324, 389, 251, 71, 0, 0, 182, 183, 184, 540, - 539, 542, 543, 544, 545, 0, 0, 212, 541, 219, - 546, 547, 548, 1528, 233, 273, 239, 232, 404, 0, - 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 530, 531, 0, 0, 0, - 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, - 529, 534, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 259, 0, 313, 0, 576, 0, 0, 435, 0, - 0, 574, 0, 0, 0, 0, 0, 284, 0, 281, - 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, - 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, - 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, - 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, - 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, - 200, 374, 216, 193, 396, 417, 213, 377, 0, 0, - 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, - 235, 255, 226, 326, 412, 413, 225, 449, 204, 432, - 197, 0, 431, 319, 408, 416, 308, 299, 196, 414, - 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, - 314, 316, 0, 191, 0, 390, 425, 450, 210, 0, - 0, 403, 441, 446, 0, 355, 211, 256, 244, 351, - 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, - 420, 248, 428, 318, 205, 268, 386, 282, 291, 0, - 0, 336, 367, 214, 423, 387, 564, 575, 570, 571, - 568, 569, 563, 567, 566, 565, 578, 555, 556, 557, - 558, 560, 0, 572, 573, 559, 185, 198, 287, 0, - 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 188, 199, 207, 217, 229, 242, 250, 260, 264, - 267, 270, 271, 274, 279, 296, 301, 302, 303, 304, - 320, 321, 322, 325, 328, 329, 332, 334, 335, 338, - 344, 345, 346, 347, 348, 350, 357, 361, 369, 370, - 371, 372, 373, 375, 376, 380, 381, 382, 383, 391, - 395, 410, 411, 422, 434, 438, 261, 418, 439, 0, - 295, 0, 0, 297, 246, 263, 272, 0, 429, 392, - 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, - 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, - 398, 399, 400, 402, 309, 234, 327, 0, 0, 0, - 0, 519, 0, 0, 0, 237, 0, 518, 0, 0, - 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, - 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, - 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, - 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, - 0, 0, 275, 221, 190, 324, 389, 251, 71, 0, - 596, 182, 183, 184, 540, 539, 542, 543, 544, 545, - 0, 0, 212, 541, 219, 546, 547, 548, 0, 233, - 273, 239, 232, 404, 0, 0, 0, 516, 533, 0, - 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 530, 531, 0, 0, 0, 0, 577, 0, 532, 0, - 0, 525, 526, 528, 527, 529, 534, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, - 576, 0, 0, 435, 0, 0, 574, 0, 0, 0, - 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, - 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, - 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, - 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, - 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, - 384, 257, 189, 288, 444, 200, 374, 216, 193, 396, - 417, 213, 377, 0, 0, 0, 195, 415, 393, 307, - 277, 278, 194, 0, 358, 235, 255, 226, 326, 412, - 413, 225, 449, 204, 432, 197, 0, 431, 319, 408, - 416, 308, 299, 196, 414, 306, 298, 283, 245, 265, - 352, 293, 353, 266, 315, 314, 316, 0, 191, 0, - 390, 425, 450, 210, 0, 0, 403, 441, 446, 0, - 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, - 445, 209, 349, 262, 330, 420, 248, 428, 318, 205, - 268, 386, 282, 291, 0, 0, 336, 367, 214, 423, - 387, 564, 575, 570, 571, 568, 569, 563, 567, 566, - 565, 578, 555, 556, 557, 558, 560, 0, 572, 573, - 559, 185, 198, 287, 0, 356, 252, 448, 430, 426, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 188, 199, 207, 217, - 229, 242, 250, 260, 264, 267, 270, 271, 274, 279, - 296, 301, 302, 303, 304, 320, 321, 322, 325, 328, - 329, 332, 334, 335, 338, 344, 345, 346, 347, 348, - 350, 357, 361, 369, 370, 371, 372, 373, 375, 376, - 380, 381, 382, 383, 391, 395, 410, 411, 422, 434, - 438, 261, 418, 439, 0, 295, 0, 0, 297, 246, - 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, - 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, - 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, - 234, 327, 0, 0, 0, 0, 519, 0, 0, 0, - 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, - 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, - 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, - 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, - 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, - 324, 389, 251, 71, 0, 0, 182, 183, 184, 540, - 539, 542, 543, 544, 545, 0, 0, 212, 541, 219, - 546, 547, 548, 0, 233, 273, 239, 232, 404, 0, - 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 530, 531, 609, 0, 0, - 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, - 529, 534, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 259, 0, 313, 0, 576, 0, 0, 435, 0, - 0, 574, 0, 0, 0, 0, 0, 284, 0, 281, - 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, - 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, - 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, - 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, - 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, - 200, 374, 216, 193, 396, 417, 213, 377, 0, 0, - 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, - 235, 255, 226, 326, 412, 413, 225, 449, 204, 432, - 197, 0, 431, 319, 408, 416, 308, 299, 196, 414, - 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, - 314, 316, 0, 191, 0, 390, 425, 450, 210, 0, - 0, 403, 441, 446, 0, 355, 211, 256, 244, 351, - 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, - 420, 248, 428, 318, 205, 268, 386, 282, 291, 0, - 0, 336, 367, 214, 423, 387, 564, 575, 570, 571, - 568, 569, 563, 567, 566, 565, 578, 555, 556, 557, - 558, 560, 0, 572, 573, 559, 185, 198, 287, 0, - 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 188, 199, 207, 217, 229, 242, 250, 260, 264, - 267, 270, 271, 274, 279, 296, 301, 302, 303, 304, - 320, 321, 322, 325, 328, 329, 332, 334, 335, 338, - 344, 345, 346, 347, 348, 350, 357, 361, 369, 370, - 371, 372, 373, 375, 376, 380, 381, 382, 383, 391, - 395, 410, 411, 422, 434, 438, 261, 418, 439, 0, - 295, 0, 0, 297, 246, 263, 272, 0, 429, 392, - 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, - 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, - 398, 399, 400, 402, 309, 234, 327, 0, 0, 0, - 0, 519, 0, 0, 0, 237, 0, 518, 0, 0, - 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, - 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, - 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, - 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, - 0, 0, 275, 221, 190, 324, 389, 251, 71, 0, - 0, 182, 183, 184, 540, 1433, 542, 543, 544, 545, - 0, 0, 212, 541, 219, 546, 547, 548, 0, 233, - 273, 239, 232, 404, 0, 0, 0, 516, 533, 0, - 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 530, 531, 609, 0, 0, 0, 577, 0, 532, 0, - 0, 525, 526, 528, 527, 529, 534, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, - 576, 0, 0, 435, 0, 0, 574, 0, 0, 0, - 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, - 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, - 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, - 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, - 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, - 384, 257, 189, 288, 444, 200, 374, 216, 193, 396, - 417, 213, 377, 0, 0, 0, 195, 415, 393, 307, - 277, 278, 194, 0, 358, 235, 255, 226, 326, 412, - 413, 225, 449, 204, 432, 197, 0, 431, 319, 408, - 416, 308, 299, 196, 414, 306, 298, 283, 245, 265, - 352, 293, 353, 266, 315, 314, 316, 0, 191, 0, - 390, 425, 450, 210, 0, 0, 403, 441, 446, 0, - 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, - 445, 209, 349, 262, 330, 420, 248, 428, 318, 205, - 268, 386, 282, 291, 0, 0, 336, 367, 214, 423, - 387, 564, 575, 570, 571, 568, 569, 563, 567, 566, - 565, 578, 555, 556, 557, 558, 560, 0, 572, 573, - 559, 185, 198, 287, 0, 356, 252, 448, 430, 426, - 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 187, 188, 199, 207, 217, - 229, 242, 250, 260, 264, 267, 270, 271, 274, 279, - 296, 301, 302, 303, 304, 320, 321, 322, 325, 328, - 329, 332, 334, 335, 338, 344, 345, 346, 347, 348, - 350, 357, 361, 369, 370, 371, 372, 373, 375, 376, - 380, 381, 382, 383, 391, 395, 410, 411, 422, 434, - 438, 261, 418, 439, 0, 295, 0, 0, 297, 246, - 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, - 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, - 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, - 234, 327, 0, 0, 0, 0, 519, 0, 0, 0, - 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, - 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, - 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, - 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, - 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, - 324, 389, 251, 71, 0, 0, 182, 183, 184, 540, - 1430, 542, 543, 544, 545, 0, 0, 212, 541, 219, - 546, 547, 548, 0, 233, 273, 239, 232, 404, 0, - 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 530, 531, 609, 0, 0, - 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, - 529, 534, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 259, 0, 313, 0, 576, 0, 0, 435, 0, - 0, 574, 0, 0, 0, 0, 0, 284, 0, 281, - 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, - 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, - 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, - 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, - 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, - 200, 374, 216, 193, 396, 417, 213, 377, 0, 0, - 0, 195, 415, 393, 307, 277, 278, 194, 0, 358, - 235, 255, 226, 326, 412, 413, 225, 449, 204, 432, - 197, 0, 431, 319, 408, 416, 308, 299, 196, 414, - 306, 298, 283, 245, 265, 352, 293, 353, 266, 315, - 314, 316, 0, 191, 0, 390, 425, 450, 210, 0, - 0, 403, 441, 446, 0, 355, 211, 256, 244, 351, - 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, - 420, 248, 428, 318, 205, 268, 386, 282, 291, 0, - 0, 336, 367, 214, 423, 387, 564, 575, 570, 571, - 568, 569, 563, 567, 566, 565, 578, 555, 556, 557, - 558, 560, 0, 572, 573, 559, 185, 198, 287, 0, - 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 187, 188, 199, 207, 217, 229, 242, 250, 260, 264, - 267, 270, 271, 274, 279, 296, 301, 302, 303, 304, - 320, 321, 322, 325, 328, 329, 332, 334, 335, 338, - 344, 345, 346, 347, 348, 350, 357, 361, 369, 370, - 371, 372, 373, 375, 376, 380, 381, 382, 383, 391, - 395, 410, 411, 422, 434, 438, 261, 418, 439, 0, - 295, 0, 0, 297, 246, 263, 272, 0, 429, 392, - 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, - 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, - 398, 399, 400, 402, 309, 234, 589, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, - 0, 0, 0, 0, 519, 0, 0, 0, 237, 0, - 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, + 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, + 0, 0, 1415, 0, 519, 0, 0, 0, 237, 0, + 518, 0, 0, 0, 285, 0, 0, 1416, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, 0, 0, @@ -2342,7 +2042,7 @@ var yyAct = [...]int{ 548, 0, 233, 273, 239, 232, 404, 0, 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 530, 531, 0, 0, 0, 0, 577, + 0, 0, 0, 530, 531, 609, 0, 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, 529, 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, 576, 0, 0, 435, 0, 0, 574, @@ -2381,10 +2081,10 @@ var yyAct = [...]int{ 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, - 553, 554, 0, 0, 0, 0, 0, 0, 0, 0, + 553, 554, 0, 0, 0, 0, 0, 0, 1527, 0, 275, 221, 190, 324, 389, 251, 71, 0, 0, 182, 183, 184, 540, 539, 542, 543, 544, 545, 0, 0, - 212, 541, 219, 546, 547, 548, 0, 233, 273, 239, + 212, 541, 219, 546, 547, 548, 1528, 233, 273, 239, 232, 404, 0, 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 530, 531, @@ -2422,16 +2122,16 @@ var yyAct = [...]int{ 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, + 0, 0, 0, 0, 519, 0, 0, 0, 237, 0, + 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, 389, - 251, 71, 0, 0, 182, 183, 184, 540, 539, 542, + 251, 71, 0, 596, 182, 183, 184, 540, 539, 542, 543, 544, 545, 0, 0, 212, 541, 219, 546, 547, 548, 0, 233, 273, 239, 232, 404, 0, 0, 0, - 0, 533, 0, 561, 0, 0, 0, 0, 0, 0, + 516, 533, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 530, 531, 0, 0, 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, 529, 534, @@ -2439,7 +2139,7 @@ var yyAct = [...]int{ 0, 313, 0, 576, 0, 0, 435, 0, 0, 574, 0, 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, - 366, 337, 421, 208, 249, 359, 342, 364, 2197, 0, + 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, 374, @@ -2467,19 +2167,19 @@ var yyAct = [...]int{ 0, 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, - 400, 402, 309, 234, 327, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, + 400, 402, 309, 234, 327, 0, 0, 0, 0, 519, + 0, 0, 0, 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, 0, 0, - 275, 221, 190, 324, 389, 251, 71, 0, 596, 182, + 275, 221, 190, 324, 389, 251, 71, 0, 0, 182, 183, 184, 540, 539, 542, 543, 544, 545, 0, 0, 212, 541, 219, 546, 547, 548, 0, 233, 273, 239, - 232, 404, 0, 0, 0, 0, 533, 0, 561, 0, + 232, 404, 0, 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 530, 531, - 0, 0, 0, 0, 577, 0, 532, 0, 0, 525, + 609, 0, 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, 529, 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, 576, 0, 0, 435, 0, 0, 574, 0, 0, 0, 0, 0, @@ -2513,18 +2213,18 @@ var yyAct = [...]int{ 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, - 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, + 0, 0, 0, 0, 519, 0, 0, 0, 237, 0, + 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, 389, - 251, 71, 0, 0, 182, 183, 184, 540, 539, 542, + 251, 71, 0, 0, 182, 183, 184, 540, 1433, 542, 543, 544, 545, 0, 0, 212, 541, 219, 546, 547, 548, 0, 233, 273, 239, 232, 404, 0, 0, 0, - 0, 533, 0, 561, 0, 0, 0, 0, 0, 0, + 516, 533, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 530, 531, 0, 0, 0, 0, 577, + 0, 0, 0, 530, 531, 609, 0, 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, 527, 529, 534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, 576, 0, 0, 435, 0, 0, 574, @@ -2558,113 +2258,22 @@ var yyAct = [...]int{ 0, 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, - 400, 402, 309, 234, 327, 0, 0, 0, 0, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, - 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, - 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, - 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 275, 221, 190, 324, 389, 251, 0, 0, 0, 182, - 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, - 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, - 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 983, 982, 992, 993, 985, 986, - 987, 988, 989, 990, 991, 984, 0, 0, 994, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 259, 0, 313, 0, 0, 0, - 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, - 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, - 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, - 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, - 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, - 331, 394, 424, 385, 310, 405, 406, 280, 384, 257, - 189, 288, 444, 200, 374, 216, 193, 396, 417, 213, - 377, 0, 0, 0, 195, 415, 393, 307, 277, 278, - 194, 0, 358, 235, 255, 226, 326, 412, 413, 225, - 449, 204, 432, 197, 0, 431, 319, 408, 416, 308, - 299, 196, 414, 306, 298, 283, 245, 265, 352, 293, - 353, 266, 315, 314, 316, 0, 191, 0, 390, 425, - 450, 210, 0, 0, 403, 441, 446, 0, 355, 211, - 256, 244, 351, 254, 286, 440, 442, 443, 445, 209, - 349, 262, 330, 420, 248, 428, 318, 205, 268, 386, - 282, 291, 0, 0, 336, 367, 214, 423, 387, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, - 198, 287, 0, 356, 252, 448, 430, 426, 0, 0, - 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 187, 188, 199, 207, 217, 229, 242, - 250, 260, 264, 267, 270, 271, 274, 279, 296, 301, - 302, 303, 304, 320, 321, 322, 325, 328, 329, 332, - 334, 335, 338, 344, 345, 346, 347, 348, 350, 357, - 361, 369, 370, 371, 372, 373, 375, 376, 380, 381, - 382, 383, 391, 395, 410, 411, 422, 434, 438, 261, - 418, 439, 0, 295, 0, 0, 297, 246, 263, 272, - 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, - 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, - 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, - 0, 0, 0, 0, 0, 0, 0, 0, 237, 809, - 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, - 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, - 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 275, 221, 190, 324, 389, - 251, 0, 0, 0, 182, 183, 184, 0, 0, 0, - 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, - 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, - 0, 313, 0, 0, 0, 808, 435, 0, 0, 0, - 0, 0, 0, 805, 806, 284, 774, 281, 186, 201, - 799, 803, 323, 362, 368, 0, 0, 0, 224, 0, - 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, - 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, - 401, 433, 447, 202, 228, 331, 394, 424, 385, 310, - 405, 406, 280, 384, 257, 189, 288, 444, 200, 374, - 216, 193, 396, 417, 213, 377, 0, 0, 0, 195, - 415, 393, 307, 277, 278, 194, 0, 358, 235, 255, - 226, 326, 412, 413, 225, 449, 204, 432, 197, 0, - 431, 319, 408, 416, 308, 299, 196, 414, 306, 298, - 283, 245, 265, 352, 293, 353, 266, 315, 314, 316, - 0, 191, 0, 390, 425, 450, 210, 0, 0, 403, - 441, 446, 0, 355, 211, 256, 244, 351, 254, 286, - 440, 442, 443, 445, 209, 349, 262, 330, 420, 248, - 428, 318, 205, 268, 386, 282, 291, 0, 0, 336, - 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 185, 198, 287, 0, 356, 252, - 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 187, 188, - 199, 207, 217, 229, 242, 250, 260, 264, 267, 270, - 271, 274, 279, 296, 301, 302, 303, 304, 320, 321, - 322, 325, 328, 329, 332, 334, 335, 338, 344, 345, - 346, 347, 348, 350, 357, 361, 369, 370, 371, 372, - 373, 375, 376, 380, 381, 382, 383, 391, 395, 410, - 411, 422, 434, 438, 261, 418, 439, 0, 295, 0, - 0, 297, 246, 263, 272, 0, 429, 392, 203, 363, - 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, - 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, - 400, 402, 309, 234, 327, 0, 0, 0, 1086, 0, - 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, + 400, 402, 309, 234, 327, 0, 0, 0, 0, 519, + 0, 0, 0, 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, - 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, + 247, 240, 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, + 553, 554, 0, 0, 0, 0, 0, 0, 0, 0, + 275, 221, 190, 324, 389, 251, 71, 0, 0, 182, + 183, 184, 540, 1430, 542, 543, 544, 545, 0, 0, + 212, 541, 219, 546, 547, 548, 0, 233, 273, 239, + 232, 404, 0, 0, 0, 516, 533, 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 275, 221, 190, 324, 389, 251, 0, 0, 0, 182, - 183, 184, 0, 1088, 0, 0, 0, 0, 0, 0, - 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, - 232, 404, 972, 973, 971, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 974, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 259, 0, 313, 0, 0, 0, - 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 530, 531, + 609, 0, 0, 0, 577, 0, 532, 0, 0, 525, + 526, 528, 527, 529, 534, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 259, 0, 313, 0, 576, 0, + 0, 435, 0, 0, 574, 0, 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, @@ -2679,9 +2288,9 @@ var yyAct = [...]int{ 450, 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, 386, - 282, 291, 0, 0, 336, 367, 214, 423, 387, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 185, + 282, 291, 0, 0, 336, 367, 214, 423, 387, 564, + 575, 570, 571, 568, 569, 563, 567, 566, 565, 578, + 555, 556, 557, 558, 560, 0, 572, 573, 559, 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2694,24 +2303,24 @@ var yyAct = [...]int{ 418, 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, - 360, 215, 378, 398, 399, 400, 402, 309, 234, 35, + 360, 215, 378, 398, 399, 400, 402, 309, 234, 589, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 327, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, + 0, 0, 327, 0, 0, 0, 0, 519, 0, 0, + 0, 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, - 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, - 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, + 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, + 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, - 190, 324, 389, 251, 71, 0, 596, 182, 183, 184, - 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, - 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 259, 0, 313, 0, 0, 0, 0, 435, - 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, + 190, 324, 389, 251, 71, 0, 0, 182, 183, 184, + 540, 539, 542, 543, 544, 545, 0, 0, 212, 541, + 219, 546, 547, 548, 0, 233, 273, 239, 232, 404, + 0, 0, 0, 516, 533, 0, 561, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 530, 531, 0, 0, + 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, + 527, 529, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 313, 0, 576, 0, 0, 435, + 0, 0, 574, 0, 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, @@ -2726,9 +2335,9 @@ var yyAct = [...]int{ 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, - 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 185, 198, 287, + 0, 0, 336, 367, 214, 423, 387, 564, 575, 570, + 571, 568, 569, 563, 567, 566, 565, 578, 555, 556, + 557, 558, 560, 0, 572, 573, 559, 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2742,24 +2351,206 @@ var yyAct = [...]int{ 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, - 0, 1460, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 519, 0, 0, 0, 237, 0, 518, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, - 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, - 0, 0, 182, 183, 184, 0, 1462, 0, 0, 0, - 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, - 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, + 0, 0, 0, 553, 554, 0, 0, 0, 0, 0, + 0, 0, 0, 275, 221, 190, 324, 389, 251, 71, + 0, 0, 182, 183, 184, 540, 539, 542, 543, 544, + 545, 0, 0, 212, 541, 219, 546, 547, 548, 0, + 233, 273, 239, 232, 404, 0, 0, 0, 516, 533, + 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 530, 531, 0, 0, 0, 0, 577, 0, 532, + 0, 0, 525, 526, 528, 527, 529, 534, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, + 0, 576, 0, 0, 435, 0, 0, 574, 0, 0, + 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, + 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, + 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, + 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, + 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, + 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, + 396, 417, 213, 377, 0, 0, 0, 195, 415, 393, + 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, + 412, 413, 225, 449, 204, 432, 197, 0, 431, 319, + 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, + 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, + 0, 390, 425, 450, 210, 0, 0, 403, 441, 446, + 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, + 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, + 205, 268, 386, 282, 291, 0, 0, 336, 367, 214, + 423, 387, 564, 575, 570, 571, 568, 569, 563, 567, + 566, 565, 578, 555, 556, 557, 558, 560, 0, 572, + 573, 559, 185, 198, 287, 0, 356, 252, 448, 430, + 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 188, 199, 207, + 217, 229, 242, 250, 260, 264, 267, 270, 271, 274, + 279, 296, 301, 302, 303, 304, 320, 321, 322, 325, + 328, 329, 332, 334, 335, 338, 344, 345, 346, 347, + 348, 350, 357, 361, 369, 370, 371, 372, 373, 375, + 376, 380, 381, 382, 383, 391, 395, 410, 411, 422, + 434, 438, 261, 418, 439, 0, 295, 0, 0, 297, + 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, + 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, + 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, + 309, 234, 327, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, + 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, + 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, + 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, + 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, + 190, 324, 389, 251, 71, 0, 0, 182, 183, 184, + 540, 539, 542, 543, 544, 545, 0, 0, 212, 541, + 219, 546, 547, 548, 0, 233, 273, 239, 232, 404, + 0, 0, 0, 0, 533, 0, 561, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 530, 531, 0, 0, + 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, + 527, 529, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 313, 0, 576, 0, 0, 435, + 0, 0, 574, 0, 0, 0, 0, 0, 284, 0, + 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, + 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, + 364, 2202, 0, 365, 290, 409, 354, 419, 436, 437, + 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, + 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, + 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, + 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, + 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, + 432, 197, 0, 431, 319, 408, 416, 308, 299, 196, + 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, + 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, + 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, + 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, + 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, + 0, 0, 336, 367, 214, 423, 387, 564, 575, 570, + 571, 568, 569, 563, 567, 566, 565, 578, 555, 556, + 557, 558, 560, 0, 572, 573, 559, 185, 198, 287, + 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 188, 199, 207, 217, 229, 242, 250, 260, + 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, + 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, + 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, + 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, + 391, 395, 410, 411, 422, 434, 438, 261, 418, 439, + 0, 295, 0, 0, 297, 246, 263, 272, 0, 429, + 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, + 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, + 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, + 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, + 397, 333, 562, 289, 0, 0, 388, 312, 0, 0, + 0, 0, 0, 553, 554, 0, 0, 0, 0, 0, + 0, 0, 0, 275, 221, 190, 324, 389, 251, 71, + 0, 596, 182, 183, 184, 540, 539, 542, 543, 544, + 545, 0, 0, 212, 541, 219, 546, 547, 548, 0, + 233, 273, 239, 232, 404, 0, 0, 0, 0, 533, + 0, 561, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 530, 531, 0, 0, 0, 0, 577, 0, 532, + 0, 0, 525, 526, 528, 527, 529, 534, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, + 0, 576, 0, 0, 435, 0, 0, 574, 0, 0, + 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, + 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, + 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, + 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, + 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, + 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, + 396, 417, 213, 377, 0, 0, 0, 195, 415, 393, + 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, + 412, 413, 225, 449, 204, 432, 197, 0, 431, 319, + 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, + 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, + 0, 390, 425, 450, 210, 0, 0, 403, 441, 446, + 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, + 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, + 205, 268, 386, 282, 291, 0, 0, 336, 367, 214, + 423, 387, 564, 575, 570, 571, 568, 569, 563, 567, + 566, 565, 578, 555, 556, 557, 558, 560, 0, 572, + 573, 559, 185, 198, 287, 0, 356, 252, 448, 430, + 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 187, 188, 199, 207, + 217, 229, 242, 250, 260, 264, 267, 270, 271, 274, + 279, 296, 301, 302, 303, 304, 320, 321, 322, 325, + 328, 329, 332, 334, 335, 338, 344, 345, 346, 347, + 348, 350, 357, 361, 369, 370, 371, 372, 373, 375, + 376, 380, 381, 382, 383, 391, 395, 410, 411, 422, + 434, 438, 261, 418, 439, 0, 295, 0, 0, 297, + 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, + 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, + 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, + 309, 234, 327, 0, 0, 0, 0, 0, 0, 0, + 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, + 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, + 236, 222, 269, 300, 339, 397, 333, 562, 289, 0, + 0, 388, 312, 0, 0, 0, 0, 0, 553, 554, + 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, + 190, 324, 389, 251, 71, 0, 0, 182, 183, 184, + 540, 539, 542, 543, 544, 545, 0, 0, 212, 541, + 219, 546, 547, 548, 0, 233, 273, 239, 232, 404, + 0, 0, 0, 0, 533, 0, 561, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 530, 531, 0, 0, + 0, 0, 577, 0, 532, 0, 0, 525, 526, 528, + 527, 529, 534, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 313, 0, 576, 0, 0, 435, + 0, 0, 574, 0, 0, 0, 0, 0, 284, 0, + 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, + 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, + 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, + 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, + 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, + 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, + 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, + 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, + 432, 197, 0, 431, 319, 408, 416, 308, 299, 196, + 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, + 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, + 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, + 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, + 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, + 0, 0, 336, 367, 214, 423, 387, 564, 575, 570, + 571, 568, 569, 563, 567, 566, 565, 578, 555, 556, + 557, 558, 560, 0, 572, 573, 559, 185, 198, 287, + 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 187, 188, 199, 207, 217, 229, 242, 250, 260, + 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, + 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, + 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, + 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, + 391, 395, 410, 411, 422, 434, 438, 261, 418, 439, + 0, 295, 0, 0, 297, 246, 263, 272, 0, 429, + 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, + 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, + 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, + 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, + 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, + 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, + 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, + 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 983, 982, 992, + 993, 985, 986, 987, 988, 989, 990, 991, 984, 0, + 0, 994, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, - 421, 208, 249, 359, 342, 364, 0, 1458, 365, 290, + 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, @@ -2788,7 +2579,7 @@ var yyAct = [...]int{ 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, + 0, 237, 809, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, @@ -2797,13 +2588,13 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 259, 0, 313, 0, 0, 0, 0, 435, - 0, 0, 0, 0, 0, 0, 0, 0, 284, 774, - 281, 186, 201, 772, 0, 323, 362, 368, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 259, 0, 313, 0, 0, 0, 808, 435, + 0, 0, 0, 0, 0, 0, 805, 806, 284, 774, + 281, 186, 201, 799, 803, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, @@ -2833,17 +2624,17 @@ var yyAct = [...]int{ 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, - 0, 1460, 0, 0, 0, 0, 237, 0, 0, 0, + 0, 1086, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, - 0, 0, 182, 183, 184, 0, 1462, 0, 0, 0, + 0, 0, 182, 183, 184, 0, 1088, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, - 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 233, 273, 239, 232, 404, 972, 973, 971, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 974, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, @@ -2885,7 +2676,7 @@ var yyAct = [...]int{ 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 71, 0, 0, + 0, 275, 221, 190, 324, 389, 251, 71, 0, 596, 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, @@ -2925,14 +2716,14 @@ var yyAct = [...]int{ 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 327, 0, 0, 0, 1460, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, - 1480, 0, 0, 1481, 0, 0, 212, 0, 219, 0, + 389, 251, 0, 0, 0, 182, 183, 184, 0, 1462, + 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2943,7 +2734,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, - 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, + 1458, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, @@ -2971,22 +2762,22 @@ var yyAct = [...]int{ 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 1119, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, - 182, 183, 184, 0, 1118, 0, 0, 0, 0, 0, + 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, - 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, + 0, 284, 774, 281, 186, 201, 772, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, @@ -3016,13 +2807,13 @@ var yyAct = [...]int{ 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 327, 0, 0, 0, 1460, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 596, 182, 183, 184, 0, 0, + 389, 251, 0, 0, 0, 182, 183, 184, 0, 1462, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3067,7 +2858,7 @@ var yyAct = [...]int{ 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 71, 0, 0, + 0, 275, 221, 190, 324, 389, 251, 0, 0, 596, 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, @@ -3076,7 +2867,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, 259, 0, 313, 0, 0, - 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 435, 0, 0, 0, 0, 2105, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, @@ -3107,371 +2898,828 @@ var yyAct = [...]int{ 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, - 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, - 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, - 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 0, 182, 183, 184, 0, 1462, - 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, - 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, + 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 327, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 71, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, - 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, - 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, - 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, - 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, - 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, - 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, - 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, - 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, - 255, 226, 326, 412, 413, 225, 449, 204, 432, 197, - 0, 431, 319, 408, 416, 308, 299, 196, 414, 306, - 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, - 316, 0, 191, 0, 390, 425, 450, 210, 0, 0, - 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, - 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, - 248, 428, 318, 205, 268, 386, 282, 291, 0, 0, - 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 185, 198, 287, 0, 356, - 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 188, 199, 207, 217, 229, 242, 250, 260, 264, 267, - 270, 271, 274, 279, 296, 301, 302, 303, 304, 320, - 321, 322, 325, 328, 329, 332, 334, 335, 338, 344, - 345, 346, 347, 348, 350, 357, 361, 369, 370, 371, - 372, 373, 375, 376, 380, 381, 382, 383, 391, 395, - 410, 411, 422, 434, 438, 261, 418, 439, 0, 295, - 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, - 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, - 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, - 399, 400, 402, 309, 234, 327, 0, 0, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, - 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, - 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, - 182, 183, 184, 0, 1088, 0, 0, 0, 0, 0, - 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, - 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 0, 1480, 0, + 0, 1481, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, - 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, - 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, - 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, - 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, - 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, - 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, - 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, - 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, - 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, - 225, 449, 204, 432, 197, 0, 431, 319, 408, 416, - 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, - 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, - 425, 450, 210, 0, 0, 403, 441, 446, 0, 355, - 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, - 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, - 386, 282, 291, 0, 0, 336, 367, 214, 423, 387, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 1119, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 1118, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 188, 199, 207, 217, 229, - 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, - 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, - 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, - 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, - 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, - 261, 418, 439, 0, 295, 0, 0, 297, 246, 263, - 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, - 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, - 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, - 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, - 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, - 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, - 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, - 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, - 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, - 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, - 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, - 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, - 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, - 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, - 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, - 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, - 255, 226, 326, 412, 413, 225, 449, 204, 432, 197, - 0, 431, 319, 408, 416, 308, 299, 196, 414, 306, - 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, - 316, 0, 191, 0, 390, 425, 450, 210, 0, 0, - 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, - 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, - 248, 428, 318, 205, 268, 386, 282, 291, 0, 0, - 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 185, 198, 287, 1365, 356, - 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 188, 199, 207, 217, 229, 242, 250, 260, 264, 267, - 270, 271, 274, 279, 296, 301, 302, 303, 304, 320, - 321, 322, 325, 328, 329, 332, 334, 335, 338, 344, - 345, 346, 347, 348, 350, 357, 361, 369, 370, 371, - 372, 373, 375, 376, 380, 381, 382, 383, 391, 395, - 410, 411, 422, 434, 438, 261, 418, 439, 0, 295, - 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, - 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, - 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, - 399, 400, 402, 309, 234, 327, 0, 1243, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, - 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, - 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, - 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, - 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, - 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 2186, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, - 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, - 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, - 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, - 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, - 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, - 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, - 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, - 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, - 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, - 225, 449, 204, 432, 197, 0, 431, 319, 408, 416, - 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, - 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, - 425, 450, 210, 0, 0, 403, 441, 446, 0, 355, - 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, - 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, - 386, 282, 291, 0, 0, 336, 367, 214, 423, 387, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 188, 199, 207, 217, 229, - 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, - 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, - 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, - 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, - 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, - 261, 418, 439, 0, 295, 0, 0, 297, 246, 263, - 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, - 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, - 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 1241, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, - 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, - 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, - 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, - 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, - 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 2105, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, - 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, - 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, - 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, - 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, - 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, - 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, - 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, - 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, - 255, 226, 326, 412, 413, 225, 449, 204, 432, 197, - 0, 431, 319, 408, 416, 308, 299, 196, 414, 306, - 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, - 316, 0, 191, 0, 390, 425, 450, 210, 0, 0, - 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, - 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, - 248, 428, 318, 205, 268, 386, 282, 291, 0, 0, - 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 185, 198, 287, 0, 356, - 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 71, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 188, 199, 207, 217, 229, 242, 250, 260, 264, 267, - 270, 271, 274, 279, 296, 301, 302, 303, 304, 320, - 321, 322, 325, 328, 329, 332, 334, 335, 338, 344, - 345, 346, 347, 348, 350, 357, 361, 369, 370, 371, - 372, 373, 375, 376, 380, 381, 382, 383, 391, 395, - 410, 411, 422, 434, 438, 261, 418, 439, 0, 295, - 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, - 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, - 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, - 399, 400, 402, 309, 234, 327, 0, 1239, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, - 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, - 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, - 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, - 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, - 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, - 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, - 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, - 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, - 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, - 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, - 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, - 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, - 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, - 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, - 225, 449, 204, 432, 197, 0, 431, 319, 408, 416, - 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, - 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, - 425, 450, 210, 0, 0, 403, 441, 446, 0, 355, - 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, - 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, - 386, 282, 291, 0, 0, 336, 367, 214, 423, 387, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 1462, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 188, 199, 207, 217, 229, - 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, - 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, - 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, - 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, - 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, - 261, 418, 439, 0, 295, 0, 0, 297, 246, 263, - 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, - 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, - 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 1237, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, - 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, - 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, - 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, - 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, - 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, - 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, - 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, - 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, - 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, - 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, - 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, - 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, - 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, - 255, 226, 326, 412, 413, 225, 449, 204, 432, 197, - 0, 431, 319, 408, 416, 308, 299, 196, 414, 306, - 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, - 316, 0, 191, 0, 390, 425, 450, 210, 0, 0, - 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, - 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, - 248, 428, 318, 205, 268, 386, 282, 291, 0, 0, - 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 1088, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 185, 198, 287, 0, 356, - 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, - 188, 199, 207, 217, 229, 242, 250, 260, 264, 267, - 270, 271, 274, 279, 296, 301, 302, 303, 304, 320, - 321, 322, 325, 328, 329, 332, 334, 335, 338, 344, - 345, 346, 347, 348, 350, 357, 361, 369, 370, 371, - 372, 373, 375, 376, 380, 381, 382, 383, 391, 395, - 410, 411, 422, 434, 438, 261, 418, 439, 0, 295, - 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, - 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, - 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, - 399, 400, 402, 309, 234, 327, 0, 1235, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, - 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, - 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, - 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, - 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, - 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, - 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 0, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 1365, 356, 252, 448, 430, 426, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 1243, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 1241, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 1239, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 1237, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 1235, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 1231, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 1229, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 327, 0, 1227, 0, 0, 0, 0, + 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, + 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, + 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, + 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, + 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, + 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, + 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, + 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 259, 0, 313, 0, 0, 0, 0, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, + 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, + 0, 0, 224, 0, 366, 337, 421, 208, 249, 359, + 342, 364, 0, 0, 365, 290, 409, 354, 419, 436, + 437, 231, 317, 427, 401, 433, 447, 202, 228, 331, + 394, 424, 385, 310, 405, 406, 280, 384, 257, 189, + 288, 444, 200, 374, 216, 193, 396, 417, 213, 377, + 0, 0, 0, 195, 415, 393, 307, 277, 278, 194, + 0, 358, 235, 255, 226, 326, 412, 413, 225, 449, + 204, 432, 197, 0, 431, 319, 408, 416, 308, 299, + 196, 414, 306, 298, 283, 245, 265, 352, 293, 353, + 266, 315, 314, 316, 0, 191, 0, 390, 425, 450, + 210, 0, 0, 403, 441, 446, 0, 355, 211, 256, + 244, 351, 254, 286, 440, 442, 443, 445, 209, 349, + 262, 330, 420, 248, 428, 318, 205, 268, 386, 282, + 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 185, 198, + 287, 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 187, 188, 199, 207, 217, 229, 242, 250, + 260, 264, 267, 270, 271, 274, 279, 296, 301, 302, + 303, 304, 320, 321, 322, 325, 328, 329, 332, 334, + 335, 338, 344, 345, 346, 347, 348, 350, 357, 361, + 369, 370, 371, 372, 373, 375, 376, 380, 381, 382, + 383, 391, 395, 410, 411, 422, 434, 438, 261, 418, + 439, 0, 295, 0, 0, 297, 246, 263, 272, 0, + 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, + 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, + 215, 378, 398, 399, 400, 402, 309, 234, 327, 0, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, + 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, + 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, + 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 275, 221, 190, 324, 389, 251, + 1202, 0, 0, 182, 183, 184, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, + 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, - 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, - 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, - 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, - 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, - 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, - 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, - 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, - 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, - 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, - 225, 449, 204, 432, 197, 0, 431, 319, 408, 416, - 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, - 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, - 425, 450, 210, 0, 0, 403, 441, 446, 0, 355, - 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, - 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, - 386, 282, 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, - 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 187, 188, 199, 207, 217, 229, - 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, - 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, - 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, - 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, - 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, - 261, 418, 439, 0, 295, 0, 0, 297, 246, 263, - 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, - 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, - 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 1231, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 0, 0, 0, 0, 0, 0, 259, 0, + 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, + 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, + 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, + 337, 421, 208, 249, 359, 342, 364, 0, 0, 365, + 290, 409, 354, 419, 436, 437, 231, 317, 427, 401, + 433, 447, 202, 228, 331, 394, 424, 385, 310, 405, + 406, 280, 384, 257, 189, 288, 444, 200, 374, 216, + 193, 396, 417, 213, 377, 0, 0, 0, 195, 415, + 393, 307, 277, 278, 194, 0, 358, 235, 255, 226, + 326, 412, 413, 225, 449, 204, 432, 197, 0, 431, + 319, 408, 416, 308, 299, 196, 414, 306, 298, 283, + 245, 265, 352, 293, 353, 266, 315, 314, 316, 0, + 191, 0, 390, 425, 450, 210, 0, 0, 403, 441, + 446, 0, 355, 211, 256, 244, 351, 254, 286, 440, + 442, 443, 445, 209, 349, 262, 330, 420, 248, 428, + 318, 205, 268, 386, 282, 291, 0, 0, 336, 367, + 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 185, 198, 287, 0, 356, 252, 448, + 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, + 207, 217, 229, 242, 250, 260, 264, 267, 270, 271, + 274, 279, 296, 301, 302, 303, 304, 320, 321, 322, + 325, 328, 329, 332, 334, 335, 338, 344, 345, 346, + 347, 348, 350, 357, 361, 369, 370, 371, 372, 373, + 375, 376, 380, 381, 382, 383, 391, 395, 410, 411, + 422, 434, 438, 261, 418, 439, 0, 295, 0, 0, + 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, + 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, + 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, + 402, 309, 234, 1101, 0, 0, 0, 0, 0, 0, + 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, @@ -3516,8 +3764,8 @@ var yyAct = [...]int{ 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, - 399, 400, 402, 309, 234, 327, 0, 1229, 0, 0, - 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 399, 400, 402, 309, 234, 327, 0, 0, 0, 0, + 0, 0, 0, 1092, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, @@ -3562,13 +3810,13 @@ var yyAct = [...]int{ 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 327, 0, 1227, 0, 0, 0, 0, 0, 0, 237, + 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, - 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, + 389, 251, 0, 0, 0, 182, 183, 184, 0, 948, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3613,7 +3861,7 @@ var yyAct = [...]int{ 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 275, 221, 190, 324, 389, 251, 1202, 0, 0, + 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, @@ -3621,7 +3869,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, 259, 0, 313, 0, 0, + 0, 0, 0, 507, 0, 259, 0, 313, 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, @@ -3644,310 +3892,127 @@ var yyAct = [...]int{ 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, 188, 199, 207, 217, 229, - 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, - 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, - 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, - 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, - 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, - 261, 418, 439, 0, 295, 0, 0, 297, 246, 263, - 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, - 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, - 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, - 1101, 0, 0, 0, 0, 0, 0, 327, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, - 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, - 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, - 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, - 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, - 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, - 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, - 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, - 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, - 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, - 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, - 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, - 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, - 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, - 396, 417, 213, 377, 0, 0, 0, 195, 415, 393, - 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, - 412, 413, 225, 449, 204, 432, 197, 0, 431, 319, - 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, - 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, - 0, 390, 425, 450, 210, 0, 0, 403, 441, 446, - 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, - 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, - 205, 268, 386, 282, 291, 0, 0, 336, 367, 214, - 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 185, 198, 287, 0, 356, 252, 448, 430, - 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 187, 188, 199, 207, - 217, 229, 242, 250, 260, 264, 267, 270, 271, 274, - 279, 296, 301, 302, 303, 304, 320, 321, 322, 325, - 328, 329, 332, 334, 335, 338, 344, 345, 346, 347, - 348, 350, 357, 361, 369, 370, 371, 372, 373, 375, - 376, 380, 381, 382, 383, 391, 395, 410, 411, 422, - 434, 438, 261, 418, 439, 0, 295, 0, 0, 297, - 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, - 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, - 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, - 309, 234, 327, 0, 0, 0, 0, 0, 0, 0, - 1092, 237, 0, 0, 0, 0, 0, 285, 0, 0, - 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, - 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, - 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, - 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, - 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, - 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 259, 0, 313, 0, 0, 0, 0, 435, - 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, - 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, - 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, - 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, - 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, - 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, - 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, - 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, - 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, - 432, 197, 0, 431, 319, 408, 416, 308, 299, 196, - 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, - 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, - 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, - 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, - 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, - 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 185, 198, 287, - 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 188, 199, 207, 217, 229, 242, 250, 260, - 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, - 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, - 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, - 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, - 391, 395, 410, 411, 422, 434, 438, 261, 418, 439, - 0, 295, 0, 0, 297, 246, 263, 272, 0, 429, - 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, - 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, - 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, - 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, - 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, - 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, - 0, 0, 182, 183, 184, 0, 948, 0, 0, 0, - 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, - 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, - 0, 0, 0, 0, 435, 0, 0, 0, 0, 0, - 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, - 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, - 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, - 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, - 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, - 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, - 396, 417, 213, 377, 0, 0, 0, 195, 415, 393, - 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, - 412, 413, 225, 449, 204, 432, 197, 0, 431, 319, - 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, - 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, - 0, 390, 425, 450, 210, 0, 0, 403, 441, 446, - 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, - 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, - 205, 268, 386, 282, 291, 0, 0, 336, 367, 214, - 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 185, 198, 287, 0, 356, 252, 448, 430, - 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 187, 188, 199, 207, - 217, 229, 242, 250, 260, 264, 267, 270, 271, 274, - 279, 296, 301, 302, 303, 304, 320, 321, 322, 325, - 328, 329, 332, 334, 335, 338, 344, 345, 346, 347, - 348, 350, 357, 361, 369, 370, 371, 372, 373, 375, - 376, 380, 381, 382, 383, 391, 395, 410, 411, 422, - 434, 438, 261, 418, 439, 0, 295, 0, 0, 297, - 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, - 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, - 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, - 309, 234, 327, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, - 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, - 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, - 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, - 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, - 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, - 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 507, 0, 259, 0, 313, 0, 0, 0, 0, 435, - 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, - 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, - 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, - 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, - 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, - 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, - 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, - 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, - 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, - 432, 197, 0, 431, 319, 408, 416, 308, 299, 196, - 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, - 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, - 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, - 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, - 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, - 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 185, 198, 287, - 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 188, 199, 207, 217, 229, 242, 250, 260, - 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, - 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, - 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, - 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, - 391, 395, 410, 411, 422, 434, 438, 506, 418, 439, - 0, 295, 0, 0, 297, 246, 263, 272, 0, 429, - 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, - 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, - 378, 398, 399, 400, 402, 309, 234, 327, 0, 0, - 0, 0, 0, 0, 0, 0, 237, 0, 0, 0, - 0, 0, 285, 0, 0, 0, 341, 0, 379, 223, - 294, 292, 407, 247, 240, 236, 222, 269, 300, 339, - 397, 333, 0, 289, 0, 0, 388, 312, 0, 0, + 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, + 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, + 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, + 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, + 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, + 506, 418, 439, 0, 295, 0, 0, 297, 246, 263, + 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, + 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, + 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, + 327, 0, 0, 0, 0, 0, 0, 0, 0, 237, + 0, 0, 0, 0, 0, 285, 0, 0, 0, 341, + 0, 379, 223, 294, 292, 407, 247, 240, 236, 222, + 269, 300, 339, 397, 333, 0, 289, 0, 0, 388, + 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 275, 221, 190, 324, + 389, 251, 0, 0, 0, 182, 183, 184, 0, 0, + 0, 0, 0, 0, 0, 0, 212, 0, 219, 0, + 0, 0, 0, 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 275, 221, 190, 324, 389, 251, 0, - 0, 0, 182, 183, 184, 0, 0, 0, 0, 0, - 0, 0, 0, 212, 0, 219, 0, 0, 0, 0, - 233, 273, 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 259, 0, 313, - 0, 0, 456, 0, 435, 0, 0, 0, 0, 0, - 0, 0, 0, 284, 0, 281, 186, 201, 0, 0, - 323, 362, 368, 0, 0, 0, 224, 0, 366, 337, - 421, 208, 249, 359, 342, 364, 0, 0, 365, 290, - 409, 354, 419, 436, 437, 231, 317, 427, 401, 433, - 447, 202, 228, 331, 394, 424, 385, 310, 405, 406, - 280, 384, 257, 189, 288, 444, 200, 374, 216, 193, - 396, 417, 213, 377, 0, 0, 0, 195, 415, 393, - 307, 277, 278, 194, 0, 358, 235, 255, 226, 326, - 412, 413, 225, 449, 204, 432, 197, 0, 431, 319, - 408, 416, 308, 299, 196, 414, 306, 298, 283, 245, - 265, 352, 293, 353, 266, 315, 314, 316, 0, 191, - 0, 390, 425, 450, 210, 0, 0, 403, 441, 446, - 0, 355, 211, 256, 244, 351, 254, 286, 440, 442, - 443, 445, 209, 349, 262, 330, 420, 248, 428, 318, - 205, 268, 386, 282, 291, 0, 0, 336, 367, 214, - 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, + 259, 0, 313, 0, 0, 456, 0, 435, 0, 0, + 0, 0, 0, 0, 0, 0, 284, 0, 281, 186, + 201, 0, 0, 323, 362, 368, 0, 0, 0, 224, + 0, 366, 337, 421, 208, 249, 359, 342, 364, 0, + 0, 365, 290, 409, 354, 419, 436, 437, 231, 317, + 427, 401, 433, 447, 202, 228, 331, 394, 424, 385, + 310, 405, 406, 280, 384, 257, 189, 288, 444, 200, + 374, 216, 193, 396, 417, 213, 377, 0, 0, 0, + 195, 415, 393, 307, 277, 278, 194, 0, 358, 235, + 255, 226, 326, 412, 413, 225, 449, 204, 432, 197, + 0, 431, 319, 408, 416, 308, 299, 196, 414, 306, + 298, 283, 245, 265, 352, 293, 353, 266, 315, 314, + 316, 0, 191, 0, 390, 425, 450, 210, 0, 0, + 403, 441, 446, 0, 355, 211, 256, 244, 351, 254, + 286, 440, 442, 443, 445, 209, 349, 262, 330, 420, + 248, 428, 318, 205, 268, 386, 282, 291, 0, 0, + 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 185, 198, 287, 0, 356, 252, 448, 430, - 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 185, 198, 287, 0, 356, + 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 187, 188, 199, 207, - 217, 229, 242, 250, 260, 264, 267, 270, 271, 274, - 279, 296, 301, 302, 303, 304, 320, 321, 322, 325, - 328, 329, 332, 334, 335, 338, 344, 345, 346, 347, - 348, 350, 357, 361, 369, 370, 371, 372, 373, 375, - 376, 380, 381, 382, 383, 391, 395, 410, 411, 422, - 434, 438, 261, 418, 439, 0, 295, 0, 0, 297, - 246, 263, 272, 0, 429, 392, 203, 363, 253, 192, - 220, 206, 227, 241, 243, 276, 305, 311, 340, 343, - 258, 238, 218, 360, 215, 378, 398, 399, 400, 402, - 309, 234, 327, 0, 0, 0, 0, 0, 0, 0, - 0, 237, 0, 0, 0, 0, 0, 285, 0, 0, - 0, 341, 0, 379, 223, 294, 292, 407, 247, 240, - 236, 222, 269, 300, 339, 397, 333, 0, 289, 0, - 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 275, 221, - 190, 324, 389, 251, 0, 0, 0, 182, 183, 184, - 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, - 219, 0, 0, 0, 0, 233, 273, 239, 232, 404, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 187, + 188, 199, 207, 217, 229, 242, 250, 260, 264, 267, + 270, 271, 274, 279, 296, 301, 302, 303, 304, 320, + 321, 322, 325, 328, 329, 332, 334, 335, 338, 344, + 345, 346, 347, 348, 350, 357, 361, 369, 370, 371, + 372, 373, 375, 376, 380, 381, 382, 383, 391, 395, + 410, 411, 422, 434, 438, 261, 418, 439, 0, 295, + 0, 0, 297, 246, 263, 272, 0, 429, 392, 203, + 363, 253, 192, 220, 206, 227, 241, 243, 276, 305, + 311, 340, 343, 258, 238, 218, 360, 215, 378, 398, + 399, 400, 402, 309, 234, 327, 0, 0, 0, 0, + 0, 0, 0, 0, 237, 0, 0, 0, 0, 0, + 285, 0, 0, 0, 341, 0, 379, 223, 294, 292, + 407, 247, 240, 236, 222, 269, 300, 339, 397, 333, + 0, 289, 0, 0, 388, 312, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 275, 221, 190, 324, 389, 251, 0, 0, 0, + 182, 183, 184, 0, 0, 0, 0, 0, 0, 0, + 0, 212, 0, 219, 0, 0, 0, 0, 233, 273, + 239, 232, 404, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 259, 0, 313, 0, 0, 0, 0, 435, - 0, 0, 0, 0, 0, 0, 0, 0, 284, 0, - 281, 186, 201, 0, 0, 323, 362, 368, 0, 0, - 0, 224, 0, 366, 337, 421, 208, 249, 359, 342, - 364, 0, 0, 365, 290, 409, 354, 419, 436, 437, - 231, 317, 427, 401, 433, 447, 202, 228, 331, 394, - 424, 385, 310, 405, 406, 280, 384, 257, 189, 288, - 444, 200, 374, 216, 193, 396, 417, 213, 377, 0, - 0, 0, 195, 415, 393, 307, 277, 278, 194, 0, - 358, 235, 255, 226, 326, 412, 413, 225, 449, 204, - 432, 197, 0, 431, 319, 408, 416, 308, 299, 196, - 414, 306, 298, 283, 245, 265, 352, 293, 353, 266, - 315, 314, 316, 0, 191, 0, 390, 425, 450, 210, - 0, 0, 403, 441, 446, 0, 355, 211, 256, 244, - 351, 254, 286, 440, 442, 443, 445, 209, 349, 262, - 330, 420, 248, 428, 318, 205, 268, 386, 282, 291, - 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, + 0, 0, 0, 0, 0, 259, 0, 313, 0, 0, + 0, 0, 435, 0, 0, 0, 0, 0, 0, 0, + 0, 284, 0, 281, 186, 201, 0, 0, 323, 362, + 368, 0, 0, 0, 224, 0, 366, 337, 421, 208, + 249, 359, 342, 364, 0, 0, 365, 290, 409, 354, + 419, 436, 437, 231, 317, 427, 401, 433, 447, 202, + 228, 331, 394, 424, 385, 310, 405, 406, 280, 384, + 257, 189, 288, 444, 200, 374, 216, 193, 396, 417, + 213, 377, 0, 0, 0, 195, 415, 393, 307, 277, + 278, 194, 0, 358, 235, 255, 226, 326, 412, 413, + 225, 449, 204, 432, 197, 0, 431, 319, 408, 416, + 308, 299, 196, 414, 306, 298, 283, 245, 265, 352, + 293, 353, 266, 315, 314, 316, 0, 191, 0, 390, + 425, 450, 210, 0, 0, 403, 441, 446, 0, 355, + 211, 256, 244, 351, 254, 286, 440, 442, 443, 445, + 209, 349, 262, 330, 420, 248, 428, 318, 205, 268, + 386, 282, 291, 0, 0, 336, 367, 214, 423, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 185, 198, 287, - 0, 356, 252, 448, 430, 426, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 185, 198, 287, 0, 356, 252, 448, 430, 426, 0, + 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 187, 188, 199, 207, 217, 229, 242, 250, 260, - 264, 267, 270, 271, 274, 279, 296, 301, 302, 303, - 304, 320, 321, 322, 325, 328, 329, 332, 334, 335, - 338, 344, 345, 346, 347, 348, 350, 357, 361, 369, - 370, 371, 372, 373, 375, 376, 380, 381, 382, 383, - 391, 395, 410, 411, 422, 434, 438, 261, 418, 439, - 0, 295, 0, 0, 297, 246, 263, 272, 0, 429, - 392, 203, 363, 253, 192, 220, 206, 227, 241, 243, - 276, 305, 311, 340, 343, 258, 238, 218, 360, 215, - 378, 398, 399, 400, 402, 309, 234, + 0, 0, 0, 0, 187, 188, 199, 207, 217, 229, + 242, 250, 260, 264, 267, 270, 271, 274, 279, 296, + 301, 302, 303, 304, 320, 321, 322, 325, 328, 329, + 332, 334, 335, 338, 344, 345, 346, 347, 348, 350, + 357, 361, 369, 370, 371, 372, 373, 375, 376, 380, + 381, 382, 383, 391, 395, 410, 411, 422, 434, 438, + 261, 418, 439, 0, 295, 0, 0, 297, 246, 263, + 272, 0, 429, 392, 203, 363, 253, 192, 220, 206, + 227, 241, 243, 276, 305, 311, 340, 343, 258, 238, + 218, 360, 215, 378, 398, 399, 400, 402, 309, 234, } var yyPact = [...]int{ - 2708, -1000, -342, 1647, -1000, -1000, -1000, -1000, -1000, -1000, + 4553, -1000, -344, 1605, -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, 1601, 1240, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 581, 1270, 222, 1508, 213, 167, 27823, 412, - 85, 27368, 403, 2109, 27823, -1000, 99, -1000, 86, 27823, - 91, 26913, -1000, -1000, -284, 12775, 1450, 10, 8, 27823, - 106, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1246, - 1573, 1579, 1598, 1090, 1603, -1000, 10942, 10942, 354, 354, - 354, 9122, -1000, -1000, 16883, 27823, 27823, 1275, 402, 952, - 389, 387, 386, -1000, -106, -1000, -1000, -1000, -1000, 1508, - -1000, -1000, 168, -1000, 254, 1237, -1000, 1225, -1000, 419, - 416, 250, 330, 329, 248, 247, 245, 244, 242, 241, - 240, 238, 259, -1000, 539, 539, -172, -179, 296, 321, - 321, 321, 369, 1477, 1461, -1000, 623, -1000, 539, 539, - 164, 539, 539, 539, 539, 221, 219, 539, 539, 539, - 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, - 539, 539, 27823, -1000, 162, 580, 246, 613, 1508, 212, + -1000, -1000, -1000, 1576, 1182, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 581, 1246, 223, 1493, 3583, 156, 28476, 362, + 101, 28021, 361, 3864, 28476, -1000, 102, -1000, 89, 28476, + 93, 27566, -1000, -1000, -282, 12518, 1445, 16, 15, 28476, + 109, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1216, + 1534, 1542, 1581, 1059, 1598, -1000, 10685, 10685, 296, 296, + 296, 8865, -1000, -1000, 16626, 28476, 28476, 1258, 360, 964, + 346, 344, 343, -1000, -104, -1000, -1000, -1000, -1000, 1493, + -1000, -1000, 146, -1000, 234, 1176, -1000, 1175, -1000, 493, + 462, 231, 308, 295, 230, 229, 228, 226, 224, 220, + 219, 216, 237, -1000, 491, 491, -164, -172, 2210, 287, + 287, 287, 317, 1457, 1456, -1000, 526, -1000, 491, 491, + 126, 491, 491, 491, 491, 175, 171, 491, 491, 491, + 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 28476, -1000, 151, 495, 246, 534, 1493, 164, -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, @@ -3975,26 +4040,26 @@ 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, 27823, 400, 952, 349, -1000, 27823, -1000, 483, 27823, - 636, 636, 63, 636, 636, 636, 636, 82, 462, -10, - -1000, 73, 201, 187, 191, 673, 74, 62, -1000, -1000, - 189, 673, 90, -1000, 636, 7246, 7246, 7246, -1000, 1498, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 367, -1000, - -1000, -1000, -1000, 27823, 26458, 278, 598, -1000, -1000, -1000, - 23, -1000, -1000, 1146, 568, -1000, 12775, 2381, 1241, 1241, - -1000, -1000, 471, -1000, -1000, 14140, 14140, 14140, 14140, 14140, - 14140, 14140, 14140, 14140, 14140, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1241, - 479, -1000, 12320, 1241, 1241, 1241, 1241, 1241, 1241, 1241, - 1241, 12775, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, - 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, 1241, -1000, - -1000, -1000, 27823, -1000, 1241, 987, 1601, -1000, 1240, -1000, - -1000, -1000, 1494, 12775, 12775, 1601, -1000, 1390, 10942, -1000, - -1000, 1481, -1000, -1000, -1000, -1000, -1000, 711, 1633, -1000, - 15505, 476, 1632, 26003, -1000, 19626, 25548, 1205, 8653, -24, - -1000, -1000, -1000, 592, 18716, -1000, -1000, -1000, -1000, -1000, + -1000, 28476, 359, 964, 297, -1000, 28476, -1000, 419, 28476, + 628, 628, 49, 628, 628, 628, 628, 91, 417, 13, + -1000, 76, 160, 158, 152, 584, 111, 62, -1000, -1000, + 161, 584, 103, -1000, 628, 6989, 6989, 6989, -1000, 1480, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 316, -1000, + -1000, -1000, -1000, 28476, 27111, 286, 531, -1000, -1000, -1000, + 72, -1000, -1000, 1117, 765, -1000, 12518, 2281, 1178, 1178, + -1000, -1000, 410, -1000, -1000, 13883, 13883, 13883, 13883, 13883, + 13883, 13883, 13883, 13883, 13883, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1178, + 416, -1000, 12063, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 12518, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, -1000, + -1000, -1000, 28476, -1000, 1178, 926, 1576, -1000, 1182, -1000, + -1000, -1000, 1482, 12518, 12518, 1576, -1000, 1374, 10685, -1000, + -1000, 1506, -1000, -1000, -1000, -1000, -1000, 622, 1604, -1000, + 15248, 415, 1602, 26656, -1000, 20279, 26201, 1174, 8396, -47, + -1000, -1000, -1000, 529, 18914, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 1498, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 1480, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, @@ -4006,191 +4071,191 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1128, 27823, -1000, - -1000, 2563, 952, -1000, 1269, -1000, 1123, -1000, 1249, 162, - 352, 1287, 952, 952, 952, 352, -1000, -1000, -1000, 539, - 539, 257, 213, 3838, -1000, -1000, -1000, 25086, 1268, 952, - -1000, 1267, -1000, 1531, 337, 579, 579, 952, -1000, -1000, - 27823, 952, 1530, 1527, 27823, 27823, -1000, 24631, -1000, 24176, - 23721, 867, 27823, 23266, 22811, 22356, 21901, 21446, -1000, 1347, - -1000, 1262, -1000, -1000, -1000, 27823, 27823, 27823, -6, -1000, - -1000, 27823, 952, -1000, -1000, 860, 851, 539, 539, 850, - 986, 982, 977, 539, 539, 820, 976, 1012, 190, 813, - 804, 801, 831, 974, 108, 810, 789, 794, 27823, 1266, - -1000, 150, 578, 220, 270, 200, 27823, 132, 1571, 198, - 1508, 1449, 1202, 366, 349, 1308, 27823, 1553, 349, -1000, - 7715, -1000, -1000, 973, 12775, -1000, 679, 673, 673, -1000, - -1000, -1000, -1000, -1000, -1000, 636, 27823, 679, -1000, -1000, - -1000, 673, 636, 27823, 636, 636, 636, 636, 673, 636, - 27823, 27823, 27823, 27823, 27823, 27823, 27823, 27823, 27823, 7246, - 7246, 7246, 528, 636, -1000, 1307, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 89, -1000, -1000, -1000, -1000, -1000, - 1647, -1000, -1000, -1000, -115, 1181, 20991, -1000, -288, -289, - -290, -291, -1000, -1000, -1000, -292, -297, -1000, -1000, -1000, - 12775, 12775, 12775, 12775, 786, 530, 14140, 756, 533, 14140, - 14140, 14140, 14140, 14140, 14140, 14140, 14140, 14140, 14140, 14140, - 14140, 14140, 14140, 14140, 718, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 952, -1000, 1637, 1039, 1039, 491, 491, - 491, 491, 491, 491, 491, 491, 491, 14595, 9577, 7715, - 1090, 1117, 1601, 10942, 10942, 12775, 12775, 11852, 11397, 10942, - 1472, 631, 568, 27823, -1000, 881, -1000, -1000, 13685, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1115, 28476, -1000, + -1000, 4167, 964, -1000, 1238, -1000, 1112, -1000, 1190, 151, + 304, 1267, 964, 964, 964, 304, -1000, -1000, -1000, 491, + 491, 236, 3583, 3840, -1000, -1000, -1000, 25739, 1237, 964, + -1000, 1236, -1000, 1511, 285, 466, 466, 964, -1000, -1000, + 28476, 964, 1510, 1509, 28476, 28476, -1000, 25284, -1000, 24829, + 24374, 823, 28476, 23919, 23464, 23009, 22554, 22099, -1000, 1304, + -1000, 1243, -1000, -1000, -1000, 28476, 28476, 28476, 29, -1000, + -1000, 28476, 964, -1000, -1000, 822, 821, 491, 491, 820, + 918, 915, 914, 491, 491, 816, 911, 1028, 174, 815, + 807, 804, 867, 909, 127, 830, 826, 786, 28476, 1231, + -1000, 144, 517, 186, 217, 190, 28476, 117, 1537, 138, + 1493, 1431, 1170, 313, 297, 1311, 28476, 1525, 297, -1000, + 7458, -1000, -1000, 908, 12518, -1000, 618, 584, 584, -1000, + -1000, -1000, -1000, -1000, -1000, 628, 28476, 618, -1000, -1000, + -1000, 584, 628, 28476, 628, 628, 628, 628, 584, 628, + 28476, 28476, 28476, 28476, 28476, 28476, 28476, 28476, 28476, 6989, + 6989, 6989, 461, 628, -1000, 1310, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 92, -1000, -1000, -1000, -1000, -1000, + 1605, -1000, -1000, -1000, -111, 1158, 21644, -1000, -286, -287, + -288, -289, -1000, -1000, -1000, -290, -296, -1000, -1000, -1000, + 12518, 12518, 12518, 12518, 734, 473, 13883, 714, 605, 13883, + 13883, 13883, 13883, 13883, 13883, 13883, 13883, 13883, 13883, 13883, + 13883, 13883, 13883, 13883, 538, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 964, -1000, 1619, 921, 921, 442, 442, + 442, 442, 442, 442, 442, 442, 442, 14338, 9320, 7458, + 1059, 1073, 1576, 10685, 10685, 12518, 12518, 11595, 11140, 10685, + 1473, 550, 765, 28476, -1000, 933, -1000, -1000, 13428, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 27823, 27823, 10942, 10942, 10942, 10942, 10942, -1000, 1177, - -1000, -175, 16428, 12775, -1000, 1579, 1090, 1481, 1546, 1641, - 520, 863, 1176, -1000, 964, 1579, 18261, 1222, -1000, 1481, - -1000, -1000, -1000, 27823, -1000, -1000, 20536, -1000, -1000, 6777, - 27823, 234, 27823, -1000, 1190, 1567, -1000, -1000, -1000, 1568, - 17806, 27823, 1145, 1122, -1000, -1000, 474, 8184, -24, -1000, - 8184, 1160, -1000, -67, -37, 10032, 467, -1000, -1000, -1000, - 296, 15050, 1114, -1000, 25, -1000, -1000, -1000, 1249, -1000, - 1249, 1249, 1249, 1249, -6, -6, -6, -6, -1000, -1000, - -1000, -1000, -1000, 1264, 1263, -1000, 1249, 1249, 1249, 1249, + -1000, 28476, 28476, 10685, 10685, 10685, 10685, 10685, -1000, 1157, + -1000, -168, 16171, 12518, -1000, 1542, 1059, 1506, 1508, 1614, + 458, 671, 1155, -1000, 685, 1542, 18459, 1098, -1000, 1506, + -1000, -1000, -1000, 28476, -1000, -1000, 21189, -1000, -1000, 6520, + 28476, 208, 28476, -1000, 1120, 1399, -1000, -1000, -1000, 1531, + 18004, 28476, 1122, 1105, -1000, -1000, 414, 7927, -47, -1000, + 7927, 1135, -1000, -43, -72, 9775, 437, -1000, -1000, -1000, + 2210, 14793, 986, -1000, 27, -1000, -1000, -1000, 1190, -1000, + 1190, 1190, 1190, 1190, 29, 29, 29, 29, -1000, -1000, + -1000, -1000, -1000, 1223, 1213, -1000, 1190, 1190, 1190, 1190, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1256, 1256, 1256, - 1251, 1251, 314, -1000, 12775, 178, 27823, 1539, 791, 150, - 27823, 587, 1306, -1000, 27823, 1287, 1287, 1287, 27823, 970, - 877, -1000, 1175, -1000, -1000, 1597, -1000, -1000, 514, 671, - 668, 565, 27823, 114, 233, -1000, 308, -1000, 27823, 1254, - 1524, 579, 952, -1000, 952, -1000, -1000, -1000, -1000, 463, - -1000, -1000, 952, 1174, -1000, 1140, 707, 662, 704, 661, - 1174, -1000, -1000, -151, 1174, -1000, 1174, -1000, 1174, -1000, - 1174, -1000, 1174, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 534, 27823, 114, 718, -1000, 356, -1000, -1000, 718, - 718, -1000, -1000, -1000, -1000, 971, 969, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1212, 1212, 1212, + 1207, 1207, 277, -1000, 12518, 143, 28476, 1522, 776, 144, + 28476, 560, 1309, -1000, 28476, 1267, 1267, 1267, 28476, 1019, + 974, -1000, 1149, -1000, -1000, 1580, -1000, -1000, 576, 603, + 578, 616, 28476, 128, 207, -1000, 264, -1000, 28476, 1211, + 1507, 466, 964, -1000, 964, -1000, -1000, -1000, -1000, 413, + -1000, -1000, 964, 1146, -1000, 1136, 707, 575, 636, 570, + 1146, -1000, -1000, -126, 1146, -1000, 1146, -1000, 1146, -1000, + 1146, -1000, 1146, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 505, 28476, 128, 538, -1000, 312, -1000, -1000, 538, + 538, -1000, -1000, -1000, -1000, 905, 904, -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, -334, 27823, 376, 142, 151, 27823, 27823, - 27823, 27823, 27823, 424, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 202, 27823, 27823, 27823, 27823, 401, -1000, -1000, 27823, - -1000, -1000, -1000, -1000, 568, 27823, -1000, -1000, 636, 636, - -1000, -1000, 27823, 636, -1000, -1000, -1000, -1000, -1000, -1000, - 636, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 963, -1000, 27823, 27823, -1000, - -1000, -1000, -1000, -1000, 70, -71, 177, -1000, -1000, -1000, - -1000, 1576, -1000, 568, 530, 633, 583, -1000, -1000, 806, - -1000, -1000, 1277, -1000, -1000, -1000, -1000, 756, 14140, 14140, - 14140, 589, 1277, 2508, 1344, 1652, 491, 656, 656, 504, - 504, 504, 504, 504, 717, 717, -1000, -1000, -1000, -1000, - 881, -1000, -1000, -1000, 881, 10942, 10942, 1172, 1241, 451, - -1000, 1246, -1000, -1000, 1579, 1092, 1092, 829, 1011, 619, - 1626, 1092, 608, 1623, 1092, 1092, 10942, -1000, -1000, 695, - -1000, 12775, 881, -1000, 892, 1166, 1165, 1092, 881, 881, - 1092, 1092, 27823, -1000, -280, -1000, -86, 460, 1241, -1000, - 20081, -1000, -1000, 881, 1146, 1494, -1000, -1000, 1466, -1000, - 1387, 12775, 12775, 12775, -1000, -1000, -1000, 1494, 1578, -1000, - 1400, 1397, 1615, 10942, 19626, 1481, -1000, -1000, -1000, 448, - 1615, 1189, 1241, -1000, 27823, 19626, 19626, 19626, 19626, 19626, - -1000, 1321, 1320, -1000, 1361, 1358, 1338, 27823, -1000, 1111, - 1090, 17806, 234, 1157, 19626, 27823, -1000, -1000, 19626, 27823, - 6308, -1000, 1160, -24, -49, -1000, -1000, -1000, -1000, 568, - -1000, 858, -1000, 2216, -1000, 315, -1000, -1000, -1000, -1000, - 480, 15, -1000, -1000, -6, -6, -1000, -1000, 467, 748, - 467, 467, 467, 958, 958, -1000, -1000, -1000, -1000, -1000, - 787, -1000, -1000, -1000, 777, -1000, -1000, 960, 1342, 178, - -1000, -1000, 539, 956, 1455, -1000, -1000, 1049, 374, -1000, - 1552, 27823, -1000, 1305, 1302, 1297, -1000, -1000, -1000, -1000, - -1000, 3686, 27823, 1105, -1000, 111, 27823, 1040, 27823, -1000, - 1100, 27823, -1000, 952, -1000, -1000, 7715, -1000, 27823, 1241, - -1000, -1000, -1000, -1000, 398, 1506, 1505, 114, 111, 467, - 952, -1000, -1000, -1000, -1000, -1000, -337, 1096, 27823, 141, - -1000, 1253, 993, -1000, 1283, -1000, -1000, -1000, -1000, 109, - 215, 216, 331, -1000, 377, 1342, 27823, -1000, -1000, -1000, - -1000, 673, -1000, -1000, 673, -1000, -1000, -1000, -1000, -1000, - -1000, 1496, -75, -311, -1000, -307, -1000, -1000, -1000, -1000, - 589, 1277, 2421, -1000, 14140, 14140, -1000, -1000, 1092, 1092, - 10942, 7715, 1601, 1494, -1000, -1000, 285, 718, 285, 14140, - 14140, -1000, 14140, 14140, -1000, -119, 1168, 622, -1000, 12775, - 672, -1000, -1000, 14140, 14140, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 385, 380, 379, 27823, -1000, -1000, - -1000, 878, 929, 1369, 568, 568, -1000, -1000, 27823, -1000, - -1000, -1000, -1000, 1604, 12775, -1000, 1158, -1000, 5839, 1579, - 1294, 27823, 1241, 1647, 15973, 27823, 1167, -1000, 566, 1567, - 1281, 1293, 1393, -1000, -1000, -1000, -1000, 1319, -1000, 1280, - -1000, -1000, -1000, -1000, -1000, 1090, 1615, 19626, 1135, -1000, - 1135, -1000, 446, -1000, -1000, -1000, -80, -52, -1000, -1000, - -1000, 296, -1000, -1000, -1000, 684, 14140, 1640, -1000, 915, - 1519, -1000, 1518, -1000, -1000, 467, 467, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1087, -1000, 1082, 1156, 1079, 54, - -1000, 1194, 1493, 539, 539, -1000, 775, -1000, 952, -1000, - 27823, -1000, -1000, 27823, 27823, 27823, 1595, 1155, -1000, 27823, - -1000, -1000, 27823, -1000, -1000, 1396, 178, 1077, -1000, -1000, - -1000, 233, 27823, -1000, 1039, 111, -1000, -1000, -1000, -1000, - -1000, -1000, 1243, -1000, -1000, -1000, 1009, -1000, -159, 952, - 27823, 27823, 27823, -1000, 27823, -1000, -1000, -1000, 636, 636, - -1000, 1485, -1000, 952, -1000, 14140, 1277, 1277, -1000, -1000, - 881, -1000, 1579, -1000, 881, 1249, 1249, -1000, 1249, 1251, - -1000, 1249, 79, 1249, 69, 881, 881, 2295, 2211, 2145, - 1797, 1241, -113, -1000, 568, 12775, 1257, 876, 1241, 1241, - 1241, 1058, 911, -6, -1000, -1000, -1000, 1607, 1594, 568, - -1000, -1000, -1000, 1535, 1017, 1134, -1000, -1000, 10487, 1068, - 1394, 439, 1058, 1601, 27823, 12775, -1000, -1000, 12775, 1248, - -1000, 12775, -1000, -1000, -1000, 1601, 1601, 1135, -1000, -1000, - 505, -1000, -1000, -1000, -1000, -1000, 1277, -66, -1000, -1000, - -1000, -1000, -1000, -6, 908, -6, 757, -1000, 746, -1000, - -1000, -218, -1000, -1000, 1211, 1323, -1000, -1000, 1243, -1000, - -1000, -1000, 27823, 27823, -1000, -1000, 230, -1000, 279, 1034, - -1000, -173, -1000, -1000, 1565, 27823, -1000, -1000, 7715, -1000, - -1000, 1242, 1286, -1000, -1000, -1000, -1000, -1000, -1000, 1277, - -1000, 1494, -1000, -1000, 218, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 14140, 14140, 14140, 14140, 14140, 1579, 905, - 568, 14140, 14140, 19171, 27823, 27823, 17338, -6, 0, -1000, - 12775, 12775, 1511, -1000, 1241, -1000, 1170, 27823, 1241, 27823, - -1000, 1579, -1000, 568, 568, 27823, 568, 1579, -1000, -1000, - 467, -1000, 467, 1003, 1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1560, 1155, -1000, 228, 27823, -1000, 233, - -1000, -180, -181, 1240, 1032, 1153, -1000, 538, 27823, 27823, - -1000, -1000, -1000, 892, 892, 892, 892, 211, 881, -1000, - 892, 892, 1030, -1000, 1030, 1030, 460, -271, -1000, 1445, - 1420, 568, 1146, 1638, -1000, 1241, 1647, 436, 1134, -1000, - -1000, 1027, -1000, -1000, -1000, -1000, -1000, 1240, 1241, 1212, - -1000, -1000, -1000, 180, -1000, 7715, 5370, 1022, -1000, -1000, - -1000, -1000, -1000, 881, 161, -162, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 0, 287, -1000, 1403, 1420, -1000, 1593, - 1426, 1590, -1000, 27823, 1134, 27823, -1000, 180, 13230, 27823, - -1000, -56, -1000, -1000, -1000, -1000, -1000, 1283, -1000, 1366, - -130, -169, 1419, 1422, 1422, 1403, -1000, 1588, 1586, -1000, - 903, 1584, 898, 1120, -1000, -1000, 892, 881, 998, 309, - -1000, -1000, -159, -1000, 1359, -1000, 1417, 797, -1000, -1000, - -1000, -1000, 880, 879, -1000, 859, -1000, -1000, -1000, 1290, - 166, -1000, -160, -1000, 744, -1000, -1000, -1000, -1000, -1000, - 1289, -1000, 1631, -1000, -165, -1000, -1000, -1000, 1636, 425, - 425, -171, -1000, -1000, -1000, 304, 799, -1000, -1000, -1000, - -1000, -1000, + -1000, -1000, -1000, -332, 28476, 326, 130, 147, 28476, 28476, + 28476, 28476, 28476, 376, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 169, 28476, 28476, 28476, 28476, 367, -1000, -1000, 28476, + -1000, -1000, -1000, -1000, 765, 28476, -1000, -1000, 628, 628, + -1000, -1000, 28476, 628, -1000, -1000, -1000, -1000, -1000, -1000, + 628, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 902, -1000, 28476, 28476, -1000, + -1000, -1000, -1000, -1000, 98, -54, 205, -1000, -1000, -1000, + -1000, 1539, -1000, 765, 473, 547, 579, -1000, -1000, 741, + -1000, -1000, 2401, -1000, -1000, -1000, -1000, 714, 13883, 13883, + 13883, 1035, 2401, 2516, 1111, 1217, 442, 666, 666, 441, + 441, 441, 441, 441, 712, 712, -1000, -1000, -1000, -1000, + 933, -1000, -1000, -1000, 933, 10685, 10685, 1143, 1178, 408, + -1000, 1216, -1000, -1000, 1542, 1054, 1054, 755, 936, 639, + 1600, 1054, 620, 1596, 1054, 1054, 10685, -1000, -1000, 599, + -1000, 12518, 933, -1000, 1257, 1138, 1137, 1054, 933, 933, + 1054, 1054, 28476, -1000, -274, -1000, -86, 399, 1178, -1000, + 20734, -1000, -1000, 933, 1117, 1482, -1000, -1000, 1420, -1000, + 1371, 12518, 12518, 12518, -1000, -1000, -1000, 1482, 1575, -1000, + 1388, 1383, 1590, 10685, 20279, 1506, -1000, -1000, -1000, 406, + 1590, 1152, 1178, -1000, 28476, 20279, 20279, 20279, 20279, 20279, + -1000, 1349, 1348, -1000, 1336, 1335, 1343, 28476, -1000, 1067, + 1059, 18004, 208, 1102, 20279, 28476, -1000, -1000, 20279, 28476, + 6051, -1000, 1135, -47, -17, -1000, -1000, -1000, -1000, 765, + -1000, 882, -1000, 269, -1000, 270, -1000, -1000, -1000, -1000, + 573, 22, -1000, -1000, 29, 29, -1000, -1000, 437, 601, + 437, 437, 437, 900, 900, -1000, -1000, -1000, -1000, -1000, + 772, -1000, -1000, -1000, 746, -1000, -1000, 774, 1300, 143, + -1000, -1000, 491, 884, 1451, -1000, -1000, 971, 319, -1000, + 1521, 28476, -1000, 1308, 1305, 1302, -1000, -1000, -1000, -1000, + -1000, 307, 28476, 1063, -1000, 124, 28476, 968, 28476, -1000, + 1061, 28476, -1000, 964, -1000, -1000, 7458, -1000, 28476, 1178, + -1000, -1000, -1000, -1000, 348, 1487, 1483, 128, 124, 437, + 964, -1000, -1000, -1000, -1000, -1000, -335, 1057, 28476, 136, + -1000, 1209, 833, -1000, 1263, -1000, -1000, -1000, -1000, 108, + 185, 166, 309, -1000, 353, 1300, 28476, -1000, -1000, -1000, + -1000, 584, -1000, -1000, 584, -1000, -1000, -1000, -1000, -1000, + -1000, 1477, -68, -308, -1000, -305, -1000, -1000, -1000, -1000, + 1035, 2401, 2380, -1000, 13883, 13883, -1000, -1000, 1054, 1054, + 10685, 7458, 1576, 1482, -1000, -1000, 345, 538, 345, 13883, + 13883, -1000, 13883, 13883, -1000, -118, 1065, 546, -1000, 12518, + 777, -1000, -1000, 13883, 13883, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 331, 328, 310, 28476, -1000, -1000, + -1000, 782, 883, 1357, 765, 765, -1000, -1000, 28476, -1000, + -1000, -1000, -1000, 1587, 12518, -1000, 1130, -1000, 5582, 1542, + 1301, 28476, 1178, 1605, 15716, 28476, 1079, -1000, 492, 1399, + 1293, 1290, 1414, -1000, -1000, -1000, -1000, 1347, -1000, 1339, + -1000, -1000, -1000, -1000, -1000, 1059, 1590, 20279, 1077, -1000, + 1077, -1000, 403, -1000, -1000, -1000, -80, -82, -1000, -1000, + -1000, 2210, -1000, -1000, -1000, 637, 13883, 1613, -1000, 877, + 1502, -1000, 1497, -1000, -1000, 437, 437, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, 1049, -1000, 1046, 1129, 1043, 58, + -1000, 1161, 1472, 491, 491, -1000, 728, -1000, 964, -1000, + 28476, -1000, -1000, 28476, 28476, 28476, 1579, 1125, -1000, 28476, + -1000, -1000, 28476, -1000, -1000, 1382, 143, 1041, -1000, -1000, + -1000, 207, 28476, -1000, 921, 124, -1000, -1000, -1000, -1000, + -1000, -1000, 1184, -1000, -1000, -1000, 963, -1000, -127, 964, + 28476, 28476, 28476, -1000, 28476, -1000, -1000, -1000, 628, 628, + -1000, 1471, -1000, 964, -1000, 13883, 2401, 2401, -1000, -1000, + 933, -1000, 1542, -1000, 933, 1190, 1190, -1000, 1190, 1207, + -1000, 1190, 78, 1190, 73, 933, 933, 2481, 2418, 2145, + 846, 1178, -112, -1000, 765, 12518, 2128, 1288, 1178, 1178, + 1178, 1017, 875, 29, -1000, -1000, -1000, 1585, 1577, 765, + -1000, -1000, -1000, 1514, 1128, 1100, -1000, -1000, 10230, 1038, + 1378, 385, 1017, 1576, 28476, 12518, -1000, -1000, 12518, 1189, + -1000, 12518, -1000, -1000, -1000, 1576, 1576, 1077, -1000, -1000, + 375, -1000, -1000, -1000, -1000, -1000, 2401, -48, -1000, -1000, + -1000, -1000, -1000, 29, 870, 29, 710, -1000, 693, -1000, + -1000, -215, -1000, -1000, 1156, 1268, -1000, -1000, 1184, -1000, + -1000, -1000, 28476, 28476, -1000, -1000, 198, -1000, 254, 1015, + -1000, -173, -1000, -1000, 1529, 28476, -1000, -1000, 7458, -1000, + -1000, 1181, 1265, -1000, -1000, -1000, -1000, -1000, -1000, 2401, + -1000, 1482, -1000, -1000, 247, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 13883, 13883, 13883, 13883, 13883, 1542, 866, + 765, 13883, 13883, 17536, 19824, 19824, 17081, 29, -4, -1000, + 12518, 12518, 1496, -1000, 1178, -1000, 1034, 28476, 1178, 28476, + -1000, 1542, -1000, 765, 765, 28476, 765, 1542, -1000, -1000, + 437, -1000, 437, 939, 937, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 1528, 1125, -1000, 192, 28476, -1000, 207, + -1000, -179, -180, 1182, 1012, 1123, -1000, 490, 28476, 28476, + -1000, -1000, -1000, 1257, 1257, 1257, 1257, 122, 933, -1000, + 1257, 1257, 1003, -1000, -1000, -1000, 1003, 1003, 399, -267, + -1000, 1428, 1394, 765, 1117, 1608, -1000, 1178, 1605, 379, + 1100, -1000, -1000, 992, -1000, -1000, -1000, -1000, -1000, 1182, + 1178, 1060, -1000, -1000, -1000, 213, -1000, 7458, 5113, 990, + -1000, -1000, -1000, -1000, -1000, 933, 153, -151, -1000, -1000, + -1000, 19369, -1000, -1000, -1000, -1000, -4, 268, -1000, 1404, + 1394, -1000, 1574, 1412, 1572, -1000, 28476, 1100, 28476, -1000, + 213, 12973, 28476, -1000, -51, -1000, -1000, -1000, -1000, -1000, + 1263, -1000, 1355, -124, -161, -1000, -1000, 1402, 1408, 1408, + 1404, -1000, 1561, 1548, -1000, 859, 1547, 852, 997, -1000, + -1000, 1257, 933, 984, 272, -1000, -1000, -127, -1000, 1354, + -1000, 1392, 713, -1000, -1000, -1000, -1000, 849, 847, -1000, + 667, -1000, -1000, -1000, 1272, 148, -1000, -128, -1000, 646, + -1000, -1000, -1000, -1000, -1000, 1269, -1000, 1595, -1000, -157, + -1000, -1000, -1000, 1607, 496, 496, -171, -1000, -1000, -1000, + 263, 721, -1000, -1000, -1000, -1000, -1000, } var yyPgo = [...]int{ - 0, 1902, 1899, 32, 88, 85, 1898, 1897, 1896, 1894, - 131, 130, 129, 1891, 1889, 1888, 1886, 1885, 1884, 1883, - 1882, 1880, 1878, 1877, 1872, 65, 122, 37, 39, 126, - 1870, 1869, 53, 1868, 1866, 1864, 120, 116, 463, 1858, - 119, 1857, 1856, 1853, 1852, 1849, 1848, 1847, 1846, 1845, - 1842, 1838, 1837, 1836, 1835, 182, 1834, 1833, 5, 1832, - 56, 1831, 1829, 1828, 1823, 1822, 87, 1820, 1818, 1814, - 104, 1813, 1812, 48, 114, 51, 74, 1811, 1809, 76, - 814, 1808, 93, 128, 1807, 181, 1806, 42, 79, 69, - 1805, 44, 1804, 1803, 90, 1801, 1799, 1796, 67, 1794, - 1779, 3133, 1777, 66, 80, 20, 31, 1776, 1775, 1774, - 1773, 34, 450, 1772, 1771, 23, 1770, 1769, 145, 1767, - 86, 18, 1766, 16, 14, 21, 1761, 82, 1760, 11, - 58, 30, 1759, 83, 1758, 1756, 1755, 1754, 43, 1751, - 72, 107, 160, 1749, 1748, 7, 15, 1747, 1744, 1743, - 1742, 1741, 1737, 10, 1734, 2, 1731, 26, 1725, 17, - 22, 71, 47, 28, 8, 1724, 121, 1723, 27, 125, - 63, 109, 1722, 1721, 1720, 844, 140, 1717, 1716, 35, - 1715, 113, 124, 1714, 1486, 1713, 1712, 68, 1276, 2523, - 13, 111, 1711, 1709, 2164, 59, 78, 24, 1708, 75, - 1707, 1706, 1705, 127, 118, 50, 841, 46, 1704, 1703, - 1702, 1700, 1698, 1697, 1696, 133, 9, 19, 99, 29, - 1694, 1693, 1692, 61, 41, 1691, 108, 103, 64, 94, - 1690, 112, 106, 73, 1689, 40, 1687, 1686, 1685, 1684, - 45, 1683, 1681, 1680, 1679, 98, 89, 57, 36, 1678, - 38, 91, 102, 101, 1674, 25, 123, 12, 1673, 6, - 0, 1672, 3, 117, 1501, 115, 1671, 1670, 1, 1669, - 4, 1668, 1662, 81, 1661, 1660, 1659, 1658, 3249, 559, - 110, 1656, 134, + 0, 1897, 1896, 32, 83, 85, 1894, 1889, 1888, 1886, + 134, 133, 131, 1885, 1884, 1883, 1881, 1880, 1878, 1873, + 1866, 1858, 1857, 1852, 1848, 65, 123, 43, 37, 140, + 1847, 1846, 47, 1845, 1844, 1842, 126, 117, 439, 1841, + 119, 1840, 1839, 1838, 1837, 1835, 1834, 1828, 1827, 1822, + 1820, 1818, 1815, 1814, 1813, 144, 1812, 1811, 7, 1810, + 51, 1809, 1808, 1807, 1806, 1805, 89, 1803, 1802, 1801, + 114, 1800, 1797, 50, 416, 63, 73, 1795, 1787, 77, + 770, 1786, 106, 128, 1782, 898, 1779, 61, 78, 86, + 1778, 46, 1777, 1773, 90, 1771, 1769, 1765, 74, 1761, + 1760, 3185, 1759, 68, 76, 15, 27, 1753, 1752, 1747, + 1743, 34, 44, 1741, 1732, 23, 1731, 1726, 136, 1725, + 88, 18, 1724, 14, 13, 21, 1723, 87, 1722, 42, + 56, 31, 1717, 82, 1716, 1715, 1714, 1713, 57, 1711, + 79, 109, 30, 1710, 1709, 6, 11, 1708, 1707, 1706, + 1705, 1704, 1703, 10, 1702, 4, 1700, 28, 1699, 9, + 22, 17, 72, 118, 26, 8, 1698, 121, 1697, 29, + 122, 66, 107, 1695, 1694, 1692, 871, 141, 1691, 1690, + 35, 1689, 116, 127, 1687, 1450, 1686, 1685, 58, 1276, + 2643, 19, 113, 1684, 1683, 1891, 48, 80, 24, 1681, + 75, 1680, 1679, 1678, 132, 125, 69, 811, 53, 1677, + 1676, 1675, 1673, 1672, 1671, 1670, 135, 16, 20, 108, + 36, 1669, 1668, 1667, 67, 38, 1666, 105, 104, 71, + 94, 1664, 115, 99, 59, 1661, 40, 1656, 1654, 1653, + 1652, 41, 1651, 1649, 1648, 1646, 112, 98, 64, 45, + 1645, 39, 93, 101, 102, 1644, 25, 124, 12, 1643, + 3, 0, 1642, 5, 120, 1482, 103, 1641, 1638, 1, + 1637, 2, 1636, 1633, 81, 1632, 1631, 1630, 1628, 2492, + 340, 110, 1627, 129, } -//line sql.y:5200 +//line sql.y:5218 type yySymType struct { union interface{} empty struct{} @@ -4628,129 +4693,103 @@ func (st *yySymType) whensUnion() []*When { } var yyR1 = [...]int{ - 0, 276, 277, 277, 1, 1, 1, 1, 1, 1, + 0, 277, 278, 278, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 260, 260, 260, 263, 263, + 1, 1, 1, 1, 1, 261, 261, 261, 264, 264, 21, 50, 3, 3, 3, 3, 2, 2, 8, 9, 4, 5, 5, 10, 10, 62, 62, 11, 12, 12, - 12, 12, 280, 280, 96, 96, 94, 94, 95, 95, - 161, 161, 13, 14, 14, 171, 171, 170, 170, 170, - 172, 172, 172, 172, 206, 206, 15, 15, 15, 15, - 15, 71, 71, 262, 262, 261, 259, 259, 258, 258, - 257, 23, 24, 33, 33, 33, 33, 34, 35, 264, - 264, 236, 39, 39, 38, 38, 38, 38, 40, 40, - 37, 37, 36, 36, 238, 238, 225, 225, 237, 237, - 237, 237, 237, 237, 237, 224, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 208, 208, 208, - 208, 211, 211, 209, 209, 209, 209, 209, 209, 209, - 209, 209, 210, 210, 210, 210, 210, 212, 212, 212, - 212, 212, 213, 213, 213, 213, 213, 213, 213, 213, - 213, 213, 213, 213, 213, 213, 213, 214, 214, 214, - 214, 214, 214, 214, 214, 223, 223, 215, 215, 218, - 218, 219, 219, 219, 220, 220, 221, 221, 216, 216, - 216, 216, 217, 217, 217, 226, 250, 250, 249, 249, - 247, 247, 247, 247, 235, 235, 244, 244, 244, 244, - 244, 234, 234, 230, 230, 230, 231, 231, 232, 232, - 229, 229, 233, 233, 246, 246, 245, 227, 227, 228, - 228, 252, 252, 252, 252, 253, 269, 270, 268, 268, - 268, 268, 268, 60, 60, 60, 183, 183, 183, 242, - 242, 241, 241, 241, 243, 243, 240, 240, 240, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, - 240, 240, 240, 240, 240, 178, 178, 178, 267, 267, - 267, 267, 267, 267, 266, 266, 266, 239, 239, 239, - 265, 265, 130, 130, 131, 131, 30, 30, 30, 30, + 12, 12, 281, 281, 96, 96, 94, 94, 95, 95, + 162, 162, 13, 14, 14, 172, 172, 171, 171, 171, + 173, 173, 173, 173, 207, 207, 15, 15, 15, 15, + 15, 71, 71, 263, 263, 262, 260, 260, 259, 259, + 258, 23, 24, 33, 33, 33, 33, 34, 35, 265, + 265, 237, 39, 39, 38, 38, 38, 38, 40, 40, + 37, 37, 36, 36, 239, 239, 226, 226, 238, 238, + 238, 238, 238, 238, 238, 225, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 209, 209, 209, + 209, 212, 212, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 211, 211, 211, 211, 211, 213, 213, 213, + 213, 213, 214, 214, 214, 214, 214, 214, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 215, 215, 215, + 215, 215, 215, 215, 215, 224, 224, 216, 216, 219, + 219, 220, 220, 220, 221, 221, 222, 222, 217, 217, + 217, 217, 218, 218, 218, 227, 251, 251, 250, 250, + 248, 248, 248, 248, 236, 236, 245, 245, 245, 245, + 245, 235, 235, 231, 231, 231, 232, 232, 233, 233, + 230, 230, 234, 234, 247, 247, 246, 228, 228, 229, + 229, 253, 253, 253, 253, 254, 270, 271, 269, 269, + 269, 269, 269, 60, 60, 60, 184, 184, 184, 243, + 243, 242, 242, 242, 244, 244, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, + 241, 241, 241, 241, 241, 179, 179, 179, 268, 268, + 268, 268, 268, 268, 267, 267, 267, 240, 240, 240, + 266, 266, 130, 130, 131, 131, 30, 30, 30, 30, 30, 30, 29, 29, 29, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 31, 31, 26, 26, 26, 26, 26, 26, 26, 26, 26, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 222, - 222, 222, 254, 254, 255, 255, 17, 22, 22, 18, + 16, 16, 16, 16, 16, 16, 16, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 223, + 223, 223, 255, 255, 256, 256, 17, 22, 22, 18, 18, 18, 18, 19, 19, 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 271, 271, 177, 177, 185, 185, 176, 176, 199, 199, - 199, 179, 179, 179, 180, 180, 275, 275, 275, 43, - 43, 45, 45, 46, 47, 47, 201, 201, 202, 202, + 272, 272, 178, 178, 186, 186, 177, 177, 200, 200, + 200, 180, 180, 180, 181, 181, 276, 276, 276, 43, + 43, 45, 45, 46, 47, 47, 202, 202, 203, 203, 48, 49, 61, 61, 61, 61, 61, 61, 63, 63, 63, 7, 7, 7, 7, 57, 57, 57, 6, 6, - 44, 44, 51, 272, 272, 273, 274, 274, 274, 274, + 44, 44, 51, 273, 273, 274, 275, 275, 275, 275, 52, 54, 20, 20, 20, 20, 20, 20, 78, 78, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 72, 72, 72, 67, 67, 281, 55, 56, + 66, 66, 72, 72, 72, 67, 67, 282, 55, 56, 56, 70, 70, 70, 64, 64, 64, 69, 69, 69, 75, 75, 77, 77, 77, 77, 77, 79, 79, 79, 79, 79, 79, 79, 74, 74, 76, 76, 76, 76, - 192, 192, 192, 191, 191, 86, 86, 87, 87, 88, + 193, 193, 193, 192, 192, 86, 86, 87, 87, 88, 88, 89, 89, 89, 128, 104, 104, 160, 160, 159, - 159, 162, 162, 90, 90, 90, 90, 91, 91, 92, - 92, 93, 93, 200, 200, 197, 197, 197, 196, 196, - 97, 97, 97, 99, 98, 98, 98, 98, 100, 100, - 102, 102, 101, 101, 103, 105, 105, 105, 105, 105, - 106, 106, 85, 85, 85, 85, 85, 85, 85, 85, - 174, 174, 108, 108, 107, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 119, 119, 119, 119, 119, 119, - 109, 109, 109, 109, 109, 109, 109, 73, 73, 120, - 120, 120, 127, 121, 121, 112, 112, 112, 112, 112, + 159, 161, 161, 161, 161, 163, 163, 90, 90, 90, + 90, 91, 91, 92, 92, 93, 93, 201, 201, 198, + 198, 198, 197, 197, 97, 97, 97, 99, 98, 98, + 98, 98, 100, 100, 102, 102, 101, 101, 103, 105, + 105, 105, 105, 105, 106, 106, 85, 85, 85, 85, + 85, 85, 85, 85, 175, 175, 108, 108, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 119, 119, + 119, 119, 119, 119, 109, 109, 109, 109, 109, 109, + 109, 73, 73, 120, 120, 120, 127, 121, 121, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 116, - 116, 116, 116, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, - 115, 115, 115, 282, 282, 118, 117, 117, 117, 117, - 117, 117, 117, 68, 68, 68, 68, 68, 205, 205, - 205, 207, 207, 207, 207, 207, 207, 207, 207, 207, - 207, 207, 207, 207, 134, 134, 65, 65, 132, 132, - 133, 135, 135, 129, 129, 129, 111, 111, 111, 111, - 111, 111, 111, 111, 113, 113, 113, 136, 136, 137, - 137, 138, 138, 139, 139, 140, 141, 141, 141, 142, - 142, 142, 142, 32, 32, 32, 32, 32, 27, 27, - 27, 27, 28, 28, 28, 80, 80, 80, 80, 82, - 82, 81, 81, 58, 58, 59, 59, 59, 83, 83, - 84, 84, 84, 84, 157, 157, 157, 143, 143, 143, - 143, 149, 149, 149, 145, 145, 147, 147, 147, 148, - 148, 148, 146, 154, 154, 156, 156, 155, 155, 151, - 151, 152, 152, 153, 153, 153, 150, 150, 110, 110, - 110, 110, 110, 158, 158, 158, 158, 163, 163, 123, - 123, 125, 125, 124, 126, 164, 164, 168, 165, 165, - 169, 169, 169, 169, 169, 166, 166, 167, 167, 193, - 193, 193, 173, 173, 184, 184, 181, 181, 182, 182, - 175, 175, 186, 186, 186, 53, 122, 122, 251, 251, - 248, 189, 189, 190, 190, 194, 194, 198, 198, 195, - 195, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 187, 187, - 187, 187, 187, 187, 187, 187, 187, 187, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 116, 116, 116, 116, 114, 114, 114, + 114, 114, 114, 114, 114, 114, 114, 114, 114, 114, + 114, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 283, 283, 118, + 117, 117, 117, 117, 117, 117, 117, 68, 68, 68, + 68, 68, 206, 206, 206, 208, 208, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 134, 134, + 65, 65, 132, 132, 133, 135, 135, 129, 129, 129, + 111, 111, 111, 111, 111, 111, 111, 111, 113, 113, + 113, 136, 136, 137, 137, 138, 138, 139, 139, 140, + 141, 141, 141, 142, 142, 142, 142, 32, 32, 32, + 32, 32, 27, 27, 27, 27, 28, 28, 28, 80, + 80, 80, 80, 82, 82, 81, 81, 58, 58, 59, + 59, 59, 83, 83, 84, 84, 84, 84, 157, 157, + 157, 143, 143, 143, 143, 149, 149, 149, 145, 145, + 147, 147, 147, 148, 148, 148, 146, 154, 154, 156, + 156, 155, 155, 151, 151, 152, 152, 153, 153, 153, + 150, 150, 110, 110, 110, 110, 110, 158, 158, 158, + 158, 164, 164, 123, 123, 125, 125, 124, 126, 165, + 165, 169, 166, 166, 170, 170, 170, 170, 170, 167, + 167, 168, 168, 194, 194, 194, 174, 174, 185, 185, + 182, 182, 183, 183, 176, 176, 187, 187, 187, 53, + 122, 122, 252, 252, 249, 190, 190, 191, 191, 195, + 195, 199, 199, 196, 196, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, @@ -4764,7 +4803,34 @@ var yyR1 = [...]int{ 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, - 188, 188, 188, 188, 278, 279, 203, 204, 204, 204, + 188, 188, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 279, 280, + 204, 205, 205, 205, } var yyR2 = [...]int{ @@ -4829,41 +4895,42 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 3, 1, 2, 3, 5, 0, 1, 2, 1, 1, 0, 2, 1, 3, 1, 1, 1, 3, 3, 3, 3, 7, 0, 3, 1, - 3, 1, 3, 4, 4, 4, 3, 2, 4, 0, - 1, 0, 2, 0, 1, 0, 1, 2, 1, 1, - 1, 2, 2, 1, 2, 3, 2, 3, 2, 2, - 2, 1, 1, 3, 3, 0, 5, 4, 5, 5, - 0, 2, 1, 3, 3, 3, 2, 3, 1, 2, - 0, 3, 1, 1, 3, 3, 4, 4, 5, 3, - 4, 5, 6, 2, 1, 2, 1, 2, 1, 2, - 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, - 1, 1, 3, 1, 3, 1, 1, 1, 1, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 3, 1, 1, 1, 1, 4, - 5, 5, 6, 4, 4, 6, 6, 6, 8, 8, - 8, 8, 9, 8, 5, 4, 2, 2, 2, 2, + 3, 1, 1, 3, 3, 1, 3, 4, 4, 4, + 3, 2, 4, 0, 1, 0, 2, 0, 1, 0, + 1, 2, 1, 1, 1, 2, 2, 1, 2, 3, + 2, 3, 2, 2, 2, 1, 1, 3, 3, 0, + 5, 4, 5, 5, 0, 2, 1, 3, 3, 3, + 2, 3, 1, 2, 0, 3, 1, 1, 3, 3, + 4, 4, 5, 3, 4, 5, 6, 2, 1, 2, + 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, + 1, 0, 2, 1, 1, 1, 3, 1, 3, 1, + 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 3, 1, + 1, 1, 1, 4, 5, 5, 6, 4, 4, 6, + 6, 6, 8, 8, 8, 8, 9, 8, 5, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 8, 8, 0, 2, 3, 4, 4, 4, 4, - 4, 4, 4, 0, 3, 4, 7, 3, 1, 1, - 1, 2, 3, 3, 1, 2, 2, 1, 2, 1, - 2, 2, 1, 2, 0, 1, 0, 2, 1, 2, - 4, 0, 2, 1, 3, 5, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 2, 2, 0, 3, 0, - 2, 0, 3, 1, 3, 2, 0, 1, 1, 0, - 2, 4, 4, 0, 2, 2, 1, 1, 3, 3, - 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, - 3, 1, 1, 0, 4, 0, 1, 1, 0, 3, - 1, 3, 2, 1, 0, 2, 4, 0, 9, 3, - 5, 0, 3, 3, 0, 1, 0, 2, 2, 0, - 2, 2, 2, 0, 2, 1, 2, 3, 3, 0, - 2, 1, 2, 3, 4, 3, 0, 1, 2, 1, - 5, 4, 4, 1, 3, 3, 5, 0, 5, 1, - 3, 1, 2, 3, 1, 1, 3, 3, 1, 3, - 3, 3, 3, 3, 2, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 0, 2, 0, 3, - 0, 1, 0, 1, 1, 5, 0, 1, 0, 1, - 2, 1, 1, 1, 1, 1, 1, 0, 1, 1, + 2, 2, 2, 2, 2, 8, 8, 0, 2, 3, + 4, 4, 4, 4, 4, 4, 4, 0, 3, 4, + 7, 3, 1, 1, 1, 2, 3, 3, 1, 2, + 2, 1, 2, 1, 2, 2, 1, 2, 0, 1, + 0, 2, 1, 2, 4, 0, 2, 1, 3, 5, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 0, 3, 0, 2, 0, 3, 1, 3, 2, + 0, 1, 1, 0, 2, 4, 4, 0, 2, 2, + 1, 1, 3, 3, 3, 3, 3, 3, 3, 0, + 3, 3, 3, 0, 3, 1, 1, 0, 4, 0, + 1, 1, 0, 3, 1, 3, 2, 1, 0, 2, + 4, 0, 9, 3, 5, 0, 3, 3, 0, 1, + 0, 2, 2, 0, 2, 2, 2, 0, 2, 1, + 2, 3, 3, 0, 2, 1, 2, 3, 4, 3, + 0, 1, 2, 1, 5, 4, 4, 1, 3, 3, + 5, 0, 5, 1, 3, 1, 2, 3, 1, 1, + 3, 3, 1, 3, 3, 3, 3, 3, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 0, 2, 0, 3, 0, 1, 0, 1, 1, 5, + 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -4904,29 +4971,29 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, + 0, 0, 1, 1, } var yyChk = [...]int{ - -1000, -276, -1, -3, -8, -9, -10, -11, -12, -13, + -1000, -277, -1, -3, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, -41, -42, -43, -45, -46, -47, -48, -49, -6, -44, -20, -21, -50, -51, - -52, -53, -54, -4, -278, 6, 7, 8, -62, 10, + -52, -53, -54, -4, -279, 6, 7, 8, -62, 10, 11, 31, -23, -33, 153, -34, -24, 154, -35, 156, 155, 192, 157, 185, 71, 231, 232, 234, 235, 236, 237, -63, 190, 191, 159, 35, 42, 32, 33, 36, - 162, 81, 9, 334, 187, 186, 26, -277, 474, -70, - 5, -138, 16, -3, -55, -281, -55, -55, -55, -55, - -55, -55, -236, -238, 81, 126, 81, -71, -184, 165, - 174, 173, 170, -264, 107, 220, 325, 163, -39, -38, - -37, -36, -40, 30, -30, -31, -256, -29, -26, 158, + 162, 81, 9, 334, 187, 186, 26, -278, 474, -70, + 5, -138, 16, -3, -55, -282, -55, -55, -55, -55, + -55, -55, -237, -239, 81, 126, 81, -71, -185, 165, + 174, 173, 170, -265, 107, 220, 325, 163, -39, -38, + -37, -36, -40, 30, -30, -31, -257, -29, -26, 158, 155, 200, 102, 103, 192, 193, 194, 157, 176, 191, - 195, 190, 209, -25, 77, 32, 347, 350, -243, 154, - 160, 161, 335, 105, 104, 72, 156, -240, 281, 451, + 195, 190, 209, -25, 77, 32, 347, 350, -244, 154, + 160, 161, 335, 105, 104, 72, 156, -241, 281, 451, -40, 453, 95, 97, 452, 41, 165, 454, 455, 456, 457, 175, 458, 459, 460, 461, 467, 468, 469, 470, - 106, 5, 164, -264, -80, 291, 227, 77, -198, -194, - -260, -188, 84, 85, 86, 344, 178, 378, 379, 225, + 106, 5, 164, -265, -80, 291, 227, 77, -199, -195, + -261, -189, 84, 85, 86, 344, 178, 378, 379, 225, 77, 281, 451, 231, 245, 239, 266, 258, 345, 380, 228, 179, 213, 448, 256, 312, 453, 381, 193, 304, 286, 294, 95, 234, 321, 466, 230, 382, 464, 97, @@ -4953,24 +5020,24 @@ var yyChk = [...]int{ 308, 192, 431, 322, 217, 284, 352, 209, 310, 446, 351, 260, 257, 211, 432, 166, 205, 206, 433, 436, 300, 290, 301, 302, 227, 303, 291, 212, 350, 255, - 285, 164, -184, 165, 166, -264, 164, -101, -194, 164, - -166, 286, -185, 287, 288, 299, 300, 306, -177, 307, - 305, 203, -275, 313, 164, 308, 153, 144, 296, 297, - 290, 303, 291, 212, -271, -260, 456, 471, 312, 259, - 292, 298, 314, 438, 302, 301, -194, 233, -201, 238, - -189, -260, -188, 236, -101, -61, 434, 157, -203, -203, + 285, 164, -185, 165, 166, -265, 164, -101, -195, 164, + -167, 286, -186, 287, 288, 299, 300, 306, -178, 307, + 305, 203, -276, 313, 164, 308, 153, 144, 296, 297, + 290, 303, 291, 212, -272, -261, 456, 471, 312, 259, + 292, 298, 314, 438, 302, 301, -195, 233, -202, 238, + -190, -261, -189, 236, -101, -61, 434, 157, -204, -204, -72, 438, 440, -121, -85, -107, 110, -112, 30, 24, -111, -108, -129, -126, -127, 144, 145, 147, 146, 148, 133, 134, 141, 111, 149, -116, -114, -115, -117, 88, - 87, 96, 89, 90, 91, 92, 98, 99, 100, -189, - -194, -124, -278, 65, 66, 335, 336, 337, 338, 343, + 87, 96, 89, 90, 91, 92, 98, 99, 100, -190, + -195, -124, -279, 65, 66, 335, 336, 337, 338, 343, 339, 113, 54, 330, 324, 333, 332, 331, 328, 329, - 326, 327, 341, 342, 169, 325, 163, 139, 334, -260, - -188, 41, 289, 289, -101, 227, -5, -4, -278, 6, - 21, 22, -142, 18, 17, -279, 83, -64, -77, 60, + 326, 327, 341, 342, 169, 325, 163, 139, 334, -261, + -189, 41, 289, 289, -101, 227, -5, -4, -279, 6, + 21, 22, -142, 18, 17, -280, 83, -64, -77, 60, 61, -79, 22, 37, 64, 62, 21, -56, -76, 135, - -85, -194, -76, -175, 168, -175, -175, -165, -206, 233, - -169, 314, 313, -190, -167, -189, -187, -166, 311, 158, + -85, -195, -76, -176, 168, -176, -176, -166, -207, 233, + -170, 314, 313, -191, -168, -190, -188, -167, 311, 158, 353, 109, 23, 25, 112, 144, 17, 113, 36, 160, 259, 176, 143, 172, 335, 153, 69, 354, 326, 327, 324, 330, 337, 338, 325, 287, 30, 11, 356, 26, @@ -4984,282 +5051,282 @@ var yyChk = [...]int{ 127, 156, 334, 66, 375, 163, 288, 6, 340, 31, 185, 173, 64, 376, 164, 115, 341, 342, 167, 99, 5, 170, 33, 10, 71, 74, 331, 332, 333, 54, - 347, 114, 13, 377, 318, 108, 312, -237, 126, -224, - -228, -189, 180, -253, 176, -101, -246, -245, -189, -80, - 164, -260, 165, 165, 165, -55, 334, -36, -37, -166, - 143, 197, 82, 82, -228, -227, -226, -265, 199, 180, - -252, -244, 172, 181, -234, 173, 174, -229, 165, 29, - -265, -229, 171, 181, 199, 199, 106, 199, 106, 199, - 199, 199, 199, 199, 199, 199, 199, 199, 196, -235, - 118, -235, 351, 351, -240, -265, -265, -265, 167, 34, - 34, -186, -229, 167, 23, -235, -235, -166, 143, -235, - -235, -235, -235, 207, 207, -235, -235, -235, -235, -235, - -235, -235, -235, -235, -235, -235, -235, -235, -235, -235, + 347, 114, 13, 377, 318, 108, 312, -238, 126, -225, + -229, -190, 180, -254, 176, -101, -247, -246, -190, -80, + 164, -261, 165, 165, 165, -55, 334, -36, -37, -167, + 143, 197, 82, 82, -229, -228, -227, -266, 199, 180, + -253, -245, 172, 181, -235, 173, 174, -230, 165, 29, + -266, -230, 171, 181, 199, 199, 106, 199, 106, 199, + 199, 199, 199, 199, 199, 199, 199, 199, 196, -236, + 118, -236, 351, 351, -241, -266, -266, -266, 167, 34, + 34, -187, -230, 167, 23, -236, -236, -167, 143, -236, + -236, -236, -236, 207, 207, -236, -236, -236, -236, -236, + -236, -236, -236, -236, -236, -236, -236, -236, -236, -236, -101, -83, 214, 153, 155, 158, 73, 88, 228, 118, - -38, 209, -22, -101, 164, -260, -181, 169, -55, -101, - 150, -101, -179, 126, 13, -179, -176, 289, 293, 294, - 295, -179, -179, -179, -179, 210, 304, -230, 165, 34, - 177, 289, 210, 304, 210, 211, 210, 211, 210, -199, + -38, 209, -22, -101, 164, -261, -182, 169, -55, -101, + 150, -101, -180, 126, 13, -180, -177, 289, 293, 294, + 295, -180, -180, -180, -180, 210, 304, -231, 165, 34, + 177, 289, 210, 304, 210, 211, 210, 211, 210, -200, 12, 128, 325, 309, 306, 203, 164, 204, 166, 310, - -260, 441, 211, -199, 289, 206, -179, -204, -278, -190, - 259, -204, -204, 31, 167, -189, -57, -189, 88, -7, + -261, 441, 211, -200, 289, 206, -180, -205, -279, -191, + 259, -205, -205, 31, 167, -190, -57, -190, 88, -7, -3, -11, -10, -12, 118, -78, 289, -66, 144, 456, 442, 443, 444, 441, 305, 449, 447, 445, 210, 446, 82, 109, 107, 108, 125, -85, -109, 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, -174, -278, -127, -278, 151, 152, -112, -112, - -112, -112, -112, -112, -112, -112, -112, -112, -278, 150, - -2, -121, -4, -278, -278, -278, -278, -278, -278, -278, - -278, -134, -85, -278, -282, -278, -282, -118, -278, -282, - -118, -282, -118, -282, -282, -118, -282, -118, -282, -282, - -118, -278, -278, -278, -278, -278, -278, -278, -203, -272, - -273, -104, -101, -278, 88, -138, -3, -55, -157, 20, + 123, 124, -175, -279, -127, -279, 151, 152, -112, -112, + -112, -112, -112, -112, -112, -112, -112, -112, -279, 150, + -2, -121, -4, -279, -279, -279, -279, -279, -279, -279, + -279, -134, -85, -279, -283, -279, -283, -118, -279, -283, + -118, -283, -118, -283, -283, -118, -283, -118, -283, -283, + -118, -279, -279, -279, -279, -279, -279, -279, -204, -273, + -274, -104, -101, -279, 88, -138, -3, -55, -157, 20, 32, -85, -139, -140, -85, -138, 56, -74, -76, -79, - 60, 61, 94, 12, -192, -191, 23, -189, 88, 150, + 60, 61, 94, 12, -193, -192, 23, -190, 88, 150, 12, -102, 27, -101, -87, -88, -89, -90, -104, -128, - -278, 12, -94, -95, -101, -103, -194, 82, 233, -169, - -206, -171, -170, 315, 317, 118, -193, -189, 88, 30, - 83, 82, -101, -208, -211, -213, -212, -214, -209, -210, + -279, 12, -94, -95, -101, -103, -195, 82, 233, -170, + -207, -172, -171, 315, 317, 118, -194, -190, 88, 30, + 83, 82, -101, -209, -212, -214, -213, -215, -210, -211, 256, 257, 144, 260, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 31, 188, 252, 253, 254, 255, 272, 273, 274, 275, 276, 277, 278, 279, 239, 258, 345, 240, 241, 242, 243, 244, 245, 247, 248, 249, - 250, 251, -263, -260, 81, 83, 82, -215, 81, -83, - -182, 169, -251, -248, 74, -260, -260, -260, -182, -235, - -235, 196, -29, -26, -256, 16, -25, -26, 158, 102, - 103, 155, 81, -224, 81, -233, -263, -260, 81, 29, - 171, 170, -232, -229, -232, -233, -260, -129, -189, -194, - -260, 29, 29, -162, -189, -162, -162, 21, -162, 21, - -162, 21, 89, -189, -162, 21, -162, 21, -162, 21, - -162, 21, -162, 21, 30, 75, 76, 30, 78, 79, - 80, -129, -129, -224, -166, -101, -260, 89, 89, -235, - -235, 89, 88, 88, 88, -235, -235, 89, 88, -260, - 88, -266, 182, 224, 226, 89, 89, 89, 89, 30, - 88, -267, 30, 463, 462, 464, 465, 466, 89, 30, - 89, 30, 89, -189, 81, -82, 216, 118, 205, 205, + 250, 251, -264, -261, 81, 83, 82, -216, 81, -83, + -183, 169, -252, -249, 74, -261, -261, -261, -183, -236, + -236, 196, -29, -26, -257, 16, -25, -26, 158, 102, + 103, 155, 81, -225, 81, -234, -264, -261, 81, 29, + 171, 170, -233, -230, -233, -234, -261, -129, -190, -195, + -261, 29, 29, -163, -190, -163, -163, 21, -163, 21, + -163, 21, 89, -190, -163, 21, -163, 21, -163, 21, + -163, 21, -163, 21, 30, 75, 76, 30, 78, 79, + 80, -129, -129, -225, -167, -101, -261, 89, 89, -236, + -236, 89, 88, 88, 88, -236, -236, 89, 88, -261, + 88, -267, 182, 224, 226, 89, 89, 89, 89, 30, + 88, -268, 30, 463, 462, 464, 465, 466, 89, 30, + 89, 30, 89, -190, 81, -82, 216, 118, 205, 205, 164, 164, 218, -101, 229, 230, 228, 21, 217, 219, - 221, 41, 82, 167, -181, 73, -96, -101, 24, -181, - -195, -194, -187, 88, -85, -231, 12, 128, -199, -199, - -179, -101, -231, -199, -179, -101, -179, -179, -179, -179, - -199, -179, -194, -194, -101, -101, -101, -101, -101, -101, - -101, -204, -204, -204, -180, 126, -179, 73, -202, 236, + 221, 41, 82, 167, -182, 73, -96, -101, 24, -182, + -196, -195, -188, 88, -85, -232, 12, 128, -200, -200, + -180, -101, -232, -200, -180, -101, -180, -180, -180, -180, + -200, -180, -195, -195, -101, -101, -101, -101, -101, -101, + -101, -205, -205, -205, -181, 126, -180, 73, -203, 236, 270, 435, 436, 437, 82, 347, -94, 441, 441, 441, 441, 441, 441, -85, -85, -85, -85, -119, 98, 110, 99, 100, -112, -120, -124, -127, 93, 128, 126, 127, 112, -112, -112, -112, -112, -112, -112, -112, -112, -112, - -112, -112, -112, -112, -112, -112, -205, -260, 88, 144, - -260, -111, -111, -189, -75, 22, 37, -74, -190, -195, - -187, -70, -279, -279, -138, -74, -74, -85, -85, -129, + -112, -112, -112, -112, -112, -112, -206, -261, 88, 144, + -261, -111, -111, -190, -75, 22, 37, -74, -191, -196, + -188, -70, -280, -280, -138, -74, -74, -85, -85, -129, 88, -74, -129, 88, -74, -74, -69, 22, 37, -132, - -133, 114, -129, -279, -112, -189, -189, -74, -75, -75, - -74, -74, 82, -274, 317, 318, 439, -197, 199, -196, - 23, -194, 88, -122, -121, -142, -279, -143, 27, 10, - 128, 82, 19, 82, -141, 25, 26, -142, -113, -189, - 89, 92, -86, 82, 12, -79, -101, -191, 135, -195, - -101, -161, 199, -101, 31, 82, -97, -99, -98, -100, - 63, 67, 69, 64, 65, 66, 70, -200, 23, -87, - -3, -278, -101, -94, -280, 82, 12, 74, -280, 82, - 150, -169, -171, 82, 316, 318, 319, 73, 101, -85, - -217, 143, -242, -241, -240, -224, -226, -227, -228, 83, - -144, -220, 284, -215, -215, -215, -215, -215, -216, -166, - -216, -216, -216, 81, 81, -215, -215, -215, -215, -218, - 81, -218, -218, -219, 81, -219, -253, -85, -250, -249, - -247, -248, 175, 95, 347, -245, -141, 89, -82, -101, - 110, 73, -189, -251, -251, -251, -194, -260, 88, -260, - 88, 82, 17, -225, -224, -130, 224, -255, 199, -252, - -246, 81, 29, -232, -233, -233, 150, -260, 82, 27, - 106, 106, 106, 106, 347, 155, 31, -224, -130, -205, - 167, -205, -205, 88, 88, -178, 471, -94, 166, 223, + -133, 114, -129, -280, -112, -190, -190, -74, -75, -75, + -74, -74, 82, -275, 317, 318, 439, -198, 199, -197, + 23, -195, 88, -122, -121, -142, -280, -143, 27, 10, + 128, 82, 19, 82, -141, 25, 26, -142, -113, -190, + 89, 92, -86, 82, 12, -79, -101, -192, 135, -196, + -101, -162, 199, -101, 31, 82, -97, -99, -98, -100, + 63, 67, 69, 64, 65, 66, 70, -201, 23, -87, + -3, -279, -101, -94, -281, 82, 12, 74, -281, 82, + 150, -170, -172, 82, 316, 318, 319, 73, 101, -85, + -218, 143, -243, -242, -241, -225, -227, -228, -229, 83, + -144, -221, 284, -216, -216, -216, -216, -216, -217, -167, + -217, -217, -217, 81, 81, -216, -216, -216, -216, -219, + 81, -219, -219, -220, 81, -220, -254, -85, -251, -250, + -248, -249, 175, 95, 347, -246, -141, 89, -82, -101, + 110, 73, -190, -252, -252, -252, -195, -261, 88, -261, + 88, 82, 17, -226, -225, -130, 224, -256, 199, -253, + -247, 81, 29, -233, -234, -234, 150, -261, 82, 27, + 106, 106, 106, 106, 347, 155, 31, -225, -130, -206, + 167, -206, -206, 88, 88, -179, 471, -94, 166, 223, -84, 330, 88, 84, -101, -101, -101, -101, -101, 158, 155, 207, -101, -101, -94, -101, 82, -60, 184, 179, - -194, -101, -179, -179, -101, -179, -179, 88, -101, -189, + -195, -101, -180, -180, -101, -180, -180, 88, -101, -190, -66, 317, 347, 20, -67, 20, 98, 99, 100, -120, - -112, -112, -112, -73, 189, 109, -279, -279, -74, -74, - -278, 150, -5, -142, -279, -279, 82, 74, 23, 12, - 12, -279, 12, 12, -279, -279, -74, -135, -133, 116, - -85, -279, -279, 82, 82, -279, -279, -279, -279, -279, - -273, 438, 318, -105, 71, 168, 72, -278, -196, -279, - -157, 39, 47, 58, -85, -85, -140, -157, -173, 20, + -112, -112, -112, -73, 189, 109, -280, -280, -74, -74, + -279, 150, -5, -142, -280, -280, 82, 74, 23, 12, + 12, -280, 12, 12, -280, -280, -74, -135, -133, 116, + -85, -280, -280, 82, 82, -280, -280, -280, -280, -280, + -274, 438, 318, -105, 71, 168, 72, -279, -197, -280, + -157, 39, 47, 58, -85, -85, -140, -157, -174, 20, 12, 54, 54, -106, 13, -76, -87, -79, 150, -106, - -110, 31, 54, -3, -278, -278, -164, -168, -129, -88, + -110, 31, 54, -3, -279, -279, -165, -169, -129, -88, -89, -89, -88, -89, 63, 63, 63, 68, 63, 68, - 63, -98, -194, -279, -279, -3, -161, 74, -87, -101, - -87, -103, -194, 135, -170, -172, 320, 317, 323, -260, - 88, 82, -240, -228, 98, 110, 30, 73, 281, 95, - 171, 29, 170, -221, 285, -216, -216, -217, -260, 88, - 144, -217, -217, -217, -223, 88, -223, 89, 89, 83, - -32, -27, -28, 32, 77, -247, -235, 88, 38, 83, - 166, 24, -101, 73, 73, 73, 16, -159, -189, 82, - 83, -131, 225, -129, 83, -189, 83, -159, -233, -190, - -189, -278, 164, 30, 30, -130, -131, -217, -260, 473, - 472, 83, -101, -81, 214, 222, 81, 85, -262, 74, - 205, 281, 205, 208, 167, -60, -32, -101, -199, -199, - 32, 317, 450, 448, -73, 109, -112, -112, -279, -279, - -75, -190, -138, -157, -207, 144, 256, 188, 254, 250, - 270, 261, 283, 252, 284, -205, -207, -112, -112, -112, + 63, -98, -195, -280, -280, -3, -162, 74, -87, -101, + -87, -103, -195, 135, -171, -173, 320, 317, 323, -261, + 88, 82, -241, -229, 98, 110, 30, 73, 281, 95, + 171, 29, 170, -222, 285, -217, -217, -218, -261, 88, + 144, -218, -218, -218, -224, 88, -224, 89, 89, 83, + -32, -27, -28, 32, 77, -248, -236, 88, 38, 83, + 166, 24, -101, 73, 73, 73, 16, -159, -190, 82, + 83, -131, 225, -129, 83, -190, 83, -159, -234, -191, + -190, -279, 164, 30, 30, -130, -131, -218, -261, 473, + 472, 83, -101, -81, 214, 222, 81, 85, -263, 74, + 205, 281, 205, 208, 167, -60, -32, -101, -200, -200, + 32, 317, 450, 448, -73, 109, -112, -112, -280, -280, + -75, -191, -138, -157, -208, 144, 256, 188, 254, 250, + 270, 261, 283, 252, 284, -206, -208, -112, -112, -112, -112, 344, -138, 117, -85, 115, -112, -112, 165, 165, - 165, -162, 40, 88, 88, 59, -101, -136, 14, -85, - 135, -142, -163, 73, -164, -123, -125, -124, -278, -158, - -279, -189, -162, -106, 82, 118, -92, -91, 73, 74, - -93, 73, -91, 63, 63, -279, -106, -87, -106, -106, - 150, 317, 321, 322, -240, 98, -112, 10, 88, 29, - 29, -217, -217, 83, 82, 83, 82, 83, 82, -183, - 384, 110, -28, -27, -235, -235, 89, -260, -101, -101, - -101, -101, 17, 82, -224, -129, 54, -250, 83, -254, - -255, -101, -111, -131, -160, 81, 83, -259, 347, -261, - -260, -189, -189, -189, -101, -179, -179, 32, -260, -112, - -279, -142, -279, -215, -215, -215, -219, -215, 244, -215, - 244, -279, -279, 20, 20, 20, 20, -278, -65, 340, - -85, 82, 82, -278, -278, -278, -279, 88, -216, -137, - 15, 17, 28, -163, 82, -279, -279, 82, 54, 150, - -279, -138, -168, -85, -85, 81, -85, -138, -106, -115, - -216, 88, -216, 89, 89, 384, 30, 78, 79, 80, - 30, 75, 76, -160, -159, -189, 201, 183, -279, 82, - -222, 347, 350, 23, -159, -258, -257, -190, 81, 74, - -157, -216, -260, -112, -112, -112, -112, -112, -142, 88, - -112, -112, -159, -279, -159, -159, -197, -216, -146, -151, - -176, -85, -121, 29, -125, 54, -3, -189, -123, -189, - -142, -159, -142, -217, -217, 83, 83, 23, 202, -101, - -255, 351, 351, -3, 83, 82, 118, -159, -101, -279, - -279, -279, -279, -68, 128, 347, -279, -279, -279, -279, - -279, -279, -105, -149, 434, -154, 43, -152, -153, 44, - -150, 45, 53, 10, -123, 150, 83, -3, -278, 81, - -58, 347, -257, -239, -190, 88, 89, 83, -279, 345, - 70, 348, -146, 48, 262, -156, -155, 52, 44, -153, - 17, 46, 17, -164, -189, -58, -112, 198, -159, -59, - 213, 438, -262, 59, 346, 349, -147, 50, -145, 49, - -145, -155, 17, 17, 88, 17, 88, -279, -279, 83, - 176, -259, 59, -148, 51, 73, 101, 88, 88, 88, - -269, -270, 73, 215, 347, 73, 101, -270, 73, 11, - 10, 348, -268, 184, 179, 182, 31, -268, 349, 178, - 30, 98, + 165, -163, 40, 88, 88, 59, -101, -136, 14, -85, + 135, -142, -164, 73, -165, -123, -125, -124, -279, -158, + -280, -190, -163, -106, 82, 118, -92, -91, 73, 74, + -93, 73, -91, 63, 63, -280, -106, -87, -106, -106, + 150, 317, 321, 322, -241, 98, -112, 10, 88, 29, + 29, -218, -218, 83, 82, 83, 82, 83, 82, -184, + 384, 110, -28, -27, -236, -236, 89, -261, -101, -101, + -101, -101, 17, 82, -225, -129, 54, -251, 83, -255, + -256, -101, -111, -131, -160, 81, 83, -260, 347, -262, + -261, -190, -190, -190, -101, -180, -180, 32, -261, -112, + -280, -142, -280, -216, -216, -216, -220, -216, 244, -216, + 244, -280, -280, 20, 20, 20, 20, -279, -65, 340, + -85, 82, 82, -279, -279, -279, -280, 88, -217, -137, + 15, 17, 28, -164, 82, -280, -280, 82, 54, 150, + -280, -138, -169, -85, -85, 81, -85, -138, -106, -115, + -217, 88, -217, 89, 89, 384, 30, 78, 79, 80, + 30, 75, 76, -160, -159, -190, 201, 183, -280, 82, + -223, 347, 350, 23, -159, -259, -258, -191, 81, 74, + -157, -217, -261, -112, -112, -112, -112, -112, -142, 88, + -112, -112, -161, -280, -190, 171, -161, -161, -198, -217, + -146, -151, -177, -85, -121, 29, -125, 54, -3, -190, + -123, -190, -142, -159, -142, -218, -218, 83, 83, 23, + 202, -101, -256, 351, 351, -3, 83, 82, 118, -159, + -101, -280, -280, -280, -280, -68, 128, 347, -280, -280, + -280, 82, -280, -280, -280, -105, -149, 434, -154, 43, + -152, -153, 44, -150, 45, 53, 10, -123, 150, 83, + -3, -279, 81, -58, 347, -258, -240, -191, 88, 89, + 83, -280, 345, 70, 348, -190, 171, -146, 48, 262, + -156, -155, 52, 44, -153, 17, 46, 17, -165, -190, + -58, -112, 198, -159, -59, 213, 438, -263, 59, 346, + 349, -147, 50, -145, 49, -145, -155, 17, 17, 88, + 17, 88, -280, -280, 83, 176, -260, 59, -148, 51, + 73, 101, 88, 88, 88, -270, -271, 73, 215, 347, + 73, 101, -271, 73, 11, 10, 348, -269, 184, 179, + 182, 31, -269, 349, 178, 30, 98, } var yyDef = [...]int{ 34, -2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 821, 0, 557, 557, 557, 557, 557, - 557, 557, 0, 0, -2, -2, -2, 845, 957, 0, - 934, 0, 0, -2, 490, 491, 0, 493, -2, 0, - 0, 502, 1366, 1366, 552, 0, 0, 0, 0, 0, - 0, 1364, 55, 56, 508, 509, 510, 1, 3, 0, - 561, 829, 0, 0, -2, 559, 0, 0, 940, 940, - 940, 0, 86, 87, 0, 0, 0, 845, 0, 0, - 0, 0, 0, 557, 0, 935, 109, 110, 90, -2, + 31, 32, 33, 825, 0, 557, 557, 557, 557, 557, + 557, 557, 0, 0, -2, -2, -2, 849, 961, 0, + 938, 0, 0, -2, 490, 491, 0, 493, -2, 0, + 0, 502, 1370, 1370, 552, 0, 0, 0, 0, 0, + 0, 1368, 55, 56, 508, 509, 510, 1, 3, 0, + 561, 833, 0, 0, -2, 559, 0, 0, 944, 944, + 944, 0, 86, 87, 0, 0, 0, 849, 0, 0, + 0, 0, 0, 557, 0, 939, 109, 110, 90, -2, 114, 115, 0, 119, 368, 329, 371, 327, 357, -2, 320, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, 224, 224, 0, 0, -2, 320, - 320, 320, 0, 0, 0, 354, 942, 274, 224, 224, + 320, 320, 0, 0, 0, 354, 946, 274, 224, 224, 0, 224, 224, 224, 224, 0, 0, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, - 224, 224, 0, 108, 858, 0, 0, 0, 118, 958, - 955, 956, 35, 36, 37, 1098, 1099, 1100, 1101, 1102, - 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, - 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, - 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, - 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, - 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, - 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, - 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, - 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, - 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, - 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, - 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, - 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, - 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, - 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, - 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, - 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, - 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, - 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, - 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, - 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, - 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, - 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, - 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, - 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, - 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, - 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, - 1363, 0, 0, 0, 936, 557, 0, 424, 642, 0, + 224, 224, 0, 108, 862, 0, 0, 0, 118, 962, + 959, 960, 35, 36, 37, 1102, 1103, 1104, 1105, 1106, + 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, + 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, + 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, + 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, + 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, + 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, + 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, + 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, + 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, + 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, + 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, + 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, + 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, + 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, + 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, + 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, + 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, + 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, + 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, + 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, + 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, + 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, + 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, + 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, + 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, + 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, + 1367, 0, 0, 0, 940, 557, 0, 424, 646, 0, 481, 481, 0, 481, 481, 481, 481, 0, 0, 0, 436, 0, 0, 0, 0, 478, 0, 0, 455, 457, - 0, 478, 0, 465, 481, 1367, 1367, 1367, 925, 0, + 0, 478, 0, 465, 481, 1371, 1371, 1371, 929, 0, 475, 473, 487, 488, 470, 471, 489, 492, 0, 497, - 500, 951, 952, 0, 515, 0, 1174, 507, 520, 521, - 0, 553, 554, 40, 693, 652, 0, 658, 660, 0, - 695, 696, 697, 698, 699, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 725, 726, 727, 728, 806, - 807, 808, 809, 810, 811, 812, 813, 662, 663, 803, - 0, 914, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 794, 0, 763, 763, 763, 763, 763, 763, 763, - 763, 763, 0, 0, 0, 0, 0, 0, 0, -2, - -2, 1366, 0, 530, 0, 0, 821, 51, 0, 557, - 562, 563, 864, 0, 0, 821, 1365, 0, 0, -2, + 500, 955, 956, 0, 515, 0, 1178, 507, 520, 521, + 0, 553, 554, 40, 697, 656, 0, 662, 664, 0, + 699, 700, 701, 702, 703, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 729, 730, 731, 732, 810, + 811, 812, 813, 814, 815, 816, 817, 666, 667, 807, + 0, 918, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 798, 0, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 0, 0, 0, 0, 0, 0, 0, -2, + -2, 1370, 0, 530, 0, 0, 825, 51, 0, 557, + 562, 563, 868, 0, 0, 825, 1369, 0, 0, -2, -2, 573, 579, 580, 581, 582, 583, 558, 0, 586, - 590, 0, 0, 0, 941, 0, 0, 72, 0, 1330, - 918, -2, -2, 0, 0, 953, 954, 927, -2, 961, - 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, - 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, - 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, - 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1001, - 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, - 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, - 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, - 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, - 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, - 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, - 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, - 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, - 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, - 1092, 1093, 1094, 1095, 1096, 1097, -2, 0, 0, 128, - 129, 0, 38, 250, 0, 124, 0, 244, 197, 858, - 938, 948, 0, 0, 0, 938, 92, 116, 117, 224, + 590, 0, 0, 0, 945, 0, 0, 72, 0, 1334, + 922, -2, -2, 0, 0, 957, 958, 931, -2, 965, + 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, + 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, + 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, + 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, + 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, + 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, + 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, + 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, + 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, + 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, + 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, + 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, + 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, + 1096, 1097, 1098, 1099, 1100, 1101, -2, 0, 0, 128, + 129, 0, 38, 250, 0, 124, 0, 244, 197, 862, + 942, 952, 0, 0, 0, 942, 92, 116, 117, 224, 224, 0, 118, 118, 336, 337, 338, 0, 0, -2, 248, 0, 321, 0, 0, 238, 238, 242, 240, 241, 0, 0, 0, 0, 0, 0, 348, 0, 349, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 0, 225, 0, 366, 367, 275, 0, 0, 0, 0, 346, - 347, 0, 0, 943, 944, 0, 0, 224, 224, 0, + 347, 0, 0, 947, 948, 0, 0, 224, 224, 0, 0, 0, 0, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 102, 849, 0, 0, 0, 0, 0, 0, 0, 0, - -2, 0, 416, 0, 936, 0, 0, 0, 936, 423, + 102, 853, 0, 0, 0, 0, 0, 0, 0, 0, + -2, 0, 416, 0, 940, 0, 0, 0, 940, 423, 0, 425, 426, 0, 0, 427, 0, 478, 478, 476, 477, 429, 430, 431, 432, 481, 0, 0, 233, 234, 235, 478, 481, 0, 481, 481, 481, 481, 478, 481, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1367, - 1367, 1367, 484, 481, 462, 463, 466, 467, 1368, 1369, - 972, 468, 469, 926, 498, 501, 518, 516, 517, 519, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1371, + 1371, 1371, 484, 481, 462, 463, 466, 467, 1372, 1373, + 976, 468, 469, 930, 498, 501, 518, 516, 517, 519, 511, 512, 513, 514, 0, 532, 533, 538, 0, 0, 0, 0, 544, 545, 546, 0, 0, 549, 550, 551, - 0, 0, 0, 0, 0, 656, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 680, 681, 682, 683, 684, - 685, 686, 659, 0, 673, 0, 0, 0, 715, 716, - 717, 718, 719, 720, 721, 722, 723, 0, 570, 0, - 0, 0, 821, 0, 0, 0, 0, 0, 0, 0, - 567, 0, 795, 0, 746, 0, 747, 755, 0, 748, - 756, 749, 757, 750, 751, 758, 752, 759, 753, 754, - 760, 0, 0, 0, 570, 570, 0, 0, 41, 522, - 523, 0, 625, 946, 531, 829, 0, 572, 867, 0, - 0, 830, 822, 823, 826, 829, 0, 595, 584, 574, + 0, 0, 0, 0, 0, 660, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 684, 685, 686, 687, 688, + 689, 690, 663, 0, 677, 0, 0, 0, 719, 720, + 721, 722, 723, 724, 725, 726, 727, 0, 570, 0, + 0, 0, 825, 0, 0, 0, 0, 0, 0, 0, + 567, 0, 799, 0, 750, 0, 751, 759, 0, 752, + 760, 753, 761, 754, 755, 762, 756, 763, 757, 758, + 764, 0, 0, 0, 570, 570, 0, 0, 41, 522, + 523, 0, 629, 950, 531, 833, 0, 572, 871, 0, + 0, 834, 826, 827, 830, 833, 0, 595, 584, 574, 577, 578, 560, 0, 587, 591, 0, 593, 594, 0, - 0, 70, 0, 641, 0, 597, 599, 600, 601, 623, - 0, 0, 0, 0, 66, 68, 642, 0, 1330, 924, - 0, 74, 75, 0, 0, 0, 212, 929, 930, 931, + 0, 70, 0, 645, 0, 597, 599, 600, 601, 627, + 0, 0, 0, 0, 66, 68, 646, 0, 1334, 928, + 0, 74, 75, 0, 0, 0, 212, 933, 934, 935, -2, 231, 0, 136, 204, 148, 149, 150, 197, 152, 197, 197, 197, 197, 208, 208, 208, 208, 180, 181, 182, 183, 184, 0, 0, 167, 197, 197, 197, 197, 187, 188, 189, 190, 191, 192, 193, 194, 153, 154, 155, 156, 157, 158, 159, 160, 161, 199, 199, 199, - 201, 201, 0, 39, 0, 216, 0, 826, 0, 849, - 0, 0, 0, 949, 0, 948, 948, 948, 0, 0, + 201, 201, 0, 39, 0, 216, 0, 830, 0, 853, + 0, 0, 0, 953, 0, 952, 952, 952, 0, 0, 0, 369, 330, 358, 370, 0, 333, 334, -2, 0, 0, 320, 0, 322, 0, 232, 0, -2, 0, 0, - 0, 238, 242, 239, 242, 230, 243, 350, 803, 0, - 351, 352, 0, 388, 611, 0, 0, 0, 0, 0, + 0, 238, 242, 239, 242, 230, 243, 350, 807, 0, + 351, 352, 0, 388, 615, 0, 0, 0, 0, 0, 394, 395, 396, 0, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 359, 360, 361, 362, 363, 364, 365, 0, 0, 322, 0, 355, 0, 276, 277, 0, @@ -5267,102 +5334,102 @@ var yyDef = [...]int{ 289, 290, 314, 315, 316, 291, 292, 293, 294, 295, 296, 297, 308, 309, 310, 311, 312, 313, 298, 299, 300, 301, 302, 305, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 383, 384, 385, 386, 846, 847, - 848, 0, 0, 0, 0, 0, 263, 64, 937, 0, - 643, 959, 960, 482, 483, 0, 236, 237, 481, 481, + 0, 0, 0, 0, 383, 384, 385, 386, 850, 851, + 852, 0, 0, 0, 0, 0, 263, 64, 941, 0, + 647, 963, 964, 482, 483, 0, 236, 237, 481, 481, 433, 456, 0, 481, 437, 458, 438, 440, 439, 441, 481, 444, 479, 480, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 460, 0, 461, 0, 0, 499, 503, 504, 505, 506, 0, 0, 535, 540, 541, 542, - 543, 555, 548, 694, 653, 654, 655, 657, 674, 0, - 676, 678, 664, 665, 689, 690, 691, 0, 0, 0, - 0, 687, 669, 0, 700, 701, 702, 703, 704, 705, - 706, 707, 708, 709, 710, 711, 714, 778, 779, 780, - 0, 712, 713, 724, 0, 0, 0, 571, 804, 0, - -2, 0, 692, 913, 829, 0, 0, 0, 0, 697, - 806, 0, 697, 806, 0, 0, 0, 568, 569, 801, - 798, 0, 0, 764, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 525, 526, 528, 0, 645, 0, 626, - 0, 628, 629, 0, 947, 864, 52, 42, 0, 865, - 0, 0, 0, 0, 825, 827, 828, 864, 0, 814, - 0, 0, 650, 0, 0, 575, 48, 592, 588, 0, - 650, 0, 0, 640, 0, 0, 0, 0, 0, 0, - 630, 0, 0, 633, 0, 0, 0, 0, 624, 0, + 543, 555, 548, 698, 657, 658, 659, 661, 678, 0, + 680, 682, 668, 669, 693, 694, 695, 0, 0, 0, + 0, 691, 673, 0, 704, 705, 706, 707, 708, 709, + 710, 711, 712, 713, 714, 715, 718, 782, 783, 784, + 0, 716, 717, 728, 0, 0, 0, 571, 808, 0, + -2, 0, 696, 917, 833, 0, 0, 0, 0, 701, + 810, 0, 701, 810, 0, 0, 0, 568, 569, 805, + 802, 0, 0, 768, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 525, 526, 528, 0, 649, 0, 630, + 0, 632, 633, 0, 951, 868, 52, 42, 0, 869, + 0, 0, 0, 0, 829, 831, 832, 868, 0, 818, + 0, 0, 654, 0, 0, 575, 48, 592, 588, 0, + 654, 0, 0, 644, 0, 0, 0, 0, 0, 0, + 634, 0, 0, 637, 0, 0, 0, 0, 628, 0, 0, 0, -2, 0, 0, 0, 62, 63, 0, 0, - 0, 919, 73, 0, 0, 78, 79, 920, 921, 922, - 923, 0, 111, -2, 271, 130, 132, 133, 134, 125, + 0, 923, 73, 0, 0, 78, 79, 924, 925, 926, + 927, 0, 111, -2, 271, 130, 132, 133, 134, 125, 135, 206, 205, 151, 208, 208, 174, 175, 212, 0, 212, 212, 212, 0, 0, 168, 169, 170, 171, 162, - 0, 163, 164, 165, 0, 166, 249, 0, 833, 217, + 0, 163, 164, 165, 0, 166, 249, 0, 837, 217, 218, 220, 224, 0, 0, 245, 246, 0, 0, 101, - 0, 0, 950, 0, 0, 0, 107, 120, 121, 122, + 0, 0, 954, 0, 0, 0, 107, 120, 121, 122, 123, 118, 0, 0, 126, 324, 0, 0, 0, 247, 0, 0, 226, 242, 227, 228, 0, 353, 0, 0, 390, 391, 392, 393, 0, 0, 0, 322, 324, 212, 0, 278, 279, 284, 285, 303, 0, 0, 0, 0, - 859, 860, 0, 863, 93, 376, 378, 377, 381, 0, - 0, 0, 0, 417, 263, 833, 0, 421, 264, 265, + 863, 864, 0, 867, 93, 376, 378, 377, 381, 0, + 0, 0, 0, 417, 263, 837, 0, 421, 264, 265, 422, 478, 443, 459, 478, 435, 442, 485, 464, 495, - 539, 0, 0, 0, 547, 0, 675, 677, 679, 666, - 687, 670, 0, 667, 0, 0, 661, 729, 0, 0, - 570, 0, 821, 864, 733, 734, 0, 0, 0, 0, - 0, 771, 0, 0, 772, 0, 821, 0, 799, 0, - 0, 745, 765, 0, 0, 766, 767, 768, 769, 770, - 524, 527, 529, 605, 0, 0, 0, 0, 627, 945, - 44, 0, 0, 0, 831, 832, 824, 43, 0, 932, - 933, 815, 816, 817, 0, 585, 596, 576, 0, 829, - 907, 0, 0, 899, 0, 0, 650, 915, 0, 598, - 619, 621, 0, 616, 631, 632, 634, 0, 636, 0, - 638, 639, 602, 603, 604, 0, 650, 0, 650, 67, - 650, 69, 0, 644, 76, 77, 0, 0, 83, 213, + 539, 0, 0, 0, 547, 0, 679, 681, 683, 670, + 691, 674, 0, 671, 0, 0, 665, 733, 0, 0, + 570, 0, 825, 868, 737, 738, 0, 0, 0, 0, + 0, 775, 0, 0, 776, 0, 825, 0, 803, 0, + 0, 749, 769, 0, 0, 770, 771, 772, 773, 774, + 524, 527, 529, 605, 0, 0, 0, 0, 631, 949, + 44, 0, 0, 0, 835, 836, 828, 43, 0, 936, + 937, 819, 820, 821, 0, 585, 596, 576, 0, 833, + 911, 0, 0, 903, 0, 0, 654, 919, 0, 598, + 623, 625, 0, 620, 635, 636, 638, 0, 640, 0, + 642, 643, 602, 603, 604, 0, 654, 0, 654, 67, + 654, 69, 0, 648, 76, 77, 0, 0, 83, 213, 214, 118, 273, 131, 137, 0, 0, 0, 141, 0, 0, 144, 146, 147, 207, 212, 212, 176, 209, 210, 211, 177, 178, 179, 0, 195, 0, 0, 0, 266, - 88, 837, 836, 224, 224, 219, 0, 222, 0, 198, - 0, 939, 103, 0, 0, 0, 0, 328, 609, 0, - 339, 340, 0, 323, 387, 0, 216, 0, 229, 804, - 612, 0, 0, 341, 0, 324, 344, 345, 356, 306, - 307, 304, 607, 850, 851, 852, 0, 862, 96, 0, + 88, 841, 840, 224, 224, 219, 0, 222, 0, 198, + 0, 943, 103, 0, 0, 0, 0, 328, 609, 0, + 339, 340, 0, 323, 387, 0, 216, 0, 229, 808, + 616, 0, 0, 341, 0, 324, 344, 345, 356, 306, + 307, 304, 607, 854, 855, 856, 0, 866, 96, 0, 0, 0, 0, 374, 0, 419, 420, 65, 481, 481, - 534, 0, 537, 0, 668, 0, 688, 671, 730, 731, - 0, 805, 829, 46, 0, 197, 197, 784, 197, 201, - 787, 197, 789, 197, 792, 0, 0, 0, 0, 0, - 0, 0, 796, 744, 802, 0, 0, 0, 0, 0, - 0, 0, 0, 208, 869, 866, 45, 819, 0, 651, - 589, 49, 53, 0, 907, 898, 909, 911, 0, 0, - 0, 903, 0, 821, 0, 0, 613, 620, 0, 0, - 614, 0, 615, 635, 637, -2, 821, 650, 60, 61, + 534, 0, 537, 0, 672, 0, 692, 675, 734, 735, + 0, 809, 833, 46, 0, 197, 197, 788, 197, 201, + 791, 197, 793, 197, 796, 0, 0, 0, 0, 0, + 0, 0, 800, 748, 806, 0, 0, 0, 0, 0, + 0, 0, 0, 208, 873, 870, 45, 823, 0, 655, + 589, 49, 53, 0, 911, 902, 913, 915, 0, 0, + 0, 907, 0, 825, 0, 0, 617, 624, 0, 0, + 618, 0, 619, 639, 641, -2, 825, 654, 60, 61, 0, 80, 81, 82, 272, 138, 139, 0, 142, 143, 145, 172, 173, 208, 0, 208, 0, 202, 0, 255, - 267, 0, 834, 835, 0, 0, 221, 223, 607, 104, + 267, 0, 838, 839, 0, 0, 221, 223, 607, 104, 105, 106, 0, 0, 127, 325, 0, 215, 0, 0, - 412, 409, 342, 343, 0, 0, 861, 375, 0, 94, - 95, 0, 0, 380, 418, 428, 434, 536, 556, 672, - 732, 864, 735, 781, 208, 785, 786, 788, 790, 791, - 793, 737, 736, 0, 0, 0, 0, 0, 829, 0, - 800, 0, 0, 0, 0, 0, 625, 208, 889, 50, - 0, 0, 0, 54, 0, 912, 0, 0, 0, 0, - 71, 829, 916, 917, 617, 0, 622, 829, 59, 140, - 212, 196, 212, 0, 0, 268, 838, 839, 840, 841, - 842, 843, 844, 0, 331, 610, 0, 0, 389, 0, + 412, 409, 342, 343, 0, 0, 865, 375, 0, 94, + 95, 0, 0, 380, 418, 428, 434, 536, 556, 676, + 736, 868, 739, 785, 208, 789, 790, 792, 794, 795, + 797, 741, 740, 0, 0, 0, 0, 0, 833, 0, + 804, 0, 0, 0, 0, 0, 629, 208, 893, 50, + 0, 0, 0, 54, 0, 916, 0, 0, 0, 0, + 71, 833, 920, 921, 621, 0, 626, 833, 59, 140, + 212, 196, 212, 0, 0, 268, 842, 843, 844, 845, + 846, 847, 848, 0, 331, 610, 0, 0, 389, 0, 397, 0, 0, 0, 0, 97, 98, 0, 0, 0, - 47, 782, 783, 0, 0, 0, 0, 773, 0, 797, - 0, 0, 0, 647, 0, 0, 645, 871, 870, 883, - 896, 820, 818, 0, 910, 0, 902, 905, 901, 904, - 57, 0, 58, 185, 186, 200, 203, 0, 0, 0, - 413, 410, 411, 853, 608, 0, 0, 0, 382, 738, - 740, 739, 741, 0, 0, 0, 743, 761, 762, 646, - 648, 649, 606, 889, 0, 882, 0, -2, 891, 0, - 0, 0, 897, 0, 900, 0, 618, 853, 0, 0, - 372, 855, 99, 100, 317, 318, 319, 93, 742, 0, - 0, 0, 876, 874, 874, 884, 885, 0, 0, 892, - 0, 0, 0, 908, 906, 89, 0, 0, 0, 0, - 856, 857, 96, 774, 0, 777, 879, 0, 872, 875, - 873, 886, 0, 0, 893, 0, 895, 414, 415, 251, - 0, 379, 775, 868, 0, 877, 878, 887, 888, 894, - 252, 253, 0, 854, 0, 880, 881, 254, 0, 0, - 0, 0, 256, 258, 259, 0, 0, 257, 776, 260, - 261, 262, + 47, 786, 787, 0, 0, 0, 0, 777, 0, 801, + 0, 0, 0, 651, 611, 612, 0, 0, 649, 875, + 874, 887, 900, 824, 822, 0, 914, 0, 906, 909, + 905, 908, 57, 0, 58, 185, 186, 200, 203, 0, + 0, 0, 413, 410, 411, 857, 608, 0, 0, 0, + 382, 742, 744, 743, 745, 0, 0, 0, 747, 765, + 766, 0, 650, 652, 653, 606, 893, 0, 886, 0, + -2, 895, 0, 0, 0, 901, 0, 904, 0, 622, + 857, 0, 0, 372, 859, 99, 100, 317, 318, 319, + 93, 746, 0, 0, 0, 613, 614, 880, 878, 878, + 888, 889, 0, 0, 896, 0, 0, 0, 912, 910, + 89, 0, 0, 0, 0, 860, 861, 96, 778, 0, + 781, 883, 0, 876, 879, 877, 890, 0, 0, 897, + 0, 899, 414, 415, 251, 0, 379, 779, 872, 0, + 881, 882, 891, 892, 898, 252, 253, 0, 858, 0, + 884, 885, 254, 0, 0, 0, 0, 256, 258, 259, + 0, 0, 257, 780, 260, 261, 262, } var yyTok1 = [...]int{ @@ -10096,199 +10163,229 @@ yydefault: } case 611: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL Partitions + var yyLOCAL Columns //line sql.y:3195 { - yyLOCAL = Partitions{yyDollar[1].colIdent} + yyLOCAL = Columns{yyDollar[1].colIdent} } yyVAL.union = yyLOCAL case 612: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Columns //line sql.y:3199 + { + yyLOCAL = Columns{NewColIdent(string(yyDollar[1].str))} + } + yyVAL.union = yyLOCAL + case 613: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3203 + { + yySLICE := (*Columns)(yyIaddr(yyVAL.union)) + *yySLICE = append(*yySLICE, yyDollar[3].colIdent) + } + case 614: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3207 + { + yySLICE := (*Columns)(yyIaddr(yyVAL.union)) + *yySLICE = append(*yySLICE, NewColIdent(string(yyDollar[3].str))) + } + case 615: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Partitions +//line sql.y:3213 + { + yyLOCAL = Partitions{yyDollar[1].colIdent} + } + yyVAL.union = yyLOCAL + case 616: + yyDollar = yyS[yypt-3 : yypt+1] +//line sql.y:3217 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colIdent) } - case 613: + case 617: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3212 +//line sql.y:3230 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 614: + case 618: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3216 +//line sql.y:3234 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 615: + case 619: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3220 +//line sql.y:3238 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 616: + case 620: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3224 +//line sql.y:3242 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL - case 617: + case 621: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3230 +//line sql.y:3248 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].exprUnion()} } - case 618: + case 622: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3232 +//line sql.y:3250 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columnsUnion()} } - case 619: + case 623: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3236 +//line sql.y:3254 { yyVAL.joinCondition = JoinCondition{} } - case 620: + case 624: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3238 +//line sql.y:3256 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 621: + case 625: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3242 +//line sql.y:3260 { yyVAL.joinCondition = JoinCondition{} } - case 622: + case 626: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3244 +//line sql.y:3262 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].exprUnion()} } - case 623: + case 627: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3247 +//line sql.y:3265 { yyVAL.empty = struct{}{} } - case 624: + case 628: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3249 +//line sql.y:3267 { yyVAL.empty = struct{}{} } - case 625: + case 629: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3252 +//line sql.y:3270 { yyVAL.tableIdent = NewTableIdent("") } - case 626: + case 630: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3256 +//line sql.y:3274 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 627: + case 631: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3260 +//line sql.y:3278 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 629: + case 633: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3267 +//line sql.y:3285 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].str)) } - case 630: + case 634: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:3273 +//line sql.y:3291 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 631: + case 635: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3277 +//line sql.y:3295 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 632: + case 636: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3281 +//line sql.y:3299 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 633: + case 637: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:3287 +//line sql.y:3305 { yyLOCAL = StraightJoinType } yyVAL.union = yyLOCAL - case 634: + case 638: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3293 +//line sql.y:3311 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 635: + case 639: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:3297 +//line sql.y:3315 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 636: + case 640: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3301 +//line sql.y:3319 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 637: + case 641: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:3305 +//line sql.y:3323 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 638: + case 642: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3311 +//line sql.y:3329 { yyLOCAL = NaturalJoinType } yyVAL.union = yyLOCAL - case 639: + case 643: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3315 +//line sql.y:3333 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -10297,668 +10394,668 @@ yydefault: } } yyVAL.union = yyLOCAL - case 640: + case 644: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3325 +//line sql.y:3343 { yyVAL.tableName = yyDollar[2].tableName } - case 641: + case 645: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3329 +//line sql.y:3347 { yyVAL.tableName = yyDollar[1].tableName } - case 642: + case 646: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3335 +//line sql.y:3353 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 643: + case 647: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3339 +//line sql.y:3357 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } - case 644: + case 648: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3345 +//line sql.y:3363 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 645: + case 649: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3350 +//line sql.y:3368 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 646: + case 650: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3354 +//line sql.y:3372 { yyLOCAL = &IndexHints{Type: UseOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 647: + case 651: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3358 +//line sql.y:3376 { yyLOCAL = &IndexHints{Type: UseOp} } yyVAL.union = yyLOCAL - case 648: + case 652: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3362 +//line sql.y:3380 { yyLOCAL = &IndexHints{Type: IgnoreOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 649: + case 653: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3366 +//line sql.y:3384 { yyLOCAL = &IndexHints{Type: ForceOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 650: + case 654: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:3371 +//line sql.y:3389 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 651: + case 655: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3375 +//line sql.y:3393 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 652: + case 656: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3381 +//line sql.y:3399 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 653: + case 657: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3385 +//line sql.y:3403 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 654: + case 658: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3389 +//line sql.y:3407 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 655: + case 659: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3393 +//line sql.y:3411 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 656: + case 660: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3397 +//line sql.y:3415 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 657: + case 661: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3401 +//line sql.y:3419 { yyLOCAL = &IsExpr{Operator: yyDollar[3].isExprOperatorUnion(), Expr: yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 658: + case 662: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3405 +//line sql.y:3423 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 659: + case 663: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3409 +//line sql.y:3427 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 660: + case 664: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3415 +//line sql.y:3433 { yyVAL.str = "" } - case 661: + case 665: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3419 +//line sql.y:3437 { yyVAL.str = string(yyDollar[2].colIdent.String()) } - case 662: + case 666: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:3425 +//line sql.y:3443 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 663: + case 667: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:3429 +//line sql.y:3447 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 664: + case 668: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3435 +//line sql.y:3453 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 665: + case 669: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3439 +//line sql.y:3457 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL - case 666: + case 670: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3443 +//line sql.y:3461 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL - case 667: + case 671: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3447 +//line sql.y:3465 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 668: + case 672: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3451 +//line sql.y:3469 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 669: + case 673: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3455 +//line sql.y:3473 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 670: + case 674: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3459 +//line sql.y:3477 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 671: + case 675: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3463 +//line sql.y:3481 { yyLOCAL = &RangeCond{Left: yyDollar[1].exprUnion(), Operator: BetweenOp, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 672: + case 676: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:3467 +//line sql.y:3485 { yyLOCAL = &RangeCond{Left: yyDollar[1].exprUnion(), Operator: NotBetweenOp, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 673: + case 677: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3471 +//line sql.y:3489 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL - case 674: + case 678: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3477 +//line sql.y:3495 { yyLOCAL = IsNullOp } yyVAL.union = yyLOCAL - case 675: + case 679: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3481 +//line sql.y:3499 { yyLOCAL = IsNotNullOp } yyVAL.union = yyLOCAL - case 676: + case 680: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3485 +//line sql.y:3503 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 677: + case 681: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3489 +//line sql.y:3507 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 678: + case 682: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3493 +//line sql.y:3511 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 679: + case 683: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3497 +//line sql.y:3515 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 680: + case 684: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3503 +//line sql.y:3521 { yyLOCAL = EqualOp } yyVAL.union = yyLOCAL - case 681: + case 685: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3507 +//line sql.y:3525 { yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL - case 682: + case 686: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3511 +//line sql.y:3529 { yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL - case 683: + case 687: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3515 +//line sql.y:3533 { yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL - case 684: + case 688: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3519 +//line sql.y:3537 { yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL - case 685: + case 689: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3523 +//line sql.y:3541 { yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL - case 686: + case 690: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3527 +//line sql.y:3545 { yyLOCAL = NullSafeEqualOp } yyVAL.union = yyLOCAL - case 687: + case 691: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:3532 +//line sql.y:3550 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 688: + case 692: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3536 +//line sql.y:3554 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 689: + case 693: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:3542 +//line sql.y:3560 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 690: + case 694: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:3546 +//line sql.y:3564 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 691: + case 695: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:3550 +//line sql.y:3568 { yyLOCAL = ListArg(yyDollar[1].str) bindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 692: + case 696: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Subquery -//line sql.y:3557 +//line sql.y:3575 { yyLOCAL = &Subquery{yyDollar[2].selStmtUnion()} } yyVAL.union = yyLOCAL - case 693: + case 697: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:3563 +//line sql.y:3581 { yyLOCAL = Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 694: + case 698: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3567 +//line sql.y:3585 { yySLICE := (*Exprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } - case 695: + case 699: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3573 +//line sql.y:3591 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 696: + case 700: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3577 +//line sql.y:3595 { yyLOCAL = yyDollar[1].boolValUnion() } yyVAL.union = yyLOCAL - case 697: + case 701: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3581 +//line sql.y:3599 { yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL - case 698: + case 702: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3585 +//line sql.y:3603 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 699: + case 703: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3589 +//line sql.y:3607 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 700: + case 704: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3593 +//line sql.y:3611 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 701: + case 705: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3597 +//line sql.y:3615 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 702: + case 706: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3601 +//line sql.y:3619 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 703: + case 707: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3605 +//line sql.y:3623 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 704: + case 708: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3609 +//line sql.y:3627 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 705: + case 709: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3613 +//line sql.y:3631 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 706: + case 710: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3617 +//line sql.y:3635 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 707: + case 711: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3621 +//line sql.y:3639 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 708: + case 712: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3625 +//line sql.y:3643 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 709: + case 713: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3629 +//line sql.y:3647 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 710: + case 714: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3633 +//line sql.y:3651 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 711: + case 715: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3637 +//line sql.y:3655 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 712: + case 716: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3641 +//line sql.y:3659 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].colNameUnion(), Operator: JSONExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 713: + case 717: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3645 +//line sql.y:3663 { yyLOCAL = &BinaryExpr{Left: yyDollar[1].colNameUnion(), Operator: JSONUnquoteExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 714: + case 718: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3649 +//line sql.y:3667 { yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Charset: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 715: + case 719: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3653 +//line sql.y:3671 { yyLOCAL = &UnaryExpr{Operator: BinaryOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 716: + case 720: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3657 +//line sql.y:3675 { yyLOCAL = &UnaryExpr{Operator: UBinaryOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 717: + case 721: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3661 +//line sql.y:3679 { yyLOCAL = &UnaryExpr{Operator: Utf8Op, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 718: + case 722: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3665 +//line sql.y:3683 { yyLOCAL = &UnaryExpr{Operator: Utf8mb4Op, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 719: + case 723: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3669 +//line sql.y:3687 { yyLOCAL = &UnaryExpr{Operator: Latin1Op, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 720: + case 724: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3673 +//line sql.y:3691 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 721: + case 725: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3677 +//line sql.y:3695 { yyLOCAL = handleUnaryMinus(yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL - case 722: + case 726: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3681 +//line sql.y:3699 { yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 723: + case 727: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3685 +//line sql.y:3703 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 724: + case 728: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3689 +//line sql.y:3707 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -10967,666 +11064,666 @@ yydefault: yyLOCAL = &IntervalExpr{Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].colIdent.String()} } yyVAL.union = yyLOCAL - case 729: + case 733: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3707 +//line sql.y:3725 { yyLOCAL = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 730: + case 734: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3711 +//line sql.y:3729 { yyLOCAL = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 731: + case 735: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3715 +//line sql.y:3733 { yyLOCAL = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 732: + case 736: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:3719 +//line sql.y:3737 { yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 733: + case 737: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3729 +//line sql.y:3747 { yyLOCAL = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 734: + case 738: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3733 +//line sql.y:3751 { yyLOCAL = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 735: + case 739: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:3737 +//line sql.y:3755 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 736: + case 740: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:3741 +//line sql.y:3759 { yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL - case 737: + case 741: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:3745 +//line sql.y:3763 { yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } yyVAL.union = yyLOCAL - case 738: + case 742: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3749 +//line sql.y:3767 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].colNameUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 739: + case 743: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3753 +//line sql.y:3771 { yyLOCAL = &SubstrExpr{Name: yyDollar[3].colNameUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 740: + case 744: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3757 +//line sql.y:3775 { yyLOCAL = &SubstrExpr{StrVal: NewStrLiteral(yyDollar[3].str), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 741: + case 745: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3761 +//line sql.y:3779 { yyLOCAL = &SubstrExpr{StrVal: NewStrLiteral(yyDollar[3].str), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 742: + case 746: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr -//line sql.y:3765 +//line sql.y:3783 { yyLOCAL = &MatchExpr{Columns: yyDollar[3].selectExprsUnion(), Expr: yyDollar[7].exprUnion(), Option: yyDollar[8].matchExprOptionUnion()} } yyVAL.union = yyLOCAL - case 743: + case 747: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3769 +//line sql.y:3787 { yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].selectExprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL - case 744: + case 748: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3773 +//line sql.y:3791 { yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 745: + case 749: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3777 +//line sql.y:3795 { yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL - case 746: + case 750: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3781 +//line sql.y:3799 { yyLOCAL = &FuncExpr{Name: NewColIdent(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 747: + case 751: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3791 +//line sql.y:3809 { yyLOCAL = &FuncExpr{Name: NewColIdent("current_timestamp")} } yyVAL.union = yyLOCAL - case 748: + case 752: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3795 +//line sql.y:3813 { yyLOCAL = &FuncExpr{Name: NewColIdent("utc_timestamp")} } yyVAL.union = yyLOCAL - case 749: + case 753: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3799 +//line sql.y:3817 { yyLOCAL = &FuncExpr{Name: NewColIdent("utc_time")} } yyVAL.union = yyLOCAL - case 750: + case 754: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3804 +//line sql.y:3822 { yyLOCAL = &FuncExpr{Name: NewColIdent("utc_date")} } yyVAL.union = yyLOCAL - case 751: + case 755: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3809 +//line sql.y:3827 { yyLOCAL = &FuncExpr{Name: NewColIdent("localtime")} } yyVAL.union = yyLOCAL - case 752: + case 756: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3814 +//line sql.y:3832 { yyLOCAL = &FuncExpr{Name: NewColIdent("localtimestamp")} } yyVAL.union = yyLOCAL - case 753: + case 757: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3820 +//line sql.y:3838 { yyLOCAL = &FuncExpr{Name: NewColIdent("current_date")} } yyVAL.union = yyLOCAL - case 754: + case 758: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3825 +//line sql.y:3843 { yyLOCAL = &FuncExpr{Name: NewColIdent("current_time")} } yyVAL.union = yyLOCAL - case 755: + case 759: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3830 +//line sql.y:3848 { yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 756: + case 760: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3834 +//line sql.y:3852 { yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 757: + case 761: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3838 +//line sql.y:3856 { yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 758: + case 762: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3843 +//line sql.y:3861 { yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 759: + case 763: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3848 +//line sql.y:3866 { yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 760: + case 764: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3853 +//line sql.y:3871 { yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 761: + case 765: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3857 +//line sql.y:3875 { yyLOCAL = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 762: + case 766: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr -//line sql.y:3861 +//line sql.y:3879 { yyLOCAL = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 765: + case 769: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3871 +//line sql.y:3889 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 766: + case 770: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3881 +//line sql.y:3899 { yyLOCAL = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 767: + case 771: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3885 +//line sql.y:3903 { yyLOCAL = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 768: + case 772: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3889 +//line sql.y:3907 { yyLOCAL = &FuncExpr{Name: NewColIdent("schema"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 769: + case 773: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3893 +//line sql.y:3911 { yyLOCAL = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 770: + case 774: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3897 +//line sql.y:3915 { yyLOCAL = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 771: + case 775: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3901 +//line sql.y:3919 { yyLOCAL = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 772: + case 776: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3905 +//line sql.y:3923 { yyLOCAL = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL - case 773: + case 777: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:3911 +//line sql.y:3929 { yyLOCAL = NoOption } yyVAL.union = yyLOCAL - case 774: + case 778: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:3915 +//line sql.y:3933 { yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL - case 775: + case 779: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:3919 +//line sql.y:3937 { yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL - case 776: + case 780: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:3923 +//line sql.y:3941 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL - case 777: + case 781: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:3927 +//line sql.y:3945 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL - case 778: + case 782: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3933 +//line sql.y:3951 { yyVAL.str = string(yyDollar[1].colIdent.String()) } - case 779: + case 783: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3937 +//line sql.y:3955 { yyVAL.str = string(yyDollar[1].str) } - case 780: + case 784: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3941 +//line sql.y:3959 { yyVAL.str = string(yyDollar[1].str) } - case 781: + case 785: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3947 +//line sql.y:3965 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 782: + case 786: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3951 +//line sql.y:3969 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: yyDollar[3].str, Operator: CharacterSetOp} } yyVAL.union = yyLOCAL - case 783: + case 787: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3955 +//line sql.y:3973 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: string(yyDollar[3].colIdent.String())} } yyVAL.union = yyLOCAL - case 784: + case 788: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3959 +//line sql.y:3977 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 785: + case 789: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3963 +//line sql.y:3981 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 786: + case 790: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3967 +//line sql.y:3985 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL - case 787: + case 791: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3973 +//line sql.y:3991 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 788: + case 792: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3977 +//line sql.y:3995 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 789: + case 793: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3981 +//line sql.y:3999 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 790: + case 794: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3985 +//line sql.y:4003 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 791: + case 795: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3989 +//line sql.y:4007 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 792: + case 796: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3993 +//line sql.y:4011 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 793: + case 797: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:3997 +//line sql.y:4015 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 794: + case 798: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:4002 +//line sql.y:4020 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 795: + case 799: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4006 +//line sql.y:4024 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 796: + case 800: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4011 +//line sql.y:4029 { yyVAL.str = string("") } - case 797: + case 801: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4015 +//line sql.y:4033 { yyVAL.str = " separator " + encodeSQLString(yyDollar[2].str) } - case 798: + case 802: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:4021 +//line sql.y:4039 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 799: + case 803: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4025 +//line sql.y:4043 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 800: + case 804: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:4031 +//line sql.y:4049 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 801: + case 805: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:4036 +//line sql.y:4054 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 802: + case 806: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4040 +//line sql.y:4058 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 803: + case 807: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:4046 +//line sql.y:4064 { yyLOCAL = &ColName{Name: yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 804: + case 808: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:4050 +//line sql.y:4068 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } yyVAL.union = yyLOCAL - case 805: + case 809: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:4054 +//line sql.y:4072 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } yyVAL.union = yyLOCAL - case 806: + case 810: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4060 +//line sql.y:4078 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 807: + case 811: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4064 +//line sql.y:4082 { yyLOCAL = NewHexLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 808: + case 812: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4068 +//line sql.y:4086 { yyLOCAL = NewBitLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 809: + case 813: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4072 +//line sql.y:4090 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 810: + case 814: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4076 +//line sql.y:4094 { yyLOCAL = NewFloatLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 811: + case 815: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4080 +//line sql.y:4098 { yyLOCAL = NewHexNumLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 812: + case 816: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4084 +//line sql.y:4102 { yyLOCAL = NewArgument(yyDollar[1].str) bindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 813: + case 817: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4089 +//line sql.y:4107 { yyLOCAL = &NullVal{} } yyVAL.union = yyLOCAL - case 814: + case 818: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4095 +//line sql.y:4113 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -11636,707 +11733,707 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 815: + case 819: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4104 +//line sql.y:4122 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 816: + case 820: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4108 +//line sql.y:4126 { yyLOCAL = NewArgument(yyDollar[1].str) bindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 817: + case 821: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:4114 +//line sql.y:4132 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 818: + case 822: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:4118 +//line sql.y:4136 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 819: + case 823: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:4123 +//line sql.y:4141 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 820: + case 824: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4127 +//line sql.y:4145 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 821: + case 825: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:4132 +//line sql.y:4150 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 822: + case 826: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:4136 +//line sql.y:4154 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 823: + case 827: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:4142 +//line sql.y:4160 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 824: + case 828: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4146 +//line sql.y:4164 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 825: + case 829: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:4152 +//line sql.y:4170 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 826: + case 830: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:4157 +//line sql.y:4175 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 827: + case 831: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:4161 +//line sql.y:4179 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 828: + case 832: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:4165 +//line sql.y:4183 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 829: + case 833: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:4170 +//line sql.y:4188 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 830: + case 834: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:4174 +//line sql.y:4192 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 831: + case 835: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:4178 +//line sql.y:4196 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 832: + case 836: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:4182 +//line sql.y:4200 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 833: + case 837: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:4187 +//line sql.y:4205 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 834: + case 838: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:4191 +//line sql.y:4209 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 835: + case 839: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:4195 +//line sql.y:4213 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 836: + case 840: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:4199 +//line sql.y:4217 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 837: + case 841: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:4203 +//line sql.y:4221 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 838: + case 842: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4210 +//line sql.y:4228 { yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL - case 839: + case 843: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4214 +//line sql.y:4232 { yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL - case 840: + case 844: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4218 +//line sql.y:4236 { yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL - case 841: + case 845: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4222 +//line sql.y:4240 { yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL - case 842: + case 846: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4228 +//line sql.y:4246 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 843: + case 847: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4232 +//line sql.y:4250 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 844: + case 848: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4236 +//line sql.y:4254 { yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL - case 845: + case 849: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4241 +//line sql.y:4259 { yyVAL.str = "" } - case 846: + case 850: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4245 +//line sql.y:4263 { yyVAL.str = string(yyDollar[3].str) } - case 847: + case 851: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4249 +//line sql.y:4267 { yyVAL.str = string(yyDollar[3].str) } - case 848: + case 852: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4253 +//line sql.y:4271 { yyVAL.str = string(yyDollar[3].str) } - case 849: + case 853: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4258 +//line sql.y:4276 { yyVAL.str = "" } - case 850: + case 854: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4262 +//line sql.y:4280 { yyVAL.str = yyDollar[3].str } - case 851: + case 855: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4268 +//line sql.y:4286 { yyVAL.str = string(yyDollar[1].str) } - case 852: + case 856: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4272 +//line sql.y:4290 { yyVAL.str = string(yyDollar[1].str) } - case 853: + case 857: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4277 +//line sql.y:4295 { yyVAL.str = "" } - case 854: + case 858: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4281 +//line sql.y:4299 { yyVAL.str = yyDollar[2].str } - case 855: + case 859: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4286 +//line sql.y:4304 { yyVAL.str = "cascaded" } - case 856: + case 860: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4290 +//line sql.y:4308 { yyVAL.str = string(yyDollar[1].str) } - case 857: + case 861: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4294 +//line sql.y:4312 { yyVAL.str = string(yyDollar[1].str) } - case 858: + case 862: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4299 +//line sql.y:4317 { yyVAL.str = "" } - case 859: + case 863: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4303 +//line sql.y:4321 { yyVAL.str = yyDollar[3].str } - case 860: + case 864: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4309 +//line sql.y:4327 { yyVAL.str = string(yyDollar[1].str) } - case 861: + case 865: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4313 +//line sql.y:4331 { yyVAL.str = string(yyDollar[1].str) } - case 862: + case 866: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4317 +//line sql.y:4335 { yyVAL.str = encodeSQLString(yyDollar[1].str) + "@" + string(yyDollar[2].str) } - case 863: + case 867: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4321 +//line sql.y:4339 { yyVAL.str = string(yyDollar[1].str) } - case 864: + case 868: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Lock -//line sql.y:4326 +//line sql.y:4344 { yyLOCAL = NoLock } yyVAL.union = yyLOCAL - case 865: + case 869: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:4330 +//line sql.y:4348 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 866: + case 870: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:4334 +//line sql.y:4352 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 867: + case 871: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4339 +//line sql.y:4357 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 868: + case 872: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4343 +//line sql.y:4361 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].str, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 869: + case 873: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4347 +//line sql.y:4365 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: "", FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 870: + case 874: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4351 +//line sql.y:4369 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].str, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 871: + case 875: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4356 +//line sql.y:4374 { yyVAL.str = "" } - case 872: + case 876: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4360 +//line sql.y:4378 { yyVAL.str = " format csv" + yyDollar[3].str } - case 873: + case 877: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4364 +//line sql.y:4382 { yyVAL.str = " format text" + yyDollar[3].str } - case 874: + case 878: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4369 +//line sql.y:4387 { yyVAL.str = "" } - case 875: + case 879: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4373 +//line sql.y:4391 { yyVAL.str = " header" } - case 876: + case 880: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4378 +//line sql.y:4396 { yyVAL.str = "" } - case 877: + case 881: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4382 +//line sql.y:4400 { yyVAL.str = " manifest on" } - case 878: + case 882: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4386 +//line sql.y:4404 { yyVAL.str = " manifest off" } - case 879: + case 883: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4391 +//line sql.y:4409 { yyVAL.str = "" } - case 880: + case 884: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4395 +//line sql.y:4413 { yyVAL.str = " overwrite on" } - case 881: + case 885: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4399 +//line sql.y:4417 { yyVAL.str = " overwrite off" } - case 882: + case 886: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4405 +//line sql.y:4423 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 883: + case 887: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4410 +//line sql.y:4428 { yyVAL.str = "" } - case 884: + case 888: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4414 +//line sql.y:4432 { yyVAL.str = " lines" + yyDollar[2].str } - case 885: + case 889: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4420 +//line sql.y:4438 { yyVAL.str = yyDollar[1].str } - case 886: + case 890: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4424 +//line sql.y:4442 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 887: + case 891: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4430 +//line sql.y:4448 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 888: + case 892: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4434 +//line sql.y:4452 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 889: + case 893: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4439 +//line sql.y:4457 { yyVAL.str = "" } - case 890: + case 894: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4443 +//line sql.y:4461 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 891: + case 895: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4449 +//line sql.y:4467 { yyVAL.str = yyDollar[1].str } - case 892: + case 896: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4453 +//line sql.y:4471 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 893: + case 897: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4459 +//line sql.y:4477 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 894: + case 898: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4463 +//line sql.y:4481 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 895: + case 899: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4467 +//line sql.y:4485 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 896: + case 900: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4472 +//line sql.y:4490 { yyVAL.str = "" } - case 897: + case 901: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4476 +//line sql.y:4494 { yyVAL.str = " optionally" } - case 898: + case 902: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Insert -//line sql.y:4489 +//line sql.y:4507 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion()} } yyVAL.union = yyLOCAL - case 899: + case 903: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:4493 +//line sql.y:4511 { yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 900: + case 904: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:4497 +//line sql.y:4515 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion()} } yyVAL.union = yyLOCAL - case 901: + case 905: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:4501 +//line sql.y:4519 { yyLOCAL = &Insert{Rows: yyDollar[4].valuesUnion()} } yyVAL.union = yyLOCAL - case 902: + case 906: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:4505 +//line sql.y:4523 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} } yyVAL.union = yyLOCAL - case 903: + case 907: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4511 +//line sql.y:4529 { yyLOCAL = Columns{yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 904: + case 908: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:4515 +//line sql.y:4533 { yyLOCAL = Columns{yyDollar[3].colIdent} } yyVAL.union = yyLOCAL - case 905: + case 909: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4519 +//line sql.y:4537 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colIdent) } - case 906: + case 910: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4523 +//line sql.y:4541 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].colIdent) } - case 907: + case 911: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:4528 +//line sql.y:4546 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 908: + case 912: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:4532 +//line sql.y:4550 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 909: + case 913: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:4538 +//line sql.y:4556 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 910: + case 914: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4542 +//line sql.y:4560 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 911: + case 915: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:4548 +//line sql.y:4566 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 912: + case 916: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:4552 +//line sql.y:4570 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 913: + case 917: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:4558 +//line sql.y:4576 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 914: + case 918: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4564 +//line sql.y:4582 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -12345,329 +12442,329 @@ yydefault: } } yyVAL.union = yyLOCAL - case 915: + case 919: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:4574 +//line sql.y:4592 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 916: + case 920: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4578 +//line sql.y:4596 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 917: + case 921: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:4584 +//line sql.y:4602 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 918: + case 922: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:4590 +//line sql.y:4608 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL - case 919: + case 923: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4594 +//line sql.y:4612 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) } - case 920: + case 924: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4600 +//line sql.y:4618 { yyLOCAL = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL - case 921: + case 925: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4604 +//line sql.y:4622 { yyLOCAL = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral("off")} } yyVAL.union = yyLOCAL - case 922: + case 926: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4608 +//line sql.y:4626 { yyLOCAL = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 923: + case 927: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4612 +//line sql.y:4630 { yyLOCAL = &SetExpr{Name: NewColIdent(string(yyDollar[1].str)), Scope: ImplicitScope, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 924: + case 928: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4616 +//line sql.y:4634 { yyDollar[2].setExprUnion().Scope = yyDollar[1].scopeUnion() yyLOCAL = yyDollar[2].setExprUnion() } yyVAL.union = yyLOCAL - case 926: + case 930: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4624 +//line sql.y:4642 { yyVAL.str = "charset" } - case 929: + case 933: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4634 +//line sql.y:4652 { yyLOCAL = NewStrLiteral(yyDollar[1].colIdent.String()) } yyVAL.union = yyLOCAL - case 930: + case 934: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4638 +//line sql.y:4656 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 931: + case 935: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4642 +//line sql.y:4660 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 934: + case 938: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4651 +//line sql.y:4669 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 935: + case 939: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4653 +//line sql.y:4671 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 936: + case 940: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4656 +//line sql.y:4674 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 937: + case 941: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4658 +//line sql.y:4676 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 938: + case 942: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4661 +//line sql.y:4679 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 939: + case 943: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:4663 +//line sql.y:4681 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 940: + case 944: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:4666 +//line sql.y:4684 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 941: + case 945: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:4668 +//line sql.y:4686 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 942: + case 946: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4671 +//line sql.y:4689 { yyVAL.empty = struct{}{} } - case 943: + case 947: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4673 +//line sql.y:4691 { yyVAL.empty = struct{}{} } - case 944: + case 948: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4675 +//line sql.y:4693 { yyVAL.empty = struct{}{} } - case 945: + case 949: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4679 +//line sql.y:4697 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 946: + case 950: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:4684 +//line sql.y:4702 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 947: + case 951: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:4688 +//line sql.y:4706 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 948: + case 952: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:4693 +//line sql.y:4711 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 949: + case 953: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:4695 +//line sql.y:4713 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 950: + case 954: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:4699 +//line sql.y:4717 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].colIdent.String())} } yyVAL.union = yyLOCAL - case 951: + case 955: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4705 +//line sql.y:4723 { yyVAL.colIdent = yyDollar[1].colIdent } - case 952: + case 956: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4709 +//line sql.y:4727 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].str)) } - case 954: + case 958: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4716 +//line sql.y:4734 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].str)) } - case 955: + case 959: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4722 +//line sql.y:4740 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].colIdent.String())) } - case 956: + case 960: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4726 +//line sql.y:4744 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].str)) } - case 957: + case 961: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4731 +//line sql.y:4749 { yyVAL.tableIdent = NewTableIdent("") } - case 958: + case 962: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4735 +//line sql.y:4753 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 960: + case 964: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4742 +//line sql.y:4760 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].str)) } - case 1364: + case 1368: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5170 +//line sql.y:5188 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 1365: + case 1369: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5179 +//line sql.y:5197 { decNesting(yylex) } - case 1366: + case 1370: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5184 +//line sql.y:5202 { skipToEnd(yylex) } - case 1367: + case 1371: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5189 +//line sql.y:5207 { skipToEnd(yylex) } - case 1368: + case 1372: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5193 +//line sql.y:5211 { skipToEnd(yylex) } - case 1369: + case 1373: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5197 +//line sql.y:5215 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 329204898d1..38fd54530f5 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -348,7 +348,7 @@ func bindVariable(yylex yyLexer, bvar string) { %type header_opt export_options manifest_opt overwrite_opt format_opt optionally_opt %type fields_opts fields_opt_list fields_opt lines_opts lines_opt lines_opt_list %type lock_opt -%type ins_column_list column_list column_list_opt +%type ins_column_list column_list column_list_opt index_list %type opt_partition_clause partition_list %type on_dup_opt %type update_list @@ -3190,6 +3190,24 @@ column_list: $$ = append($$, $3) } +index_list: + sql_id + { + $$ = Columns{$1} + } +| PRIMARY + { + $$ = Columns{NewColIdent(string($1))} + } +| index_list ',' sql_id + { + $$ = append($$, $3) + } +| index_list ',' PRIMARY + { + $$ = append($$, NewColIdent(string($3))) + } + partition_list: sql_id { @@ -3350,7 +3368,7 @@ index_hint_list: { $$ = nil } -| USE INDEX openb column_list closeb +| USE INDEX openb index_list closeb { $$ = &IndexHints{Type: UseOp, Indexes: $4} } @@ -3358,11 +3376,11 @@ index_hint_list: { $$ = &IndexHints{Type: UseOp} } -| IGNORE INDEX openb column_list closeb +| IGNORE INDEX openb index_list closeb { $$ = &IndexHints{Type: IgnoreOp, Indexes: $4} } -| FORCE INDEX openb column_list closeb +| FORCE INDEX openb index_list closeb { $$ = &IndexHints{Type: ForceOp, Indexes: $4} } From d4112ea7410bf062a32a969b90d93d32e46fe9b8 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Mon, 24 May 2021 09:07:07 -0700 Subject: [PATCH 168/310] Revert "backup: Use pargzip instead of pgzip for compression." This reverts commit d2f2d09f032c81d38a2b93d204c9685b721b7bd4. Signed-off-by: Rafael Chacon --- go.mod | 1 - go.sum | 2 -- go/vt/mysqlctl/builtinbackupengine.go | 12 ++++++------ go/vt/mysqlctl/xtrabackupengine.go | 16 ++++++++-------- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index f074e7dbfc2..87b00679aa9 100644 --- a/go.mod +++ b/go.mod @@ -77,7 +77,6 @@ require ( github.com/philhofer/fwd v1.0.0 // indirect github.com/pires/go-proxyproto v0.0.0-20191211124218-517ecdf5bb2b github.com/pkg/errors v0.9.1 - github.com/planetscale/pargzip v0.0.0-20201116224723-90c7fc03ea8a github.com/prometheus/client_golang v1.4.1 github.com/prometheus/common v0.9.1 github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 diff --git a/go.sum b/go.sum index efcf79e5849..cdf89b0e11c 100644 --- a/go.sum +++ b/go.sum @@ -556,8 +556,6 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/planetscale/pargzip v0.0.0-20201116224723-90c7fc03ea8a h1:y0OpQ4+5tKxeh9+H+2cVgASl9yMZYV9CILinKOiKafA= -github.com/planetscale/pargzip v0.0.0-20201116224723-90c7fc03ea8a/go.mod h1:GJFUzQuXIoB2Kjn1ZfDhJr/42D5nWOqRcIQVgCxTuIE= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/go/vt/mysqlctl/builtinbackupengine.go b/go/vt/mysqlctl/builtinbackupengine.go index 1e727f5afcf..21813144c88 100644 --- a/go/vt/mysqlctl/builtinbackupengine.go +++ b/go/vt/mysqlctl/builtinbackupengine.go @@ -29,7 +29,6 @@ import ( "time" "github.com/klauspost/pgzip" - "github.com/planetscale/pargzip" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sync2" @@ -409,12 +408,13 @@ func (be *BuiltinBackupEngine) backupFile(ctx context.Context, params BackupPara } // Create the gzip compression pipe, if necessary. - var gzip *pargzip.Writer + var gzip *pgzip.Writer if *backupStorageCompress { - gzip = pargzip.NewWriter(writer) - gzip.ChunkSize = *backupCompressBlockSize - gzip.Parallel = *backupCompressBlocks - gzip.CompressionLevel = pargzip.BestSpeed + gzip, err = pgzip.NewWriterLevel(writer, pgzip.BestSpeed) + if err != nil { + return vterrors.Wrap(err, "cannot create gziper") + } + gzip.SetConcurrency(*backupCompressBlockSize, *backupCompressBlocks) writer = gzip } diff --git a/go/vt/mysqlctl/xtrabackupengine.go b/go/vt/mysqlctl/xtrabackupengine.go index d0f63b5eed3..3582b777584 100644 --- a/go/vt/mysqlctl/xtrabackupengine.go +++ b/go/vt/mysqlctl/xtrabackupengine.go @@ -32,7 +32,6 @@ import ( "time" "github.com/klauspost/pgzip" - "github.com/planetscale/pargzip" "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/vt/logutil" @@ -271,7 +270,7 @@ func (be *XtrabackupEngine) backupFiles(ctx context.Context, params BackupParams destWriters := []io.Writer{} destBuffers := []*bufio.Writer{} - destCompressors := []io.WriteCloser{} + destCompressors := []*pgzip.Writer{} for _, file := range destFiles { buffer := bufio.NewWriterSize(file, writerBufferSize) destBuffers = append(destBuffers, buffer) @@ -279,10 +278,11 @@ func (be *XtrabackupEngine) backupFiles(ctx context.Context, params BackupParams // Create the gzip compression pipe, if necessary. if *backupStorageCompress { - compressor := pargzip.NewWriter(writer) - compressor.ChunkSize = *backupCompressBlockSize - compressor.Parallel = *backupCompressBlocks - compressor.CompressionLevel = pargzip.BestSpeed + compressor, err := pgzip.NewWriterLevel(writer, pgzip.BestSpeed) + if err != nil { + return replicationPosition, vterrors.Wrap(err, "cannot create gzip compressor") + } + compressor.SetConcurrency(*backupCompressBlockSize, *backupCompressBlocks) writer = compressor destCompressors = append(destCompressors, compressor) } @@ -520,7 +520,7 @@ func (be *XtrabackupEngine) extractFiles(ctx context.Context, logger logutil.Log }() srcReaders := []io.Reader{} - srcDecompressors := []io.ReadCloser{} + srcDecompressors := []*pgzip.Reader{} for _, file := range srcFiles { reader := io.Reader(file) @@ -734,7 +734,7 @@ func copyToStripes(writers []io.Writer, reader io.Reader, blockSize int64) (writ } // Read blocks from source and round-robin them to destination writers. - // Since we put a buffer in front of the destination file, and pargzip has its + // Since we put a buffer in front of the destination file, and pgzip has its // own buffer as well, we are writing into a buffer either way (whether a // compressor is in the chain or not). That means these writes should not // block often, so we shouldn't need separate goroutines here. From 69e45ca93c35bcf596bcb7b1070400f081b8edd1 Mon Sep 17 00:00:00 2001 From: Anton Tiurin Date: Wed, 5 May 2021 22:05:24 +0100 Subject: [PATCH 169/310] Add OptionalTLS grpc TransportCredentials Implement TransportCredentials that allows a server to accept both TLS and plain-text connections at the same time on the same endpoint. To detect a connection type TransportCredentials inspects the first 6 bytes read from a socket and compares them against bytes in TLS prefix. A TLS prefix is different from plain-text HTTP2 prefix. Signed-off-by: Anton Tiurin --- go/vt/grpcoptionaltls/certificates_test.go | 53 +++++++++ go/vt/grpcoptionaltls/conn_wrapper.go | 38 +++++++ go/vt/grpcoptionaltls/optionaltls.go | 58 ++++++++++ go/vt/grpcoptionaltls/server_test.go | 119 +++++++++++++++++++++ go/vt/grpcoptionaltls/tls_detector.go | 50 +++++++++ go/vt/servenv/grpc_server.go | 6 ++ 6 files changed, 324 insertions(+) create mode 100755 go/vt/grpcoptionaltls/certificates_test.go create mode 100755 go/vt/grpcoptionaltls/conn_wrapper.go create mode 100755 go/vt/grpcoptionaltls/optionaltls.go create mode 100755 go/vt/grpcoptionaltls/server_test.go create mode 100755 go/vt/grpcoptionaltls/tls_detector.go diff --git a/go/vt/grpcoptionaltls/certificates_test.go b/go/vt/grpcoptionaltls/certificates_test.go new file mode 100755 index 00000000000..2a5a37efb96 --- /dev/null +++ b/go/vt/grpcoptionaltls/certificates_test.go @@ -0,0 +1,53 @@ +/* +Copyright 2019 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 grpcoptionaltls + +import "strings" + +// LocalhostCert is a PEM-encoded TLS cert with SAN IPs +// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT. +// generated from src/crypto/tls: +// go run generate_cert.go --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h +var localhostCert = []byte(`-----BEGIN CERTIFICATE----- +MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS +MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw +MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4 +iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul +rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO +BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw +AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA +AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9 +tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs +h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM +fblo6RBxUQ== +-----END CERTIFICATE-----`) + +// LocalhostKey is the private key for localhostCert. +var localhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY----- +MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9 +SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB +l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB +AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet +3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb +uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H +qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp +jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY +fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U +fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU +y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX +qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo +f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== +-----END RSA TESTING KEY-----`)) + +func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/go/vt/grpcoptionaltls/conn_wrapper.go b/go/vt/grpcoptionaltls/conn_wrapper.go new file mode 100755 index 00000000000..5659a9170f3 --- /dev/null +++ b/go/vt/grpcoptionaltls/conn_wrapper.go @@ -0,0 +1,38 @@ +/* +Copyright 2019 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 grpcoptionaltls + +import ( + "bytes" + "io" + "net" +) + +// WrappedConn imitates MSG_PEEK behaviour +// Unlike net.Conn is not thread-safe for reading already peeked bytes +type WrappedConn struct { + net.Conn + rd io.Reader +} + +func NewWrappedConn(conn net.Conn, peeked []byte) net.Conn { + var rd = io.MultiReader(bytes.NewReader(peeked), conn) + return &WrappedConn{ + Conn: conn, + rd: rd, + } +} + +func (wc *WrappedConn) Read(b []byte) (n int, err error) { + return wc.rd.Read(b) +} diff --git a/go/vt/grpcoptionaltls/optionaltls.go b/go/vt/grpcoptionaltls/optionaltls.go new file mode 100755 index 00000000000..c18f80412a6 --- /dev/null +++ b/go/vt/grpcoptionaltls/optionaltls.go @@ -0,0 +1,58 @@ +/* +Copyright 2019 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 grpcoptionaltls + +import ( + "net" + + "google.golang.org/grpc/credentials" +) + +type optionalTLSCreds struct { + credentials.TransportCredentials +} + +func (c *optionalTLSCreds) Clone() credentials.TransportCredentials { + return New(c.TransportCredentials.Clone()) +} + +func (c *optionalTLSCreds) ServerHandshake(conn net.Conn) (net.Conn, credentials.AuthInfo, error) { + isTLS, bytes, err := DetectTLS(conn) + if err != nil { + conn.Close() + return nil, nil, err + } + + var wc net.Conn = NewWrappedConn(conn, bytes) + if isTLS { + return c.TransportCredentials.ServerHandshake(wc) + } + + var authInfo = info{ + CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.NoSecurity}, + } + + return wc, authInfo, nil +} + +func New(tc credentials.TransportCredentials) credentials.TransportCredentials { + return &optionalTLSCreds{TransportCredentials: tc} +} + +type info struct { + credentials.CommonAuthInfo +} + +func (info) AuthType() string { + return "insecure" +} diff --git a/go/vt/grpcoptionaltls/server_test.go b/go/vt/grpcoptionaltls/server_test.go new file mode 100755 index 00000000000..b0e6d6efdbb --- /dev/null +++ b/go/vt/grpcoptionaltls/server_test.go @@ -0,0 +1,119 @@ +/* +Copyright 2019 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 grpcoptionaltls + +import ( + "context" + "crypto/tls" + "crypto/x509" + "net" + "testing" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/credentials" + pb "google.golang.org/grpc/examples/helloworld/helloworld" +) + +// server is used to implement helloworld.GreeterServer. +type server struct { + pb.UnimplementedGreeterServer +} + +// SayHello implements helloworld.GreeterServer +func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { + return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil +} + +func createUnstartedServer(creds credentials.TransportCredentials) *grpc.Server { + s := grpc.NewServer(grpc.Creds(creds)) + pb.RegisterGreeterServer(s, &server{}) + return s +} + +type testCredentials struct { + client credentials.TransportCredentials + server credentials.TransportCredentials +} + +func createCredentials() (*testCredentials, error) { + cert, err := tls.X509KeyPair(localhostCert, localhostKey) + if err != nil { + return nil, err + } + + certificate, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + return nil, err + } + certpool := x509.NewCertPool() + certpool.AddCert(certificate) + + tc := &testCredentials{ + client: credentials.NewClientTLSFromCert(certpool, "example.com"), + server: credentials.NewServerTLSFromCert(&cert), + } + return tc, nil +} + +func TestOptionalTLS(t *testing.T) { + testCtx, testCancel := context.WithCancel(context.Background()) + defer testCancel() + + tc, err := createCredentials() + if err != nil { + t.Fatalf("failed to create credentials %v", err) + } + + lis, err := net.Listen("tcp", "") + if err != nil { + t.Fatalf("failed to listen %v", err) + } + defer lis.Close() + addr := lis.Addr().String() + + srv := createUnstartedServer(New(tc.server)) + go func() { + srv.Serve(lis) + }() + defer srv.Stop() + + testFunc := func(t *testing.T, dialOpt grpc.DialOption) { + ctx, cancel := context.WithTimeout(testCtx, 5*time.Second) + defer cancel() + conn, err := grpc.DialContext(ctx, addr, dialOpt) + if err != nil { + t.Fatalf("failed to connect to the server %v", err) + } + defer conn.Close() + c := pb.NewGreeterClient(conn) + resp, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Vittes"}) + if err != nil { + t.Fatalf("could not greet: %v", err) + } + if resp.Message != "Hello Vittes" { + t.Fatalf("unexpected reply %s", resp.Message) + } + } + + t.Run("Plain2TLS", func(t *testing.T) { + for i := 0; i < 5; i += 1 { + testFunc(t, grpc.WithInsecure()) + } + }) + t.Run("TLS2TLS", func(t *testing.T) { + for i := 0; i < 5; i += 1 { + testFunc(t, grpc.WithTransportCredentials(tc.client)) + } + }) +} diff --git a/go/vt/grpcoptionaltls/tls_detector.go b/go/vt/grpcoptionaltls/tls_detector.go new file mode 100755 index 00000000000..beff6bfd740 --- /dev/null +++ b/go/vt/grpcoptionaltls/tls_detector.go @@ -0,0 +1,50 @@ +/* +Copyright 2019 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 grpcoptionaltls + +import "io" + +const TLSPeekedBytes = 6 + +func looksLikeTLS(bytes []byte) bool { + if len(bytes) < TLSPeekedBytes { + return false + } + // TLS starts as + // 0: 0x16 - handshake protocol magic + // 1: 0x03 - SSL version major + // 2: 0x00 to 0x03 - SSL version minor (SSLv3 or TLS1.0 through TLS1.3) + // 3-4: length (2 bytes) + // 5: 0x01 - handshake type (ClientHello) + // 6-8: handshake len (3 bytes), equals value from offset 3-4 minus 4 + // HTTP2 initial frame bytes + // https://tools.ietf.org/html/rfc7540#section-3.4 + + // Definitely not TLS + if bytes[0] != 0x16 || bytes[1] != 0x03 || bytes[5] != 0x01 { + return false + } + return true +} + +// DetectTLS reads necessary number of bytes from io.Reader +// returns result, bytes read from Reader and error +// No matter if error happens or what flag value is +// returned bytes should be checked +func DetectTLS(r io.Reader) (bool, []byte, error) { + var bytes = make([]byte, TLSPeekedBytes) + if n, err := io.ReadFull(r, bytes); err != nil { + return false, bytes[:n], err + } + return looksLikeTLS(bytes), bytes, nil +} diff --git a/go/vt/servenv/grpc_server.go b/go/vt/servenv/grpc_server.go index 98268a50942..d58eb87b026 100644 --- a/go/vt/servenv/grpc_server.go +++ b/go/vt/servenv/grpc_server.go @@ -35,6 +35,7 @@ import ( "context" "vitess.io/vitess/go/vt/grpccommon" + "vitess.io/vitess/go/vt/grpcoptionaltls" "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/vttls" ) @@ -64,6 +65,8 @@ var ( // GRPCCA is the CA to use if TLS is enabled GRPCCA = flag.String("grpc_ca", "", "server CA to use for gRPC connections, requires TLS, and enforces client certificate check") + GRPCEnableOptionalTLS = flag.Bool("grpc_enable_optional_tls", false, "enable optional TLS mode when a server accepts both TLS and plain-text connections on the same port") + // GRPCServerCA if specified will combine server cert and server CA GRPCServerCA = flag.String("grpc_server_ca", "", "path to server CA in PEM format, which will be combine with server cert, return full certificate chain to clients") @@ -135,6 +138,9 @@ func createGRPCServer() { // create the creds server options creds := credentials.NewTLS(config) + if *GRPCEnableOptionalTLS { + creds = grpcoptionaltls.New(creds) + } opts = []grpc.ServerOption{grpc.Creds(creds)} } // Override the default max message size for both send and receive From 4e690bd1d9747a6302d1d7f9e212914aaf7f21ea Mon Sep 17 00:00:00 2001 From: Anton Tiurin Date: Wed, 5 May 2021 23:33:58 +0100 Subject: [PATCH 170/310] address feedback use go/vt/tlstest to generate certificates log warning message when the option is on Signed-off-by: Anton Tiurin --- go/vt/grpcoptionaltls/certificates_test.go | 53 ---------------------- go/vt/grpcoptionaltls/server_test.go | 20 +++++--- go/vt/servenv/grpc_server.go | 1 + 3 files changed, 15 insertions(+), 59 deletions(-) delete mode 100755 go/vt/grpcoptionaltls/certificates_test.go diff --git a/go/vt/grpcoptionaltls/certificates_test.go b/go/vt/grpcoptionaltls/certificates_test.go deleted file mode 100755 index 2a5a37efb96..00000000000 --- a/go/vt/grpcoptionaltls/certificates_test.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2019 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 grpcoptionaltls - -import "strings" - -// LocalhostCert is a PEM-encoded TLS cert with SAN IPs -// "127.0.0.1" and "[::1]", expiring at Jan 29 16:00:00 2084 GMT. -// generated from src/crypto/tls: -// go run generate_cert.go --rsa-bits 1024 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h -var localhostCert = []byte(`-----BEGIN CERTIFICATE----- -MIICEzCCAXygAwIBAgIQMIMChMLGrR+QvmQvpwAU6zANBgkqhkiG9w0BAQsFADAS -MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw -MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB -iQKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9SjY1bIw4 -iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZBl2+XsDul -rKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQABo2gwZjAO -BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw -AwEB/zAuBgNVHREEJzAlggtleGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAA -AAAAATANBgkqhkiG9w0BAQsFAAOBgQCEcetwO59EWk7WiJsG4x8SY+UIAA+flUI9 -tyC4lNhbcF2Idq9greZwbYCqTTTr2XiRNSMLCOjKyI7ukPoPjo16ocHj+P3vZGfs -h1fIw3cSS2OolhloGw/XM6RWPWtPAlGykKLciQrBru5NAPvCMsb/I1DAceTiotQM -fblo6RBxUQ== ------END CERTIFICATE-----`) - -// LocalhostKey is the private key for localhostCert. -var localhostKey = []byte(testingKey(`-----BEGIN RSA TESTING KEY----- -MIICXgIBAAKBgQDuLnQAI3mDgey3VBzWnB2L39JUU4txjeVE6myuDqkM/uGlfjb9 -SjY1bIw4iA5sBBZzHi3z0h1YV8QPuxEbi4nW91IJm2gsvvZhIrCHS3l6afab4pZB -l2+XsDulrKBxKKtD1rGxlG4LjncdabFn9gvLZad2bSysqz/qTAUStTvqJQIDAQAB -AoGAGRzwwir7XvBOAy5tM/uV6e+Zf6anZzus1s1Y1ClbjbE6HXbnWWF/wbZGOpet -3Zm4vD6MXc7jpTLryzTQIvVdfQbRc6+MUVeLKwZatTXtdZrhu+Jk7hx0nTPy8Jcb -uJqFk541aEw+mMogY/xEcfbWd6IOkp+4xqjlFLBEDytgbIECQQDvH/E6nk+hgN4H -qzzVtxxr397vWrjrIgPbJpQvBsafG7b0dA4AFjwVbFLmQcj2PprIMmPcQrooz8vp -jy4SHEg1AkEA/v13/5M47K9vCxmb8QeD/asydfsgS5TeuNi8DoUBEmiSJwma7FXY -fFUtxuvL7XvjwjN5B30pNEbc6Iuyt7y4MQJBAIt21su4b3sjXNueLKH85Q+phy2U -fQtuUE9txblTu14q3N7gHRZB4ZMhFYyDy8CKrN2cPg/Fvyt0Xlp/DoCzjA0CQQDU -y2ptGsuSmgUtWj3NM9xuwYPm+Z/F84K6+ARYiZ6PYj013sovGKUFfYAqVXVlxtIX -qyUBnu3X9ps8ZfjLZO7BAkEAlT4R5Yl6cGhaJQYZHOde3JEMhNRcVFMO8dJDaFeo -f9Oeos0UUothgiDktdQHxdNEwLjQf7lJJBzV+5OtwswCWA== ------END RSA TESTING KEY-----`)) - -func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") } diff --git a/go/vt/grpcoptionaltls/server_test.go b/go/vt/grpcoptionaltls/server_test.go index b0e6d6efdbb..a0f6e6c8ea0 100755 --- a/go/vt/grpcoptionaltls/server_test.go +++ b/go/vt/grpcoptionaltls/server_test.go @@ -15,14 +15,17 @@ package grpcoptionaltls import ( "context" "crypto/tls" - "crypto/x509" + "io/ioutil" "net" + "os" "testing" "time" "google.golang.org/grpc" "google.golang.org/grpc/credentials" pb "google.golang.org/grpc/examples/helloworld/helloworld" + + "vitess.io/vitess/go/vt/tlstest" ) // server is used to implement helloworld.GreeterServer. @@ -47,20 +50,25 @@ type testCredentials struct { } func createCredentials() (*testCredentials, error) { - cert, err := tls.X509KeyPair(localhostCert, localhostKey) + // Create a temporary directory. + certDir, err := ioutil.TempDir("", "optionaltls_grpc_test") if err != nil { return nil, err } + defer os.RemoveAll(certDir) - certificate, err := x509.ParseCertificate(cert.Certificate[0]) + certs := tlstest.CreateClientServerCertPairs(certDir) + cert, err := tls.LoadX509KeyPair(certs.ServerCert, certs.ServerKey) if err != nil { return nil, err } - certpool := x509.NewCertPool() - certpool.AddCert(certificate) + clientCredentials, err := credentials.NewClientTLSFromFile(certs.ServerCA, certs.ServerName) + if err != nil { + return nil, err + } tc := &testCredentials{ - client: credentials.NewClientTLSFromCert(certpool, "example.com"), + client: clientCredentials, server: credentials.NewServerTLSFromCert(&cert), } return tc, nil diff --git a/go/vt/servenv/grpc_server.go b/go/vt/servenv/grpc_server.go index d58eb87b026..feae9a0e6ef 100644 --- a/go/vt/servenv/grpc_server.go +++ b/go/vt/servenv/grpc_server.go @@ -139,6 +139,7 @@ func createGRPCServer() { // create the creds server options creds := credentials.NewTLS(config) if *GRPCEnableOptionalTLS { + log.Warning("Optional TLS is active. Plain-text connections will be accepted") creds = grpcoptionaltls.New(creds) } opts = []grpc.ServerOption{grpc.Creds(creds)} From 599a4555b23233ac582439d9adcb5a13628b8678 Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 4 May 2021 11:57:01 +0200 Subject: [PATCH 171/310] Added release script to the makefile Signed-off-by: Andres Taylor --- Makefile | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/Makefile b/Makefile index b499fc76775..c747c1c0d9d 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ # limitations under the License. MAKEFLAGS = -s +GIT_STATUS := $(shell git status --porcelain) export GOBIN=$(PWD)/bin export GO111MODULE=on @@ -268,6 +269,43 @@ release: docker_base echo "git push origin v$(VERSION)" echo "Also, don't forget the upload releases/v$(VERSION).tar.gz file to GitHub releases" +do_release: +ifndef RELEASE_VERSION + echo "Set the env var RELEASE_VERSION with the release version" + exit 1 +endif +ifndef DEV_VERSION + echo "Set the env var DEV_VERSION with the version the dev branch should have after release" + exit 1 +endif +ifeq ($(strip $(GIT_STATUS)),) + echo so much clean +else + echo cannot do release with dirty git state + exit 1 + echo so much win +endif +# Pre checks passed. Let's change the current version + cd java && mvn versions:set -DnewVersion=$(RELEASE_VERSION) + echo package servenv > go/vt/servenv/version.go + echo >> go/vt/servenv/version.go + echo const versionName = \"$(RELEASE_VERSION)\" >> go/vt/servenv/version.go + echo -n Pausing so relase notes can be added. Press enter to continue + read line + git add --all + git commit -n -s -m "Release commit for $(RELEASE_VERSION)" + git tag -m Version\ $(RELEASE_VERSION) v$(RELEASE_VERSION) + cd java && mvn versions:set -DnewVersion=$(DEV_VERSION) + echo package servenv > go/vt/servenv/version.go + echo >> go/vt/servenv/version.go + echo const versionName = \"$(DEV_VERSION)\" >> go/vt/servenv/version.go + git add --all + git commit -n -s -m "Back to dev mode" + echo "Release preparations successful" + echo "A git tag was created, you can push it with:" + echo " git push upstream v$(RELEASE_VERSION)" + echo "The git branch has also been updated. You need to push it and get it merged" + tools: echo $$(date): Installing dependencies ./bootstrap.sh From ffd4b9e8c06a856f0a00779f316ca4435c80198d Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Tue, 25 May 2021 11:12:40 +0200 Subject: [PATCH 172/310] Update do_release to work in the 9.0 branch Signed-off-by: Andres Taylor --- Makefile | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Makefile b/Makefile index c747c1c0d9d..9d0cc7a2ef3 100644 --- a/Makefile +++ b/Makefile @@ -287,18 +287,12 @@ else endif # Pre checks passed. Let's change the current version cd java && mvn versions:set -DnewVersion=$(RELEASE_VERSION) - echo package servenv > go/vt/servenv/version.go - echo >> go/vt/servenv/version.go - echo const versionName = \"$(RELEASE_VERSION)\" >> go/vt/servenv/version.go echo -n Pausing so relase notes can be added. Press enter to continue read line git add --all git commit -n -s -m "Release commit for $(RELEASE_VERSION)" git tag -m Version\ $(RELEASE_VERSION) v$(RELEASE_VERSION) cd java && mvn versions:set -DnewVersion=$(DEV_VERSION) - echo package servenv > go/vt/servenv/version.go - echo >> go/vt/servenv/version.go - echo const versionName = \"$(DEV_VERSION)\" >> go/vt/servenv/version.go git add --all git commit -n -s -m "Back to dev mode" echo "Release preparations successful" From 58cd7b0dc4527d568b3c3988604a41aaf4508fda Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 25 May 2021 13:49:30 +0300 Subject: [PATCH 173/310] Release commit for 9.0.2 Signed-off-by: Alkin Tezuysal --- doc/releasenotes/9_0_2_release_notes.md | 20 ++++++++++++++++++++ java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 doc/releasenotes/9_0_2_release_notes.md diff --git a/doc/releasenotes/9_0_2_release_notes.md b/doc/releasenotes/9_0_2_release_notes.md new file mode 100644 index 00000000000..14749b0069b --- /dev/null +++ b/doc/releasenotes/9_0_2_release_notes.md @@ -0,0 +1,20 @@ +## Bug fixes +### Cluster management + * Restore: Check disable_active_reparents properly before waiting for position update #8114 +### Query Serving + * Fix information_schema query with system schema in table_schema filter #8095 + * Fix for issue with information_schema queries with both table name and schema name predicates #8096 + * Fix for transactions not allowed to finish during PlannedReparentShard #8098 + * PRIMARY in index hint list #8158 +## CI/Build +### Build/CI + * Release 9.0.1 #8065 + * 9.0.0: update release notes with known issue #8080 #8082 + * Added release script to the makefile #8182 + * Update do_release to work in the 9.0 branch #8184 +## Performance +### Cluster management + * Revert "backup: Use pargzip instead of pgzip for compression." #8174 + +The release includes 17 commits (excluding merges) +Thanks to all our contributors: @GuptaManan100, @deepthi, @Harshit, @rafael, @systay diff --git a/java/client/pom.xml b/java/client/pom.xml index 188cea73f35..3aa57319115 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2-SNAPSHOT + 9.0.2 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index ceef8a55a18..7d761c62173 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2-SNAPSHOT + 9.0.2 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index f53519e6e28..158990c08a9 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2-SNAPSHOT + 9.0.2 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index c6c2a629c91..9b16abfb305 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2-SNAPSHOT + 9.0.2 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 16c1a4b4915..d68d0658532 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 9.0.2-SNAPSHOT + 9.0.2 pom Vitess Java Client libraries [Parent] From 2a4f7b467af57e22182df3ed7650e784f5203783 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Tue, 25 May 2021 13:49:33 +0300 Subject: [PATCH 174/310] Back to dev mode Signed-off-by: Alkin Tezuysal --- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/java/client/pom.xml b/java/client/pom.xml index 3aa57319115..2acf6473779 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2 + 9.0.3-SNAPSHOT vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index 7d761c62173..e8f53f4fa04 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2 + 9.0.3-SNAPSHOT vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 158990c08a9..e2413cd7b63 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2 + 9.0.3-SNAPSHOT vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 9b16abfb305..2f414226e69 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 9.0.2 + 9.0.3-SNAPSHOT vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index d68d0658532..5051661e026 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 9.0.2 + 9.0.3-SNAPSHOT pom Vitess Java Client libraries [Parent] From 1db8a4d278aef2c034e3976777f2fe57f1ae7e02 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 26 May 2021 15:58:25 +0530 Subject: [PATCH 175/310] check for topo.Error before clearing the cache value Signed-off-by: Harshit Gangal --- go/vt/srvtopo/resilient_server.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/srvtopo/resilient_server.go b/go/vt/srvtopo/resilient_server.go index cdb8b9c12e8..33f84cc38c9 100644 --- a/go/vt/srvtopo/resilient_server.go +++ b/go/vt/srvtopo/resilient_server.go @@ -20,7 +20,6 @@ import ( "flag" "fmt" "html/template" - "net/url" "sort" "sync" "time" @@ -470,8 +469,9 @@ func (server *ResilientServer) watchSrvKeyspace(callerCtx context.Context, entry log.Errorf("Initial WatchSrvKeyspace failed for %v/%v: %v", cell, keyspace, current.Err) // This watcher will able to continue to return the last value till it is not able to connect to the topo server even if the cache TTL is reached. - _, netErr := current.Err.(*url.Error) - if !netErr && time.Since(entry.lastValueTime) > server.cacheTTL { + // TTL cache is only checked if the error is a known error i.e topo.Error. + _, topoErr := current.Err.(*topo.Error) + if topoErr && time.Since(entry.lastValueTime) > server.cacheTTL { log.Errorf("WatchSrvKeyspace clearing cached entry for %v/%v", cell, keyspace) entry.value = nil } From 0522f64ed8330eb9efedc2b5c6df14474ff57e30 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Wed, 26 May 2021 20:06:34 +0530 Subject: [PATCH 176/310] added an end to end test for testing the change and fixed consul startup for testing Signed-off-by: GuptaManan100 Co-authored-by: harshit-gangal --- go/test/endtoend/cluster/topo_process.go | 52 ++++++++++++++++--- go/test/endtoend/topotest/consul/main_test.go | 44 ++++++++++++++-- 2 files changed, 87 insertions(+), 9 deletions(-) diff --git a/go/test/endtoend/cluster/topo_process.go b/go/test/endtoend/cluster/topo_process.go index 01c90906482..ae315bd2534 100644 --- a/go/test/endtoend/cluster/topo_process.go +++ b/go/test/endtoend/cluster/topo_process.go @@ -17,6 +17,7 @@ limitations under the License. package cluster import ( + "encoding/json" "fmt" "io/ioutil" "net/http" @@ -147,25 +148,62 @@ func (topo *TopoProcess) SetupZookeeper(cluster *LocalProcessCluster) (err error return } +// ConsulConfigs are the configurations that are added the config files which are used by consul +type ConsulConfigs struct { + Ports PortsInfo `json:"ports"` + DataDir string `json:"data_dir"` + LogFile string `json:"log_file"` +} + +// PortsInfo is the different ports used by consul +type PortsInfo struct { + DNS int `json:"dns"` + HTTP int `json:"http"` + SerfLan int `json:"serf_lan"` + SerfWan int `json:"serf_wan"` +} + // SetupConsul spawns a new consul service and initializes it with the defaults. // The service is kept running in the background until TearDown() is called. func (topo *TopoProcess) SetupConsul(cluster *LocalProcessCluster) (err error) { topo.VerifyURL = fmt.Sprintf("http://%s:%d/v1/kv/?keys", topo.Host, topo.Port) + _ = os.MkdirAll(topo.LogDirectory, os.ModePerm) + _ = os.MkdirAll(topo.DataDirectory, os.ModePerm) + configFile := path.Join(os.Getenv("VTDATAROOT"), "consul.json") - config := fmt.Sprintf(`{"ports":{"dns":%d,"http":%d,"serf_lan":%d,"serf_wan":%d}}`, - cluster.GetAndReservePort(), topo.Port, cluster.GetAndReservePort(), cluster.GetAndReservePort()) + logFile := path.Join(topo.LogDirectory, "/consul.log") + _, _ = os.Create(logFile) + + var config []byte + configs := ConsulConfigs{ + Ports: PortsInfo{ + DNS: cluster.GetAndReservePort(), + HTTP: topo.Port, + SerfLan: cluster.GetAndReservePort(), + SerfWan: cluster.GetAndReservePort(), + }, + DataDir: topo.DataDirectory, + LogFile: logFile, + } + config, err = json.Marshal(configs) + if err != nil { + log.Error(err.Error()) + return + } - err = ioutil.WriteFile(configFile, []byte(config), 0666) + err = ioutil.WriteFile(configFile, config, 0666) if err != nil { return } topo.proc = exec.Command( topo.Binary, "agent", - "-dev", + "-server", + "-ui", + "-bootstrap-expect=1", "-config-file", configFile, ) @@ -225,7 +263,9 @@ func (topo *TopoProcess) TearDown(Cell string, originalVtRoot string, currentRoo return nil } - topo.removeTopoDirectories(Cell) + if !(*keepData || keepdata) { + topo.removeTopoDirectories(Cell) + } // Attempt graceful shutdown with SIGTERM first _ = topo.proc.Process.Signal(syscall.SIGTERM) @@ -233,8 +273,8 @@ func (topo *TopoProcess) TearDown(Cell string, originalVtRoot string, currentRoo if !(*keepData || keepdata) { _ = os.RemoveAll(topo.DataDirectory) _ = os.RemoveAll(currentRoot) + _ = os.Setenv("VTDATAROOT", originalVtRoot) } - _ = os.Setenv("VTDATAROOT", originalVtRoot) select { case <-topo.exit: diff --git a/go/test/endtoend/topotest/consul/main_test.go b/go/test/endtoend/topotest/consul/main_test.go index f805c7c00b0..2b32220bb1a 100644 --- a/go/test/endtoend/topotest/consul/main_test.go +++ b/go/test/endtoend/topotest/consul/main_test.go @@ -107,7 +107,7 @@ func TestTopoDownServingQuery(t *testing.T) { require.Nil(t, err) defer conn.Close() - defer exec(t, conn, `delete from t1`) + defer execute(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)]]`) @@ -116,7 +116,45 @@ func TestTopoDownServingQuery(t *testing.T) { assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) } -func exec(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { +func TestTopoRestart(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() + + 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)]]`) + + defer execute(t, conn, `delete from t1`) + + ch := make(chan interface{}) + + go func() { + clusterInstance.TopoProcess.TearDown(clusterInstance.Cell, clusterInstance.OriginalVTDATAROOT, clusterInstance.CurrentVTDATAROOT, true, *clusterInstance.TopoFlavorString()) + clusterInstance.TopoProcess.Setup(*clusterInstance.TopoFlavorString(), clusterInstance) + ch <- 1 + }() + + timeOut := time.After(5 * time.Second) + + for { + select { + case <-ch: + return + case <-timeOut: + require.Fail(t, "timed out - topo process did not come up") + case <-time.After(100 * time.Millisecond): + assertMatches(t, conn, `select c1,c2,c3 from t1`, `[[INT64(300) INT64(100) INT64(300)] [INT64(301) INT64(101) INT64(301)]]`) + } + } +} + +func execute(t *testing.T, conn *mysql.Conn, query string) *sqltypes.Result { t.Helper() qr, err := conn.ExecuteFetch(query, 1000, true) require.NoError(t, err) @@ -139,7 +177,7 @@ func execMulti(t *testing.T, conn *mysql.Conn, query string) []*sqltypes.Result func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() - qr := exec(t, conn, query) + qr := execute(t, conn, query) got := fmt.Sprintf("%v", qr.Rows) diff := cmp.Diff(expected, got) if diff != "" { From 1285c6818f3331c74220c08420e332628ffbcdea Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 27 May 2021 10:26:35 +0530 Subject: [PATCH 177/310] reload test has both the tests Signed-off-by: Harshit Gangal --- go/test/endtoend/topotest/consul/main_test.go | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/go/test/endtoend/topotest/consul/main_test.go b/go/test/endtoend/topotest/consul/main_test.go index 2b32220bb1a..a0de8f56c49 100644 --- a/go/test/endtoend/topotest/consul/main_test.go +++ b/go/test/endtoend/topotest/consul/main_test.go @@ -96,26 +96,6 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -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 execute(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 TestTopoRestart(t *testing.T) { defer cluster.PanicHandler(t) ctx := context.Background() @@ -136,7 +116,13 @@ func TestTopoRestart(t *testing.T) { go func() { clusterInstance.TopoProcess.TearDown(clusterInstance.Cell, clusterInstance.OriginalVTDATAROOT, clusterInstance.CurrentVTDATAROOT, true, *clusterInstance.TopoFlavorString()) + + // Some sleep to server few queries when topo is down. + time.Sleep(400 * time.Millisecond) + clusterInstance.TopoProcess.Setup(*clusterInstance.TopoFlavorString(), clusterInstance) + + // topo is up now. ch <- 1 }() From 63fd53fa82b02e7a4951378bf70485636747694a Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 27 May 2021 10:27:26 +0530 Subject: [PATCH 178/310] check for topo.Error and not *topo.Error, fix unit test to send the correct error type Signed-off-by: Harshit Gangal --- go/vt/srvtopo/resilient_server.go | 4 ++-- go/vt/srvtopo/resilient_server_test.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go/vt/srvtopo/resilient_server.go b/go/vt/srvtopo/resilient_server.go index 33f84cc38c9..e2508978caa 100644 --- a/go/vt/srvtopo/resilient_server.go +++ b/go/vt/srvtopo/resilient_server.go @@ -466,11 +466,11 @@ func (server *ResilientServer) watchSrvKeyspace(callerCtx context.Context, entry } server.counts.Add(errorCategory, 1) - log.Errorf("Initial WatchSrvKeyspace failed for %v/%v: %v", cell, keyspace, current.Err) + log.Errorf("Initial WatchSrvKeyspace failed for %v/%v: %T %v", cell, keyspace, current.Err, current.Err) // This watcher will able to continue to return the last value till it is not able to connect to the topo server even if the cache TTL is reached. // TTL cache is only checked if the error is a known error i.e topo.Error. - _, topoErr := current.Err.(*topo.Error) + _, topoErr := current.Err.(topo.Error) if topoErr && time.Since(entry.lastValueTime) > server.cacheTTL { log.Errorf("WatchSrvKeyspace clearing cached entry for %v/%v", cell, keyspace) entry.value = nil diff --git a/go/vt/srvtopo/resilient_server_test.go b/go/vt/srvtopo/resilient_server_test.go index 59dd818cb3d..cd16808a5d3 100644 --- a/go/vt/srvtopo/resilient_server_test.go +++ b/go/vt/srvtopo/resilient_server_test.go @@ -141,7 +141,7 @@ func TestGetSrvKeyspace(t *testing.T) { // cached for at least half of the expected ttl. errorTestStart := time.Now() errorReqsBefore := rs.counts.Counts()[errorCategory] - forceErr := fmt.Errorf("test topo error") + forceErr := topo.NewError(topo.Timeout, "test topo error") factory.SetError(forceErr) expiry = time.Now().Add(*srvTopoCacheTTL / 2) @@ -200,7 +200,7 @@ func TestGetSrvKeyspace(t *testing.T) { // that even when there is no activity on the key, it is still cached // for the full configured TTL. time.Sleep(*srvTopoCacheTTL) - forceErr = fmt.Errorf("another test topo error") + forceErr = topo.NewError(topo.Interrupted, "another test topo error") factory.SetError(forceErr) expiry = time.Now().Add(*srvTopoCacheTTL / 2) From 384384ab95851506d9016127de4620aad2de6385 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 27 May 2021 11:38:16 +0530 Subject: [PATCH 179/310] changed default server port in consul setup to allow running multiple servers simultaneously Signed-off-by: GuptaManan100 --- go/test/endtoend/cluster/topo_process.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/go/test/endtoend/cluster/topo_process.go b/go/test/endtoend/cluster/topo_process.go index ae315bd2534..75c6f6ac8d7 100644 --- a/go/test/endtoend/cluster/topo_process.go +++ b/go/test/endtoend/cluster/topo_process.go @@ -161,6 +161,7 @@ type PortsInfo struct { HTTP int `json:"http"` SerfLan int `json:"serf_lan"` SerfWan int `json:"serf_wan"` + Server int `json:"server"` } // SetupConsul spawns a new consul service and initializes it with the defaults. @@ -184,6 +185,7 @@ func (topo *TopoProcess) SetupConsul(cluster *LocalProcessCluster) (err error) { HTTP: topo.Port, SerfLan: cluster.GetAndReservePort(), SerfWan: cluster.GetAndReservePort(), + Server: cluster.GetAndReservePort(), }, DataDir: topo.DataDirectory, LogFile: logFile, From 0cafdf490c998d01b3c0d66bdb3977e8bc340179 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 27 May 2021 13:07:41 +0530 Subject: [PATCH 180/310] added bind address to consul args Signed-off-by: Harshit Gangal --- go/test/endtoend/cluster/topo_process.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/go/test/endtoend/cluster/topo_process.go b/go/test/endtoend/cluster/topo_process.go index 75c6f6ac8d7..103cba1508d 100644 --- a/go/test/endtoend/cluster/topo_process.go +++ b/go/test/endtoend/cluster/topo_process.go @@ -205,7 +205,8 @@ func (topo *TopoProcess) SetupConsul(cluster *LocalProcessCluster) (err error) { topo.Binary, "agent", "-server", "-ui", - "-bootstrap-expect=1", + "-bootstrap-expect", "1", + "-bind", "127.0.0.1", "-config-file", configFile, ) @@ -214,7 +215,7 @@ func (topo *TopoProcess) SetupConsul(cluster *LocalProcessCluster) (err error) { topo.proc.Env = append(topo.proc.Env, os.Environ()...) - log.Infof("Starting consul with args %v", strings.Join(topo.proc.Args, " ")) + log.Errorf("Starting consul with args %v", strings.Join(topo.proc.Args, " ")) err = topo.proc.Start() if err != nil { return From fc7847093afae2fbcaa320eb182e2a84620de390 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Thu, 27 May 2021 11:23:38 +0300 Subject: [PATCH 181/310] Release commit for 10.0.2 Signed-off-by: Alkin Tezuysal --- doc/releasenotes/10_0_2_release_notes.md | 24 ++++++++++++++++++++++++ go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 7 files changed, 30 insertions(+), 6 deletions(-) create mode 100644 doc/releasenotes/10_0_2_release_notes.md diff --git a/doc/releasenotes/10_0_2_release_notes.md b/doc/releasenotes/10_0_2_release_notes.md new file mode 100644 index 00000000000..5ff40ef3fee --- /dev/null +++ b/doc/releasenotes/10_0_2_release_notes.md @@ -0,0 +1,24 @@ +## Bug fixes +### Query Serving + * Fixes encoding of sql strings #8029 + * Fix for issue with information_schema queries with both table name and schema name predicates #8099 + * PRIMARY in index hint list for release 10.0 #8159 +### VReplication + * VReplication: Pad binlog values for binary() columns to match the value returned by mysql selects #8137 +## CI/Build +### Build/CI + * update release notes with known issue #8081 +## Documentation +### Other + * Post v10.0.1 updates #8045 +## Enhancement +### Build/CI + * Added release script to the makefile #8030 +### Other + * Add optional TLS feature to gRPC servers #8176 +## Other +### Build/CI + * Release 10.0.1 #8031 + +The release includes 14 commits (excluding merges) +Thanks to all our contributors: @GuptaManan100, @askdba, @deepthi, @harshit-gangal, @noxiouz, @rohit-nayak-ps, @systay diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index 1aaeed280b4..e6d25d406a1 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,3 +1,3 @@ package servenv -const versionName = "10.0.2-SNAPSHOT" +const versionName = "10.0.2" diff --git a/java/client/pom.xml b/java/client/pom.xml index 6290f8f4376..d2251cd577b 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2-SNAPSHOT + 10.0.2 vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index ff8403af132..d0318cee370 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2-SNAPSHOT + 10.0.2 vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 912d5637671..84062137934 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2-SNAPSHOT + 10.0.2 vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 85bff36a1d8..3cfec1ebb03 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2-SNAPSHOT + 10.0.2 vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 074bf254e60..19009d74e50 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 10.0.2-SNAPSHOT + 10.0.2 pom Vitess Java Client libraries [Parent] From 6a5ac3b7c7e9cb75d7fb85d6825894b2d5f8468c Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Thu, 27 May 2021 11:23:40 +0300 Subject: [PATCH 182/310] Back to dev mode Signed-off-by: Alkin Tezuysal --- go/vt/servenv/version.go | 2 +- java/client/pom.xml | 2 +- java/example/pom.xml | 2 +- java/grpc-client/pom.xml | 2 +- java/jdbc/pom.xml | 2 +- java/pom.xml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/vt/servenv/version.go b/go/vt/servenv/version.go index e6d25d406a1..2cb30044a96 100644 --- a/go/vt/servenv/version.go +++ b/go/vt/servenv/version.go @@ -1,3 +1,3 @@ package servenv -const versionName = "10.0.2" +const versionName = "10.0.3-SNAPSHOT" diff --git a/java/client/pom.xml b/java/client/pom.xml index d2251cd577b..1b56e849aaa 100644 --- a/java/client/pom.xml +++ b/java/client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2 + 10.0.3-SNAPSHOT vitess-client diff --git a/java/example/pom.xml b/java/example/pom.xml index d0318cee370..23e9df634e2 100644 --- a/java/example/pom.xml +++ b/java/example/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2 + 10.0.3-SNAPSHOT vitess-example diff --git a/java/grpc-client/pom.xml b/java/grpc-client/pom.xml index 84062137934..543c9356b7a 100644 --- a/java/grpc-client/pom.xml +++ b/java/grpc-client/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2 + 10.0.3-SNAPSHOT vitess-grpc-client diff --git a/java/jdbc/pom.xml b/java/jdbc/pom.xml index 3cfec1ebb03..b992bda2524 100644 --- a/java/jdbc/pom.xml +++ b/java/jdbc/pom.xml @@ -5,7 +5,7 @@ io.vitess vitess-parent - 10.0.2 + 10.0.3-SNAPSHOT vitess-jdbc diff --git a/java/pom.xml b/java/pom.xml index 19009d74e50..72334115c4d 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ io.vitess vitess-parent - 10.0.2 + 10.0.3-SNAPSHOT pom Vitess Java Client libraries [Parent] From 3ec64ef80ae673f84be6a6be38d39ebb5722a4c8 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 27 May 2021 14:21:23 +0530 Subject: [PATCH 183/310] increase timeout Signed-off-by: Harshit Gangal --- go/test/endtoend/topotest/consul/main_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/endtoend/topotest/consul/main_test.go b/go/test/endtoend/topotest/consul/main_test.go index a0de8f56c49..563f646f55e 100644 --- a/go/test/endtoend/topotest/consul/main_test.go +++ b/go/test/endtoend/topotest/consul/main_test.go @@ -126,7 +126,7 @@ func TestTopoRestart(t *testing.T) { ch <- 1 }() - timeOut := time.After(5 * time.Second) + timeOut := time.After(15 * time.Second) for { select { From 22bec26f6d899ecb902c6b16124bd12172871967 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 28 May 2021 20:10:18 -0400 Subject: [PATCH 184/310] Move duplicated vtctld cert/tls flags to a common package Signed-off-by: Andrew Mason --- go/vt/vtctl/grpcclientcommon/dial_option.go | 41 +++++++++++++++++++++ go/vt/vtctl/grpcvtctlclient/client.go | 11 +----- go/vt/vtctl/grpcvtctldclient/client.go | 21 +---------- 3 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 go/vt/vtctl/grpcclientcommon/dial_option.go diff --git a/go/vt/vtctl/grpcclientcommon/dial_option.go b/go/vt/vtctl/grpcclientcommon/dial_option.go new file mode 100644 index 00000000000..7a69bcf9638 --- /dev/null +++ b/go/vt/vtctl/grpcclientcommon/dial_option.go @@ -0,0 +1,41 @@ +/* +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 grpcclientcommon defines the flags shared by both grpcvtctlclient and +// grpcvtctldclient. +package grpcclientcommon + +import ( + "flag" + + "google.golang.org/grpc" + + "vitess.io/vitess/go/vt/grpcclient" +) + +var ( + cert = flag.String("vtctld_grpc_cert", "", "the cert to use to connect") + key = flag.String("vtctld_grpc_key", "", "the key to use to connect") + ca = flag.String("vtctld_grpc_ca", "", "the server ca to use to validate servers when connecting") + name = flag.String("vtctld_grpc_server_name", "", "the server name to use to validate server certificate") +) + +// SecureDialOption returns a grpc.DialOption configured to use TLS (or +// insecure if no flags were set) based on the vtctld_grpc_* flags declared by +// this package. +func SecureDialOption() (grpc.DialOption, error) { + return grpcclient.SecureDialOption(*cert, *key, *ca, *name) +} diff --git a/go/vt/vtctl/grpcvtctlclient/client.go b/go/vt/vtctl/grpcvtctlclient/client.go index 5a61d7dc793..f0fe94ca330 100644 --- a/go/vt/vtctl/grpcvtctlclient/client.go +++ b/go/vt/vtctl/grpcvtctlclient/client.go @@ -18,7 +18,6 @@ limitations under the License. package grpcvtctlclient import ( - "flag" "time" "context" @@ -27,6 +26,7 @@ import ( "vitess.io/vitess/go/vt/grpcclient" "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/vtctl/grpcclientcommon" "vitess.io/vitess/go/vt/vtctl/vtctlclient" logutilpb "vitess.io/vitess/go/vt/proto/logutil" @@ -34,20 +34,13 @@ import ( vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" ) -var ( - cert = flag.String("vtctld_grpc_cert", "", "the cert to use to connect") - key = flag.String("vtctld_grpc_key", "", "the key to use to connect") - ca = flag.String("vtctld_grpc_ca", "", "the server ca to use to validate servers when connecting") - name = flag.String("vtctld_grpc_server_name", "", "the server name to use to validate server certificate") -) - type gRPCVtctlClient struct { cc *grpc.ClientConn c vtctlservicepb.VtctlClient } func gRPCVtctlClientFactory(addr string) (vtctlclient.VtctlClient, error) { - opt, err := grpcclient.SecureDialOption(*cert, *key, *ca, *name) + opt, err := grpcclientcommon.SecureDialOption() if err != nil { return nil, err } diff --git a/go/vt/vtctl/grpcvtctldclient/client.go b/go/vt/vtctl/grpcvtctldclient/client.go index a0f5a14ef77..45e19ff88e8 100644 --- a/go/vt/vtctl/grpcvtctldclient/client.go +++ b/go/vt/vtctl/grpcvtctldclient/client.go @@ -19,11 +19,10 @@ limitations under the License. package grpcvtctldclient import ( - "flag" - "google.golang.org/grpc" "vitess.io/vitess/go/vt/grpcclient" + "vitess.io/vitess/go/vt/vtctl/grpcclientcommon" "vitess.io/vitess/go/vt/vtctl/vtctldclient" vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" @@ -31,22 +30,6 @@ import ( const connClosedMsg = "grpc: the client connection is closed" -// (TODO:@amason) - These flags match exactly the flags used in grpcvtctlclient. -// If a program attempts to import both of these packages, it will panic during -// startup due to the duplicate flags. -// -// For everything else I've been doing a sed s/vtctl/vtctld, but I cannot do -// that here, since these flags are already "vtctld_*". My other options are to -// name them "vtctld2_*" or to omit them completely. -// -// Not to pitch project ideas in comments, but a nice project to solve -var ( - cert = flag.String("vtctld_grpc_cert", "", "the cert to use to connect") - key = flag.String("vtctld_grpc_key", "", "the key to use to connect") - ca = flag.String("vtctld_grpc_ca", "", "the server ca to use to validate servers when connecting") - name = flag.String("vtctld_grpc_server_name", "", "the server name to use to validate server certificate") -) - type gRPCVtctldClient struct { cc *grpc.ClientConn c vtctlservicepb.VtctldClient @@ -56,7 +39,7 @@ type gRPCVtctldClient struct { //go:generate grpcvtctldclient -out client_gen.go func gRPCVtctldClientFactory(addr string) (vtctldclient.VtctldClient, error) { - opt, err := grpcclient.SecureDialOption(*cert, *key, *ca, *name) + opt, err := grpcclientcommon.SecureDialOption() if err != nil { return nil, err } From ea4926b2382e3df270bdba003295850f81362893 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 28 May 2021 20:47:41 -0400 Subject: [PATCH 185/310] Don't show `help requested` errors as errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This turns the output from: ``` ❯ vtctlclient -server "localhost:15999" ListAllTablets -h Usage: ListAllTablets , , ... Lists all tablets in an awk-friendly way. ListAllTablets Error: rpc error: code = Unknown desc = flag: help requested E0528 19:52:46.564223 77260 main.go:76] remote error: rpc error: code = Unknown desc = flag: help requested ❯ echo $? 1 ``` into: ``` ❯ vtctlclient -server "localhost:15999" ListAllTablets -h Usage: ListAllTablets , , ... Lists all tablets in an awk-friendly way. ❯ echo $? 0 ``` Signed-off-by: Andrew Mason --- go/cmd/vtctlclient/main.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/cmd/vtctlclient/main.go b/go/cmd/vtctlclient/main.go index e7311a5cffa..bd8871851f7 100644 --- a/go/cmd/vtctlclient/main.go +++ b/go/cmd/vtctlclient/main.go @@ -67,6 +67,10 @@ func main() { logutil.LogEvent(logger, e) }) if err != nil { + if strings.Contains(err.Error(), "flag: help requested") { + return + } + errStr := strings.Replace(err.Error(), "remote error: ", "", -1) fmt.Printf("%s Error: %s\n", flag.Arg(0), errStr) log.Error(err) From 1928fac2f79b7d6e115162dc2d480d0851b70b3f Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Fri, 28 May 2021 21:37:39 -0400 Subject: [PATCH 186/310] Add LegacyVtctlCommand shim to vtctldclient CLI This is admittedly pretty hacky, and I had to spend a lot of time messing around with cobra to make this behavior correctly. But, it works! Signed-off-by: Andrew Mason --- .../internal/command/legacy_shim.go | 101 ++++++++++++++++++ go/cmd/vtctldclient/internal/command/root.go | 16 ++- go/cmd/vtctldclient/plugin_grpcvtctlclient.go | 23 ++++ 3 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 go/cmd/vtctldclient/internal/command/legacy_shim.go create mode 100644 go/cmd/vtctldclient/plugin_grpcvtctlclient.go diff --git a/go/cmd/vtctldclient/internal/command/legacy_shim.go b/go/cmd/vtctldclient/internal/command/legacy_shim.go new file mode 100644 index 00000000000..0d6bd8494b6 --- /dev/null +++ b/go/cmd/vtctldclient/internal/command/legacy_shim.go @@ -0,0 +1,101 @@ +/* +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 command + +import ( + "context" + "flag" + "fmt" + "strings" + + "github.com/spf13/cobra" + "k8s.io/apimachinery/pkg/util/sets" + + "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/logutil" + "vitess.io/vitess/go/vt/vtctl/vtctlclient" + + logutilpb "vitess.io/vitess/go/vt/proto/logutil" +) + +var ( + // LegacyVtctlCommand provides a shim to make legacy ExecuteVtctlCommand + // RPCs. This allows users to use a single binary to make RPCs against both + // the new and old vtctld gRPC APIs. + LegacyVtctlCommand = &cobra.Command{ + Use: "LegacyVtctlCommand", + Short: "Invoke a legacy vtctlclient command. Flag parsing is best effort.", + Args: cobra.ArbitraryArgs, + RunE: func(cmd *cobra.Command, args []string) error { + cli.FinishedParsing(cmd) + return runLegacyCommand(args) + }, + } +) + +func runLegacyCommand(args []string) error { + // Duplicated (mostly) from go/cmd/vtctlclient/main.go. + logger := logutil.NewConsoleLogger() + + ctx, cancel := context.WithTimeout(context.Background(), actionTimeout) + defer cancel() + + err := vtctlclient.RunCommandAndWait(ctx, server, args, func(e *logutilpb.Event) { + logutil.LogEvent(logger, e) + }) + if err != nil { + if strings.Contains(err.Error(), "flag: help requested") { + // Help is caught by SetHelpFunc, so we don't want to indicate this as an error. + return nil + } + + errStr := strings.Replace(err.Error(), "remote error: ", "", -1) + fmt.Printf("%s Error: %s\n", flag.Arg(0), errStr) + log.Error(err) + } + + return err +} + +func init() { + LegacyVtctlCommand.SetHelpFunc(func(cmd *cobra.Command, args []string) { + // PreRun (and PersistentPreRun) do not run when a Help command is + // being executed, so we need to duplicate the `--server` flag check + // here before we attempt to invoke the legacy help command. + if err := ensureServerArg(); err != nil { + log.Error(err) + return + } + + realArgs := cmd.Flags().Args() + + if len(realArgs) == 0 { + realArgs = append(realArgs, "help") + } + + argSet := sets.NewString(realArgs...) + if !argSet.HasAny("help", "-h", "--help") { + // Cobra tends to swallow the help flag, so we need to put it back + // into the arg slice that we pass to runLegacyCommand. + realArgs = append(realArgs, "-h") + } + + _ = runLegacyCommand(realArgs) + }) + Root.AddCommand(LegacyVtctlCommand) +} diff --git a/go/cmd/vtctldclient/internal/command/root.go b/go/cmd/vtctldclient/internal/command/root.go index 7243c8836e5..8335710f449 100644 --- a/go/cmd/vtctldclient/internal/command/root.go +++ b/go/cmd/vtctldclient/internal/command/root.go @@ -25,7 +25,6 @@ import ( "github.com/spf13/cobra" "vitess.io/vitess/go/trace" - "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/vtctl/vtctldclient" ) @@ -44,9 +43,7 @@ var ( // command context for every command. PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { traceCloser = trace.StartTracing("vtctldclient") - if server == "" { - err = errors.New("please specify -server to specify the vtctld server to connect to") - log.Error(err) + if err := ensureServerArg(); err != nil { return err } @@ -75,6 +72,17 @@ var ( } ) +var errNoServer = errors.New("please specify -server to specify the vtctld server to connect to") + +// ensureServerArg validates that --server was passed to the CLI. +func ensureServerArg() error { + if server == "" { + return errNoServer + } + + return nil +} + func init() { Root.PersistentFlags().StringVar(&server, "server", "", "server to use for connection") Root.PersistentFlags().DurationVar(&actionTimeout, "action_timeout", time.Hour, "timeout for the total command") diff --git a/go/cmd/vtctldclient/plugin_grpcvtctlclient.go b/go/cmd/vtctldclient/plugin_grpcvtctlclient.go new file mode 100644 index 00000000000..e08d657f428 --- /dev/null +++ b/go/cmd/vtctldclient/plugin_grpcvtctlclient.go @@ -0,0 +1,23 @@ +/* +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 main + +// Imports and register the gRPC vtctl client. + +import ( + _ "vitess.io/vitess/go/vt/vtctl/grpcvtctlclient" +) From 12a456e8444e608129a679cd61985c02cf67c33c Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Mon, 31 May 2021 13:38:12 +0530 Subject: [PATCH 187/310] added function to create vttestserver docker images Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver_test.go | 75 ++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 go/test/endtoend/docker/vttestserver_test.go diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go new file mode 100644 index 00000000000..5e74a998e4e --- /dev/null +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -0,0 +1,75 @@ +/* +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 docker + +import ( + "os" + "os/exec" + "path" + "testing" + + "github.com/golang/glog" +) + +const ( + vttestserverMysql57image = "vttestserver-e2etest/mysql57" + vttestserverMysql80image = "vttestserver-e2etest/mysql80" +) + +func TestMain(m *testing.M) { + exitCode := func() int { + err := makeVttestserverDockerImages() + if err != nil { + glog.Error(err.Error()) + return 1 + } + return m.Run() + }() + os.Exit(exitCode) +} + +//makeVttestserverDockerImages creates the vttestserver docker images for both MySQL57 and MySQL80 +func makeVttestserverDockerImages() error { + mainVitessPath := path.Join(os.Getenv("PWD"), "../../../..") + dockerFilePath := path.Join(mainVitessPath, "docker/vttestserver/Dockerfile.mysql57") + cmd57 := exec.Command("docker", "build", "-f", dockerFilePath, "-t", vttestserverMysql57image, ".") + cmd57.Dir = mainVitessPath + err := cmd57.Start() + if err != nil { + return err + } + + dockerFilePath = path.Join(mainVitessPath, "docker/vttestserver/Dockerfile.mysql80") + cmd80 := exec.Command("docker", "build", "-f", dockerFilePath, "-t", vttestserverMysql80image, ".") + cmd80.Dir = mainVitessPath + err = cmd80.Start() + if err != nil { + return err + } + + err = cmd57.Wait() + if err != nil { + return err + } + + err = cmd80.Wait() + if err != nil { + return err + } + + return nil +} From c425e9a6eb94f25b645078de545170ef8cc90ca5 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Mon, 31 May 2021 16:35:55 +0530 Subject: [PATCH 188/310] added test for unsharded keyspace in vttestserver image Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver.go | 119 +++++++++++++++++++ go/test/endtoend/docker/vttestserver_test.go | 87 +++++++++----- 2 files changed, 173 insertions(+), 33 deletions(-) create mode 100644 go/test/endtoend/docker/vttestserver.go diff --git a/go/test/endtoend/docker/vttestserver.go b/go/test/endtoend/docker/vttestserver.go new file mode 100644 index 00000000000..81f92661489 --- /dev/null +++ b/go/test/endtoend/docker/vttestserver.go @@ -0,0 +1,119 @@ +/* +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 docker + +import ( + "fmt" + "os" + "os/exec" + "path" + "strconv" + "strings" +) + +const ( + vttestserverMysql57image = "vttestserver-e2etest/mysql57" + vttestserverMysql80image = "vttestserver-e2etest/mysql80" +) + +type vttestserver struct { + dockerImage string + keyspaces []string + numShards []int + mysqlMaxConnecetions int + port int +} + +func newVttestserver(dockerImage string, keyspaces []string, numShards []int, mysqlMaxConnections, port int) *vttestserver { + return &vttestserver{ + dockerImage: dockerImage, + keyspaces: keyspaces, + numShards: numShards, + mysqlMaxConnecetions: mysqlMaxConnections, + port: port, + } +} + +func (v *vttestserver) teardown() { + cmd := exec.Command("docker", "rm", "--force", "vttestserver-end2end-test") + _ = cmd.Run() +} + +// startDockerImage starts the docker image for the vttestserver +func (v *vttestserver) startDockerImage() error { + cmd := exec.Command("docker", "run") + cmd.Args = append(cmd.Args, "--name=vttestserver-end2end-test") + cmd.Args = append(cmd.Args, "-p", fmt.Sprintf("%d:33577", v.port)) + cmd.Args = append(cmd.Args, "-e", "PORT=33574") + cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("KEYSPACES=%s", strings.Join(v.keyspaces, ","))) + cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("NUM_SHARDS=%s", strings.Join(convertToStringSlice(v.numShards), ","))) + cmd.Args = append(cmd.Args, "-e", "MYSQL_BIND_HOST=0.0.0.0") + cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("MYSQL_MAX_CONNECTIONS=%d", v.mysqlMaxConnecetions)) + cmd.Args = append(cmd.Args, `--health-cmd="mysqladmin ping -h127.0.0.1 -P33577"`) + cmd.Args = append(cmd.Args, "--health-interval=5s") + cmd.Args = append(cmd.Args, "--health-timeout=2s") + cmd.Args = append(cmd.Args, "--health-retries=5") + cmd.Args = append(cmd.Args, v.dockerImage) + + err := cmd.Start() + if err != nil { + return err + } + return nil +} + +// convertToStringSlice converts an integer slice to string slice +func convertToStringSlice(intSlice []int) []string { + var stringSlice []string + for _, val := range intSlice { + str := strconv.Itoa(val) + stringSlice = append(stringSlice, str) + } + return stringSlice +} + +//makeVttestserverDockerImages creates the vttestserver docker images for both MySQL57 and MySQL80 +func makeVttestserverDockerImages() error { + mainVitessPath := path.Join(os.Getenv("PWD"), "../../../..") + dockerFilePath := path.Join(mainVitessPath, "docker/vttestserver/Dockerfile.mysql57") + cmd57 := exec.Command("docker", "build", "-f", dockerFilePath, "-t", vttestserverMysql57image, ".") + cmd57.Dir = mainVitessPath + err := cmd57.Start() + if err != nil { + return err + } + + dockerFilePath = path.Join(mainVitessPath, "docker/vttestserver/Dockerfile.mysql80") + cmd80 := exec.Command("docker", "build", "-f", dockerFilePath, "-t", vttestserverMysql80image, ".") + cmd80.Dir = mainVitessPath + err = cmd80.Start() + if err != nil { + return err + } + + err = cmd57.Wait() + if err != nil { + return err + } + + err = cmd80.Wait() + if err != nil { + return err + } + + return nil +} diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index 5e74a998e4e..ad3a85d90c4 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -17,24 +17,25 @@ limitations under the License. package docker import ( + "context" + "fmt" "os" - "os/exec" - "path" "testing" + "time" - "github.com/golang/glog" -) + "github.com/google/go-cmp/cmp" + + "vitess.io/vitess/go/sqltypes" + + "vitess.io/vitess/go/mysql" -const ( - vttestserverMysql57image = "vttestserver-e2etest/mysql57" - vttestserverMysql80image = "vttestserver-e2etest/mysql80" + "github.com/stretchr/testify/require" ) func TestMain(m *testing.M) { exitCode := func() int { err := makeVttestserverDockerImages() if err != nil { - glog.Error(err.Error()) return 1 } return m.Run() @@ -42,34 +43,54 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -//makeVttestserverDockerImages creates the vttestserver docker images for both MySQL57 and MySQL80 -func makeVttestserverDockerImages() error { - mainVitessPath := path.Join(os.Getenv("PWD"), "../../../..") - dockerFilePath := path.Join(mainVitessPath, "docker/vttestserver/Dockerfile.mysql57") - cmd57 := exec.Command("docker", "build", "-f", dockerFilePath, "-t", vttestserverMysql57image, ".") - cmd57.Dir = mainVitessPath - err := cmd57.Start() - if err != nil { - return err - } +func TestUnsharded(t *testing.T) { + dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} + for _, image := range dockerImages { + t.Run(image, func(t *testing.T) { + vtest := newVttestserver(image, []string{"unsharded_ks"}, []int{1}, 1000, 33577) + err := vtest.startDockerImage() + require.NoError(t, err) + defer vtest.teardown() - dockerFilePath = path.Join(mainVitessPath, "docker/vttestserver/Dockerfile.mysql80") - cmd80 := exec.Command("docker", "build", "-f", dockerFilePath, "-t", vttestserverMysql80image, ".") - cmd80.Dir = mainVitessPath - err = cmd80.Start() - if err != nil { - return err - } + // wait for the docker to be setup + time.Sleep(10 * time.Second) - err = cmd57.Wait() - if err != nil { - return err + ctx := context.Background() + vttestParams := mysql.ConnParams{ + Host: "localhost", + Port: vtest.port, + } + conn, err := mysql.Connect(ctx, &vttestParams) + require.NoError(t, err) + defer conn.Close() + assertMatches(t, conn, "show databases", `[[VARCHAR("unsharded_ks")] [VARCHAR("information_schema")] [VARCHAR("mysql")] [VARCHAR("sys")] [VARCHAR("performance_schema")]]`) + _, err = execute(t, conn, "create table unsharded_ks.t1(id int)") + require.NoError(t, err) + _, err = execute(t, conn, "insert into unsharded_ks.t1(id) values (10),(20),(30)") + require.NoError(t, err) + assertMatches(t, conn, "select * from unsharded_ks.t1", `[[INT32(10)] [INT32(20)] [INT32(30)]]`) + }) } +} - err = cmd80.Wait() - if err != nil { - return err - } +func execute(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { + t.Helper() + return conn.ExecuteFetch(query, 1000, true) +} - return nil +func checkedExec(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 assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { + t.Helper() + qr := checkedExec(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) + } } From 0a3baf882341dde3dc531573bac3faabe2db1d3e Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Mon, 31 May 2021 16:45:05 +0530 Subject: [PATCH 189/310] added test for sharded keyspace for vttestserver image Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver_test.go | 32 ++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index ad3a85d90c4..12a3f00329f 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -73,6 +73,38 @@ func TestUnsharded(t *testing.T) { } } +func TestSharded(t *testing.T) { + dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} + for _, image := range dockerImages { + t.Run(image, func(t *testing.T) { + vtest := newVttestserver(image, []string{"ks"}, []int{2}, 1000, 33577) + err := vtest.startDockerImage() + require.NoError(t, err) + defer vtest.teardown() + + // wait for the docker to be setup + time.Sleep(10 * time.Second) + + ctx := context.Background() + vttestParams := mysql.ConnParams{ + Host: "localhost", + Port: vtest.port, + } + conn, err := mysql.Connect(ctx, &vttestParams) + require.NoError(t, err) + defer conn.Close() + assertMatches(t, conn, "show databases", `[[VARCHAR("ks")] [VARCHAR("information_schema")] [VARCHAR("mysql")] [VARCHAR("sys")] [VARCHAR("performance_schema")]]`) + _, err = execute(t, conn, "create table ks.t1(id int)") + require.NoError(t, err) + _, err = execute(t, conn, "alter vschema on ks.t1 add vindex `binary_md5`(id) using `binary_md5`") + require.NoError(t, err) + _, err = execute(t, conn, "insert into ks.t1(id) values (10),(20),(30)") + require.NoError(t, err) + assertMatches(t, conn, "select id from ks.t1 order by id", `[[INT32(10)] [INT32(20)] [INT32(30)]]`) + }) + } +} + func execute(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { t.Helper() return conn.ExecuteFetch(query, 1000, true) From f01e28939e2eaffe8c07146c90ebe115244b9940 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Mon, 31 May 2021 16:48:11 +0530 Subject: [PATCH 190/310] added test for mysql max connections for vttestserver image Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver_test.go | 25 ++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index 12a3f00329f..504cdee144d 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -105,6 +105,31 @@ func TestSharded(t *testing.T) { } } +func TestMysqlMaxCons(t *testing.T) { + dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} + for _, image := range dockerImages { + t.Run(image, func(t *testing.T) { + vtest := newVttestserver(image, []string{"ks"}, []int{2}, 100000, 33577) + err := vtest.startDockerImage() + require.NoError(t, err) + defer vtest.teardown() + + // wait for the docker to be setup + time.Sleep(10 * time.Second) + + ctx := context.Background() + vttestParams := mysql.ConnParams{ + Host: "localhost", + Port: vtest.port, + } + conn, err := mysql.Connect(ctx, &vttestParams) + require.NoError(t, err) + defer conn.Close() + assertMatches(t, conn, "select @@max_connections", `[[UINT64(100000)]]`) + }) + } +} + func execute(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { t.Helper() return conn.ExecuteFetch(query, 1000, true) From d2e8b5ab81a635e2686eef0edbfa19d09c35ed92 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Mon, 31 May 2021 17:00:52 +0530 Subject: [PATCH 191/310] added test for lots of keyspaces for vttestserver image Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver_test.go | 40 ++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index 504cdee144d..4226f0c0c0a 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -130,6 +130,46 @@ func TestMysqlMaxCons(t *testing.T) { } } +func TestLargeNumberOfKeyspaces(t *testing.T) { + dockerImages := []string{vttestserverMysql57image, vttestserverMysql80image} + for _, image := range dockerImages { + t.Run(image, func(t *testing.T) { + var keyspaces []string + var numShards []int + for i := 0; i < 100; i++ { + keyspaces = append(keyspaces, fmt.Sprintf("unsharded_ks%d", i)) + numShards = append(numShards, 1) + } + + vtest := newVttestserver(image, keyspaces, numShards, 100000, 33577) + err := vtest.startDockerImage() + require.NoError(t, err) + defer vtest.teardown() + + // wait for the docker to be setup + time.Sleep(15 * time.Second) + + ctx := context.Background() + vttestParams := mysql.ConnParams{ + Host: "localhost", + Port: vtest.port, + } + conn, err := mysql.Connect(ctx, &vttestParams) + require.NoError(t, err) + defer conn.Close() + + // assert that all the keyspaces are correctly setup + for _, keyspace := range keyspaces { + _, err = execute(t, conn, "create table "+keyspace+".t1(id int)") + require.NoError(t, err) + _, err = execute(t, conn, "insert into "+keyspace+".t1(id) values (10),(20),(30)") + require.NoError(t, err) + assertMatches(t, conn, "select * from "+keyspace+".t1", `[[INT32(10)] [INT32(20)] [INT32(30)]]`) + } + }) + } +} + func execute(t *testing.T, conn *mysql.Conn, query string) (*sqltypes.Result, error) { t.Helper() return conn.ExecuteFetch(query, 1000, true) From 0b76c1d794eaf06c8fd0b1c8843e130d8a637db0 Mon Sep 17 00:00:00 2001 From: Florent Poinsard Date: Thu, 3 Jun 2021 15:48:53 +0200 Subject: [PATCH 192/310] New E2E tests for new tables in unsharded/sharded keyspaces Signed-off-by: Florent Poinsard --- go/test/endtoend/vtgate/main_test.go | 2 +- go/test/endtoend/vtgate/misc_test.go | 20 ++++ .../schematracker/schematracker_test.go | 107 ++++++++++++++++++ test/config.json | 9 ++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 go/test/endtoend/vtgate/schematracker/schematracker_test.go diff --git a/go/test/endtoend/vtgate/main_test.go b/go/test/endtoend/vtgate/main_test.go index 7fda9e8fbe5..ecce216b54f 100644 --- a/go/test/endtoend/vtgate/main_test.go +++ b/go/test/endtoend/vtgate/main_test.go @@ -418,7 +418,7 @@ func TestMain(m *testing.M) { VSchema: VSchema, } clusterInstance.VtGateExtraArgs = []string{"-schema_change_signal"} - clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal"} + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "1"} err = clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, true) if err != nil { return 1 diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 77de7f40766..888bf7346f8 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" @@ -674,6 +675,25 @@ func TestVSchemaTrackerInit(t *testing.T) { assert.Equal(t, want, got) } +func TestVSchemaTrackedForNewTables(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + // create a new table which is not part of the VSchema + exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) + + // wait for vttablet's schema reload interval to pass + time.Sleep(2 * time.Second) + + // check if the new table is part of the schema + qr := exec(t, conn, "SHOW VSCHEMA TABLES") + got := fmt.Sprintf("%v", qr.Rows) + want := `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("new_table_tracked")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("vstream_test")]]` + assert.Equal(t, want, got) +} + func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) diff --git a/go/test/endtoend/vtgate/schematracker/schematracker_test.go b/go/test/endtoend/vtgate/schematracker/schematracker_test.go new file mode 100644 index 00000000000..f114c76b8c4 --- /dev/null +++ b/go/test/endtoend/vtgate/schematracker/schematracker_test.go @@ -0,0 +1,107 @@ +/* +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 schematracker + +import ( + "context" + "fmt" + "testing" + "time" + + "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 ( + hostname = "localhost" + keyspaceName = "ks" + cell = "zone1" + sqlSchema = ` + create table main ( + id bigint, + val varchar(128), + primary key(id) + ) Engine=InnoDB; +` +) + +func TestNewUnshardedTable(t *testing.T) { + defer cluster.PanicHandler(t) + var err error + + // initialize our cluster + clusterInstance := cluster.NewCluster(cell, hostname) + defer clusterInstance.Teardown() + + // Start topo server + err = clusterInstance.StartTopo() + require.NoError(t, err) + + // create keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + SchemaSQL: sqlSchema, + } + + // enabling and setting the schema reload time to one second + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "1"} + err = clusterInstance.StartUnshardedKeyspace(*keyspace, 1, false) + require.NoError(t, err) + + // Start vtgate with the schema_change_signal flag + clusterInstance.VtGateExtraArgs = []string{"-schema_change_signal"} + err = clusterInstance.StartVtgate() + require.NoError(t, err) + + // create a sql connection + ctx := context.Background() + conn, err := mysql.Connect(ctx, &mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + }) + require.NoError(t, err) + defer conn.Close() + + // ensuring our initial table "main" is in the schema + qr := exec(t, conn, "SHOW VSCHEMA TABLES") + got := fmt.Sprintf("%v", qr.Rows) + want := `[[VARCHAR("dual")] [VARCHAR("main")]]` + require.Equal(t, want, got) + + // create a new table which is not part of the VSchema + exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) + + // waiting for the vttablet's schema_reload interval to kick in + time.Sleep(2 * time.Second) + + // ensuring our new table is in the schema + qr = exec(t, conn, "SHOW VSCHEMA TABLES") + got = fmt.Sprintf("%v", qr.Rows) + want = `[[VARCHAR("dual")] [VARCHAR("main")] [VARCHAR("new_table_tracked")]]` + assert.Equal(t, want, got) +} + +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, "for query: "+query) + return qr +} diff --git a/test/config.json b/test/config.json index 61fc1660675..088d815ea74 100644 --- a/test/config.json +++ b/test/config.json @@ -606,6 +606,15 @@ "RetryMax": 0, "Tags": [] }, + "vtgate_schematracker": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, "vtgate_sequence": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sequence"], From 97ce0972f1a8cd775e3462ae7a1ad894ecda0f86 Mon Sep 17 00:00:00 2001 From: Florent Poinsard Date: Thu, 3 Jun 2021 17:25:17 +0200 Subject: [PATCH 193/310] Improved vschema tracker misc end to end tests Signed-off-by: Florent Poinsard --- go/test/endtoend/vtgate/main_test.go | 14 ++++++++ go/test/endtoend/vtgate/misc_test.go | 33 +++++++++++++++---- .../schematracker/schematracker_test.go | 4 +-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/go/test/endtoend/vtgate/main_test.go b/go/test/endtoend/vtgate/main_test.go index ecce216b54f..6b2ff4b4a0f 100644 --- a/go/test/endtoend/vtgate/main_test.go +++ b/go/test/endtoend/vtgate/main_test.go @@ -142,6 +142,12 @@ create table t8( testId bigint, primary key(id8) ) Engine=InnoDB; + +create table t9( + id9 bigint, + testId bigint, + primary key(id9) +) Engine=InnoDB; ` VSchema = ` @@ -384,6 +390,14 @@ create table t8( "name": "hash" } ] + }, + "t9": { + "column_vindexes": [ + { + "column": "id9", + "name": "hash" + } + ] } } }` diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 888bf7346f8..32b4f3b7132 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -671,8 +671,21 @@ func TestVSchemaTrackerInit(t *testing.T) { qr := exec(t, conn, "SHOW VSCHEMA TABLES") got := fmt.Sprintf("%v", qr.Rows) - want := `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("vstream_test")]]` + want := `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("vstream_test")]]` assert.Equal(t, want, got) + + // DML on existing table + exec(t, conn, "insert into t9(id9, testId) values(0,0),(1,1)") // insert initial data + result := exec(t, conn, `select id9 from t9 limit 100`) // select + assert.Equal(t, 2, len(result.Rows)) + + exec(t, conn, "update t9 set testId = 42 where testId = 0") // update + assertMatches(t, conn, "select testId from t9", `[[INT64(42)] [INT64(1)]]`) + + exec(t, conn, "delete from t9 where testId = 42") // delete + assertMatches(t, conn, "select testId from t9", `[[INT64(1)]]`) + + assertMatches(t, conn, "select testId from t9 where testId = 1", `[[INT64(1)]]`) // select with WHERE clause } func TestVSchemaTrackedForNewTables(t *testing.T) { @@ -685,13 +698,21 @@ func TestVSchemaTrackedForNewTables(t *testing.T) { exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) // wait for vttablet's schema reload interval to pass - time.Sleep(2 * time.Second) + time.Sleep(5 * time.Second) // check if the new table is part of the schema - qr := exec(t, conn, "SHOW VSCHEMA TABLES") - got := fmt.Sprintf("%v", qr.Rows) - want := `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("new_table_tracked")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("vstream_test")]]` - assert.Equal(t, want, got) + assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("new_table_tracked")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("vstream_test")]]`) + + // DML on new table + exec(t, conn, `insert into new_table_tracked(id) values(0),(1)`) // insert initial data + assertMatches(t, conn, "select id from new_table_tracked", `[[INT64(0)] [INT64(1)]]`) // select + assertMatches(t, conn, "select id from new_table_tracked where id = 1 ", `[[INT64(1)]]`) // select with WHERE clause + + exec(t, conn, `update new_table_tracked set name = "newName1" where id = 1`) // update + assertMatches(t, conn, "select name from new_table_tracked where id = 1 ", `[[VARCHAR("newName1")]]`) + + exec(t, conn, "delete from new_table_tracked where id = 0") // delete + assertMatches(t, conn, "select id from new_table_tracked", `[[INT64(1)]]`) } func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { diff --git a/go/test/endtoend/vtgate/schematracker/schematracker_test.go b/go/test/endtoend/vtgate/schematracker/schematracker_test.go index f114c76b8c4..dbc9dab3dee 100644 --- a/go/test/endtoend/vtgate/schematracker/schematracker_test.go +++ b/go/test/endtoend/vtgate/schematracker/schematracker_test.go @@ -62,7 +62,7 @@ func TestNewUnshardedTable(t *testing.T) { } // enabling and setting the schema reload time to one second - clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "1"} + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "0.1"} err = clusterInstance.StartUnshardedKeyspace(*keyspace, 1, false) require.NoError(t, err) @@ -90,7 +90,7 @@ func TestNewUnshardedTable(t *testing.T) { exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) // waiting for the vttablet's schema_reload interval to kick in - time.Sleep(2 * time.Second) + time.Sleep(5 * time.Second) // ensuring our new table is in the schema qr = exec(t, conn, "SHOW VSCHEMA TABLES") From 3f6b7a61fead5123827303b827c9c9b7f4b1f2d7 Mon Sep 17 00:00:00 2001 From: Florent Poinsard Date: Thu, 3 Jun 2021 19:51:40 +0200 Subject: [PATCH 194/310] attempt to fix panic on DML against sharded keyspace Signed-off-by: Florent Poinsard --- go/test/endtoend/vtgate/misc_test.go | 1 + go/vt/vtgate/engine/insert.go | 3 +++ 2 files changed, 4 insertions(+) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index 32b4f3b7132..2838aecd257 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -704,6 +704,7 @@ func TestVSchemaTrackedForNewTables(t *testing.T) { assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("new_table_tracked")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("vstream_test")]]`) // DML on new table + assertMatches(t, conn, "select id from new_table_tracked", `[]`) // select exec(t, conn, `insert into new_table_tracked(id) values(0),(1)`) // insert initial data assertMatches(t, conn, "select id from new_table_tracked", `[[INT64(0)] [INT64(1)]]`) // select assertMatches(t, conn, "select id from new_table_tracked where id = 1 ", `[[INT64(1)]]`) // select with WHERE clause diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index d09be708467..4774cad2a64 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -394,6 +394,9 @@ func (ins *Insert) getInsertShardedRoute(vcursor VCursor, bindVars map[string]*q // keyspace ids. For regular inserts, a failure to find a route // results in an error. For 'ignore' type inserts, the keyspace // id is returned as nil, which is used later to drop the corresponding rows. + if len(vindexRowsValues) == 0 || len(ins.Table.ColumnVindexes) == 0 { + return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] table without a primary vindex is not expectedd") + } keyspaceIDs, err := ins.processPrimary(vcursor, vindexRowsValues[0], ins.Table.ColumnVindexes[0]) if err != nil { return nil, nil, err From 37ef64f8d2269985aca6cd6fbe6b80e8e61f6429 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 7 Jun 2021 13:06:21 +0300 Subject: [PATCH 195/310] report rows_copied during and at the end of vreplication migration Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../onlineddl/vrepl/onlineddl_vrepl_test.go | 17 +++++++++++++++++ go/vt/vttablet/onlineddl/executor.go | 4 +++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go b/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go index 9e014079cc9..f0b7f0c1979 100644 --- a/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go +++ b/go/test/endtoend/onlineddl/vrepl/onlineddl_vrepl_test.go @@ -250,6 +250,7 @@ func TestSchemaChange(t *testing.T) { uuid := testOnlineDDLStatement(t, alterTableSuccessfulStatement, "online", "vtgate", "vrepl_col") onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) testRows(t) + testMigrationRowCount(t, uuid) onlineddl.CheckCancelMigration(t, &vtParams, shards, uuid, false) onlineddl.CheckRetryMigration(t, &vtParams, shards, uuid, false) }) @@ -258,6 +259,7 @@ func TestSchemaChange(t *testing.T) { uuid := testOnlineDDLStatement(t, alterTableTrivialStatement, "online", "vtctl", "vrepl_col") onlineddl.CheckMigrationStatus(t, &vtParams, shards, uuid, schema.OnlineDDLStatusComplete) testRows(t) + testMigrationRowCount(t, uuid) onlineddl.CheckCancelMigration(t, &vtParams, shards, uuid, false) onlineddl.CheckRetryMigration(t, &vtParams, shards, uuid, false) }) @@ -372,6 +374,21 @@ func testRows(t *testing.T) { require.Equal(t, countInserts, row.AsInt64("c", 0)) } +func testMigrationRowCount(t *testing.T, uuid string) { + insertMutex.Lock() + defer insertMutex.Unlock() + + var totalRowsCopied uint64 + // count sum of rows copied in all shards, that should be the total number of rows inserted to the table + rs := onlineddl.ReadMigrations(t, &vtParams, uuid) + require.NotNil(t, rs) + for _, row := range rs.Named().Rows { + rowsCopied := row.AsUint64("rows_copied", 0) + totalRowsCopied += rowsCopied + } + require.Equal(t, uint64(countInserts), totalRowsCopied) +} + func testWithInitialSchema(t *testing.T) { // Create 4 tables var sqlQuery = "" //nolint diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index 0e03f1977a6..ca9b277b03c 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -676,7 +676,7 @@ func (e *Executor) cutOverVReplMigration(ctx context.Context, s *VReplStream) er }() // Tables are now swapped! Migration is successful - _ = e.onSchemaMigrationStatus(ctx, onlineDDL.UUID, schema.OnlineDDLStatusComplete, false, progressPctFull, etaSecondsNow, rowsCopiedUnknown) + _ = e.onSchemaMigrationStatus(ctx, onlineDDL.UUID, schema.OnlineDDLStatusComplete, false, progressPctFull, etaSecondsNow, s.rowsCopied) return nil // deferred function will re-enable writes now @@ -2177,6 +2177,7 @@ func (e *Executor) isVReplMigrationReadyToCutOver(ctx context.Context, s *VReplS return false, nil } } + return true, nil } @@ -2236,6 +2237,7 @@ func (e *Executor) reviewRunningMigrations(ctx context.Context) (countRunnning i atomic.StoreInt64(&e.vreplMigrationRunning, 1) _ = e.updateMigrationTimestamp(ctx, "liveness_timestamp", uuid) + _ = e.updateRowsCopied(ctx, uuid, s.rowsCopied) _ = e.updateMigrationProgressByRowsCopied(ctx, uuid, s.rowsCopied) _ = e.updateMigrationETASecondsByProgress(ctx, uuid) From 2b18e8da7f7f36af544f0c241c39ce43d90e0036 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 7 Jun 2021 13:41:43 +0300 Subject: [PATCH 196/310] towards supporting enum=>text conversion Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 19 ++++++++++++++----- go/vt/vttablet/onlineddl/vrepl/types.go | 12 ++++++++++++ .../vreplication/table_plan_builder.go | 6 ++++++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index e60130c89ab..561211d12b5 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -358,6 +358,15 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection return err } + for i := range v.sourceSharedColumns.Columns() { + column := v.sourceSharedColumns.Columns()[i] + mappedColumn := v.targetSharedColumns.Columns()[i] + if column.Name == mappedColumn.Name && column.Type == vrepl.EnumColumnType && mappedColumn.Charset != "" { + v.targetSharedColumns.SetEnumToTextConversion(column.Name) + v.targetSharedColumns.SetEnumValues(column.Name, column.EnumValues) + } + } + v.sourceAutoIncrement, err = v.readAutoIncrement(ctx, conn, v.sourceTable) if err != nil { return err @@ -381,11 +390,11 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { if i > 0 { sb.WriteString(", ") } - switch col.Type { - case vrepl.JSONColumnType: - sb.WriteString("convert(") - sb.WriteString(escapeName(name)) - sb.WriteString(" using utf8mb4)") + switch { + case col.Type == vrepl.JSONColumnType: + sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) + case col.EnumToTextConversion: + sb.WriteString(fmt.Sprintf("ELT(%s, %s)", escapeName(name), col.EnumValues)) default: sb.WriteString(escapeName(name)) } diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index f4ff965a381..9f3aa83b3d8 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -170,6 +170,18 @@ func (l *ColumnList) Len() int { return len(l.columns) } +func (this *ColumnList) SetEnumToTextConversion(columnName string) { + this.GetColumn(columnName).EnumToTextConversion = true +} + +func (this *ColumnList) IsEnumToTextConversion(columnName string) bool { + return this.GetColumn(columnName).EnumToTextConversion +} + +func (this *ColumnList) SetEnumValues(columnName string, enumValues string) { + this.GetColumn(columnName).EnumValues = enumValues +} + // UniqueKey is the combination of a key's name and columns type UniqueKey struct { Name string diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 66c57ca09d0..87836b8dcf3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -547,6 +547,9 @@ func (tpb *tablePlanBuilder) generateValuesPart(buf *sqlparser.TrackedBuffer, bv separator = "," switch cexpr.operation { case opExpr: + // if cexpr.colType == querypb.Type_ENUM { + // fmt.Printf("========= found ENUM type for %v\n", cexpr.expr) + // } if cexpr.colType == querypb.Type_JSON { buf.Myprintf("convert(%v using utf8mb4)", cexpr.expr) } else { @@ -632,6 +635,9 @@ func (tpb *tablePlanBuilder) generateUpdateStatement() *sqlparser.ParsedQuery { separator = ", " switch cexpr.operation { case opExpr: + // if cexpr.colType == querypb.Type_ENUM { + // fmt.Printf("========= found ENUM type for %v\n", cexpr.expr) + // } bvf.mode = bvAfter if cexpr.colType == querypb.Type_JSON { buf.Myprintf("convert(%v using utf8mb4)", cexpr.expr) From 3fbc6bb0b49fd70c91cc440765ab4f231859559b Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 7 Jun 2021 15:11:28 +0300 Subject: [PATCH 197/310] Online DDL/VReplication suite: reject non utf8* charsets Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../fail-alter-charset-non-utf8}/alter | 0 .../fail-alter-charset-non-utf8}/create.sql | 0 .../expect_failure | 1 + .../fail-alter-charset-non-utf8/alter | 1 + .../fail-alter-charset-non-utf8/create.sql | 24 +++++++++++++++++++ .../expect_failure | 1 + go/vt/vttablet/onlineddl/vrepl.go | 3 +++ 7 files changed, 30 insertions(+) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset => testdata/fail-alter-charset-non-utf8}/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset => testdata/fail-alter-charset-non-utf8}/create.sql (100%) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure new file mode 100644 index 00000000000..925d0d81ded --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure @@ -0,0 +1 @@ +Vitess does not support charset diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter new file mode 100644 index 00000000000..b5ec82b1a8b --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter @@ -0,0 +1 @@ +MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql new file mode 100644 index 00000000000..9db84563248 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql @@ -0,0 +1,24 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + t1 varchar(128) charset latin1 collate latin1_swedish_ci, + t2 varchar(128) charset latin1 collate latin1_swedish_ci, + tutf8 varchar(128) charset utf8, + tutf8mb4 varchar(128) charset utf8mb4, + primary key(id) +) auto_increment=1; + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); + insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); + insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); +end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure new file mode 100644 index 00000000000..925d0d81ded --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure @@ -0,0 +1 @@ +Vitess does not support charset diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index e60130c89ab..bd4b976abcb 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -224,6 +224,9 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { + if !strings.HasPrefix(charset, "utf8") { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) + } column.Charset = charset } } From 2399ee19c69490dd0dd6b8830f4e0712e378e981 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 13 May 2021 15:11:40 +0200 Subject: [PATCH 198/310] Refactor PKInfoMap to get info for all columns in the table as ColInfoMap as a precursor to adding Extra info for detecting generated columns Signed-off-by: Rohit Nayak --- .../vreplication/replicator_plan.go | 12 ++-- .../vreplication/replicator_plan_test.go | 16 ++--- .../vreplication/table_plan_builder.go | 67 ++++++++--------- .../tabletmanager/vreplication/vcopier.go | 4 +- .../tabletmanager/vreplication/vplayer.go | 2 +- .../tabletmanager/vreplication/vreplicator.go | 72 ++++++++++--------- 6 files changed, 90 insertions(+), 83 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 672c40c56bc..385e90c0f23 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -53,7 +53,7 @@ type ReplicatorPlan struct { VStreamFilter *binlogdatapb.Filter TargetTables map[string]*TablePlan TablePlans map[string]*TablePlan - PKInfoMap map[string][]*PrimaryKeyInfo + ColInfoMap map[string][]*ColumnInfo stats *binlogplayer.Stats } @@ -94,10 +94,10 @@ func (rp *ReplicatorPlan) buildExecutionPlan(fieldEvent *binlogdatapb.FieldEvent // requires us to wait for the field info sent by the source. func (rp *ReplicatorPlan) buildFromFields(tableName string, lastpk *sqltypes.Result, fields []*querypb.Field) (*TablePlan, error) { tpb := &tablePlanBuilder{ - name: sqlparser.NewTableIdent(tableName), - lastpk: lastpk, - pkInfos: rp.PKInfoMap[tableName], - stats: rp.stats, + name: sqlparser.NewTableIdent(tableName), + lastpk: lastpk, + columnInfos: rp.ColInfoMap[tableName], + stats: rp.stats, } for _, field := range fields { colName := sqlparser.NewColIdent(field.Name) @@ -114,7 +114,7 @@ func (rp *ReplicatorPlan) buildFromFields(tableName string, lastpk *sqltypes.Res tpb.colExprs = append(tpb.colExprs, cexpr) } // The following actions are a subset of buildTablePlan. - if err := tpb.analyzePK(rp.PKInfoMap); err != nil { + if err := tpb.analyzePK(rp.ColInfoMap); err != nil { return nil, err } return tpb.generate(), nil diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go index 6297ac0652b..fc1736dc5bc 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan_test.go @@ -669,8 +669,8 @@ func TestBuildPlayerPlan(t *testing.T) { err: "group by expression is not allowed to reference an aggregate expression: a", }} - PrimaryKeyInfos := map[string][]*PrimaryKeyInfo{ - "t1": {&PrimaryKeyInfo{Name: "c1"}}, + PrimaryKeyInfos := map[string][]*ColumnInfo{ + "t1": {&ColumnInfo{Name: "c1", IsPK: true}}, } copyState := map[string]*sqltypes.Result{ @@ -711,9 +711,9 @@ func TestBuildPlayerPlan(t *testing.T) { } func TestBuildPlayerPlanNoDup(t *testing.T) { - PrimaryKeyInfos := map[string][]*PrimaryKeyInfo{ - "t1": {&PrimaryKeyInfo{Name: "c1"}}, - "t2": {&PrimaryKeyInfo{Name: "c2"}}, + PrimaryKeyInfos := map[string][]*ColumnInfo{ + "t1": {&ColumnInfo{Name: "c1"}}, + "t2": {&ColumnInfo{Name: "c2"}}, } input := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ @@ -732,9 +732,9 @@ func TestBuildPlayerPlanNoDup(t *testing.T) { } func TestBuildPlayerPlanExclude(t *testing.T) { - PrimaryKeyInfos := map[string][]*PrimaryKeyInfo{ - "t1": {&PrimaryKeyInfo{Name: "c1"}}, - "t2": {&PrimaryKeyInfo{Name: "c2"}}, + PrimaryKeyInfos := map[string][]*ColumnInfo{ + "t1": {&ColumnInfo{Name: "c1"}}, + "t2": {&ColumnInfo{Name: "c2"}}, } input := &binlogdatapb.Filter{ Rules: []*binlogdatapb.Rule{{ diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 66c57ca09d0..8ec80bc7a25 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -47,13 +47,13 @@ type tablePlanBuilder struct { // selColumns keeps track of the columns we want to pull from source. // If Lastpk is set, we compare this list against the table's pk and // add missing references. - selColumns map[string]bool - colExprs []*colExpr - onInsert insertType - pkCols []*colExpr - lastpk *sqltypes.Result - pkInfos []*PrimaryKeyInfo - stats *binlogplayer.Stats + selColumns map[string]bool + colExprs []*colExpr + onInsert insertType + pkCols []*colExpr + lastpk *sqltypes.Result + columnInfos []*ColumnInfo + stats *binlogplayer.Stats } // colExpr describes the processing to be performed to @@ -112,7 +112,7 @@ const ( // a table-specific rule is built to be sent to the source. We don't send the // original rule to the source because it may not match the same tables as the // target. -// pkInfoMap specifies the list of primary key columns for each table. +// colInfoMap specifies the list of primary key columns for each table. // copyState is a map of tables that have not been fully copied yet. // If a table is not present in copyState, then it has been fully copied. If so, // all replication events are applied. The table still has to match a Filter.Rule. @@ -123,15 +123,15 @@ const ( // The TablePlan built is a partial plan. The full plan for a table is built // when we receive field information from events or rows sent by the source. // buildExecutionPlan is the function that builds the full plan. -func buildReplicatorPlan(filter *binlogdatapb.Filter, pkInfoMap map[string][]*PrimaryKeyInfo, copyState map[string]*sqltypes.Result, stats *binlogplayer.Stats) (*ReplicatorPlan, error) { +func buildReplicatorPlan(filter *binlogdatapb.Filter, colInfoMap map[string][]*ColumnInfo, copyState map[string]*sqltypes.Result, stats *binlogplayer.Stats) (*ReplicatorPlan, error) { plan := &ReplicatorPlan{ VStreamFilter: &binlogdatapb.Filter{FieldEventMode: filter.FieldEventMode}, TargetTables: make(map[string]*TablePlan), TablePlans: make(map[string]*TablePlan), - PKInfoMap: pkInfoMap, + ColInfoMap: colInfoMap, stats: stats, } - for tableName := range pkInfoMap { + for tableName := range colInfoMap { lastpk, ok := copyState[tableName] if ok && lastpk == nil { // Don't replicate uncopied tables. @@ -144,7 +144,7 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, pkInfoMap map[string][]*Pr if rule == nil { continue } - tablePlan, err := buildTablePlan(tableName, rule.Filter, pkInfoMap, lastpk, stats) + tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, stats) if err != nil { return nil, err } @@ -183,7 +183,7 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru return nil, nil } -func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKeyInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { +func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. switch { @@ -231,10 +231,10 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey From: sel.From, Where: sel.Where, }, - selColumns: make(map[string]bool), - lastpk: lastpk, - pkInfos: pkInfoMap[tableName], - stats: stats, + selColumns: make(map[string]bool), + lastpk: lastpk, + columnInfos: colInfoMap[tableName], + stats: stats, } if err := tpb.analyzeExprs(sel.SelectExprs); err != nil { @@ -255,7 +255,7 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey if err := tpb.analyzeGroupBy(sel.GroupBy); err != nil { return nil, err } - if err := tpb.analyzePK(pkInfoMap); err != nil { + if err := tpb.analyzePK(colInfoMap); err != nil { return nil, err } @@ -475,22 +475,25 @@ func (tpb *tablePlanBuilder) analyzeGroupBy(groupBy sqlparser.GroupBy) error { } // analyzePK builds tpb.pkCols. -func (tpb *tablePlanBuilder) analyzePK(pkInfoMap map[string][]*PrimaryKeyInfo) error { - pkcols, ok := pkInfoMap[tpb.name.String()] +func (tpb *tablePlanBuilder) analyzePK(colInfoMap map[string][]*ColumnInfo) error { + cols, ok := colInfoMap[tpb.name.String()] if !ok { return fmt.Errorf("table %s not found in schema", tpb.name) } - for _, pkcol := range pkcols { - cexpr := tpb.findCol(sqlparser.NewColIdent(pkcol.Name)) + for _, col := range cols { + if !col.IsPK { + continue + } + cexpr := tpb.findCol(sqlparser.NewColIdent(col.Name)) if cexpr == nil { - return fmt.Errorf("primary key column %v not found in select list", pkcol) + return fmt.Errorf("primary key column %v not found in select list", col) } if cexpr.operation != opExpr { - return fmt.Errorf("primary key column %v is not allowed to reference an aggregate expression", pkcol) + return fmt.Errorf("primary key column %v is not allowed to reference an aggregate expression", col) } cexpr.isPK = true - cexpr.dataType = pkcol.DataType - cexpr.columnType = pkcol.ColumnType + cexpr.dataType = col.DataType + cexpr.columnType = col.ColumnType tpb.pkCols = append(tpb.pkCols, cexpr) } return nil @@ -708,13 +711,13 @@ func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bi } func (tpb *tablePlanBuilder) getCharsetAndCollation(pkname string) (charSet string, collation string) { - for _, pkInfo := range tpb.pkInfos { - if strings.EqualFold(pkInfo.Name, pkname) { - if pkInfo.CharSet != "" { - charSet = fmt.Sprintf(" _%s ", pkInfo.CharSet) + for _, colInfo := range tpb.columnInfos { + if colInfo.IsPK && strings.EqualFold(colInfo.Name, pkname) { + if colInfo.CharSet != "" { + charSet = fmt.Sprintf(" _%s ", colInfo.CharSet) } - if pkInfo.Collation != "" { - collation = fmt.Sprintf(" COLLATE %s ", pkInfo.Collation) + if colInfo.Collation != "" { + collation = fmt.Sprintf(" COLLATE %s ", colInfo.Collation) } } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index a16cb1ba528..7975dc3c05c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -57,7 +57,7 @@ func newVCopier(vr *vreplicator) *vcopier { func (vc *vcopier) initTablesForCopy(ctx context.Context) error { defer vc.vr.dbClient.Rollback() - plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.pkInfoMap, nil, vc.vr.stats) + plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.colInfoMap, nil, vc.vr.stats) if err != nil { return err } @@ -200,7 +200,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma log.Infof("Copying table %s, lastpk: %v", tableName, copyState[tableName]) - plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.pkInfoMap, nil, vc.vr.stats) + plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.colInfoMap, nil, vc.vr.stats) if err != nil { return err } diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 9933d0db7d5..c62217429c9 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -105,7 +105,7 @@ func (vp *vplayer) play(ctx context.Context) error { return nil } - plan, err := buildReplicatorPlan(vp.vr.source.Filter, vp.vr.pkInfoMap, vp.copyState, vp.vr.stats) + plan, err := buildReplicatorPlan(vp.vr.source.Filter, vp.vr.colInfoMap, vp.copyState, vp.vr.stats) if err != nil { vp.vr.stats.ErrorCounts.Add([]string{"Plan"}, 1) return err diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index 9a9e8de1ff6..28cfadb672b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -78,8 +78,8 @@ type vreplicator struct { state string stats *binlogplayer.Stats // mysqld is used to fetch the local schema. - mysqld mysqlctl.MysqlDaemon - pkInfoMap map[string][]*PrimaryKeyInfo + mysqld mysqlctl.MysqlDaemon + colInfoMap map[string][]*ColumnInfo originalFKCheckSetting int64 } @@ -154,11 +154,11 @@ func (vr *vreplicator) Replicate(ctx context.Context) error { } func (vr *vreplicator) replicate(ctx context.Context) error { - pkInfo, err := vr.buildPkInfoMap(ctx) + colInfo, err := vr.buildColInfoMap(ctx) if err != nil { return err } - vr.pkInfoMap = pkInfo + vr.colInfoMap = colInfo if err := vr.getSettingFKCheck(); err != nil { return err } @@ -224,22 +224,23 @@ func (vr *vreplicator) replicate(ctx context.Context) error { } } -// PrimaryKeyInfo is used to store charset and collation for primary keys where applicable -type PrimaryKeyInfo struct { +// ColumnInfo is used to store charset and collation for primary keys where applicable +type ColumnInfo struct { Name string CharSet string Collation string DataType string ColumnType string + IsPK bool } -func (vr *vreplicator) buildPkInfoMap(ctx context.Context) (map[string][]*PrimaryKeyInfo, error) { +func (vr *vreplicator) buildColInfoMap(ctx context.Context) (map[string][]*ColumnInfo, error) { schema, err := vr.mysqld.GetSchema(ctx, vr.dbClient.DBName(), []string{"/.*/"}, nil, false) if err != nil { return nil, err } queryTemplate := "select character_set_name, collation_name, column_name, data_type, column_type from information_schema.columns where table_schema=%s and table_name=%s;" - pkInfoMap := make(map[string][]*PrimaryKeyInfo) + colInfoMap := make(map[string][]*ColumnInfo) for _, td := range schema.TableDefinitions { query := fmt.Sprintf(queryTemplate, encodeString(vr.dbClient.DBName()), encodeString(td.Name)) @@ -257,47 +258,50 @@ func (vr *vreplicator) buildPkInfoMap(ctx context.Context) (map[string][]*Primar } else { pks = td.Columns } - var pkInfos []*PrimaryKeyInfo - for _, pk := range pks { + var colInfo []*ColumnInfo + for _, row := range qr.Rows { charSet := "" collation := "" + columnName := "" + isPK := false var dataType, columnType string - for _, row := range qr.Rows { - columnName := row[2].ToString() - if strings.EqualFold(columnName, pk) { - var currentField *querypb.Field - for _, field := range td.Fields { - if field.Name == pk { - currentField = field - break - } - } - if currentField == nil { - continue - } - dataType = row[3].ToString() - columnType = row[4].ToString() - if sqltypes.IsText(currentField.Type) { - charSet = row[0].ToString() - collation = row[1].ToString() - } + columnName = row[2].ToString() + var currentField *querypb.Field + for _, field := range td.Fields { + if field.Name == columnName { + currentField = field break } } + if currentField == nil { + continue + } + dataType = row[3].ToString() + columnType = row[4].ToString() + if sqltypes.IsText(currentField.Type) { + charSet = row[0].ToString() + collation = row[1].ToString() + } if dataType == "" || columnType == "" { - return nil, fmt.Errorf("no dataType/columnType found in information_schema.columns for table %s, column %s", td.Name, pk) + return nil, fmt.Errorf("no dataType/columnType found in information_schema.columns for table %s, column %s", td.Name, columnName) + } + for _, pk := range pks { + if columnName == pk { + isPK = true + } } - pkInfos = append(pkInfos, &PrimaryKeyInfo{ - Name: pk, + colInfo = append(colInfo, &ColumnInfo{ + Name: columnName, CharSet: charSet, Collation: collation, DataType: dataType, ColumnType: columnType, + IsPK: isPK, }) } - pkInfoMap[td.Name] = pkInfos + colInfoMap[td.Name] = colInfo } - return pkInfoMap, nil + return colInfoMap, nil } func (vr *vreplicator) readSettings(ctx context.Context) (settings binlogplayer.VRSettings, numTablesToCopy int64, err error) { From 32d438eec7572be6c00c5aa7a5fdd5b5a3986973 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 13 May 2021 21:26:05 +0200 Subject: [PATCH 199/310] Ignore inserting/updating generated columns on the target. Add e2e tests to test generated columns in source as well as target for reshard and materialize Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/config.go | 6 ++-- .../vreplication/unsharded_init_data.sql | 6 ++-- .../vreplication/replicator_plan.go | 13 ++++++++ .../vreplication/table_plan_builder.go | 26 +++++++++++++++ .../tabletmanager/vreplication/vreplicator.go | 33 +++++++++++-------- 5 files changed, 65 insertions(+), 19 deletions(-) diff --git a/go/test/endtoend/vreplication/config.go b/go/test/endtoend/vreplication/config.go index 214876a2050..937d27bf904 100644 --- a/go/test/endtoend/vreplication/config.go +++ b/go/test/endtoend/vreplication/config.go @@ -6,7 +6,7 @@ create table product(pid int, description varbinary(128), primary key(pid)); create table customer(cid int, name varbinary(128), meta json default null, typ enum('individual','soho','enterprise'), sport set('football','cricket','baseball'),ts timestamp not null default current_timestamp, primary key(cid)) CHARSET=utf8mb4; create table customer_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; create table merchant(mname varchar(128), category varchar(128), primary key(mname)) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -create table orders(oid int, cid int, pid int, mname varchar(128), price int, primary key(oid)); +create table orders(oid int, cid int, pid int, mname varchar(128), price int, qty int, total int as (qty * price), total2 int as (qty * price) stored, primary key(oid)); create table order_seq(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; create table customer2(cid int, name varbinary(128), typ enum('individual','soho','enterprise'), sport set('football','cricket','baseball'),ts timestamp not null default current_timestamp, primary key(cid)); create table customer_seq2(id int, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence'; @@ -243,8 +243,8 @@ create table tenant(tenant_id binary(16), name varbinary(16), primary key (tenan "targetKeyspace": "merchant", "tableSettings": [{ "targetTable": "morders", - "sourceExpression": "select * from orders", - "create_ddl": "create table morders(oid int, cid int, mname varchar(128), pid int, price int, primary key(oid))" + "sourceExpression": "select oid, cid, mname, pid, price, qty, total from orders", + "create_ddl": "create table morders(oid int, cid int, mname varchar(128), pid int, price int, qty int, total int, total2 int as (10 * total), primary key(oid))" }] } ` diff --git a/go/test/endtoend/vreplication/unsharded_init_data.sql b/go/test/endtoend/vreplication/unsharded_init_data.sql index 1b58404cfb7..4dd20072436 100644 --- a/go/test/endtoend/vreplication/unsharded_init_data.sql +++ b/go/test/endtoend/vreplication/unsharded_init_data.sql @@ -5,9 +5,9 @@ insert into merchant(mname, category) values('monoprice', 'electronics'); insert into merchant(mname, category) values('newegg', 'electronics'); insert into product(pid, description) values(1, 'keyboard'); insert into product(pid, description) values(2, 'monitor'); -insert into orders(oid, cid, mname, pid, price) values(1, 1, 'monoprice', 1, 10); -insert into orders(oid, cid, mname, pid, price) values(2, 1, 'newegg', 2, 15); -insert into orders(oid, cid, mname, pid, price) values(3, 2, 'monoprice', 2, 20); +insert into orders(oid, cid, mname, pid, price, qty) values(1, 1, 'monoprice', 1, 10, 1); +insert into orders(oid, cid, mname, pid, price, qty) values(2, 1, 'newegg', 2, 15, 2); +insert into orders(oid, cid, mname, pid, price, qty) values(3, 2, 'monoprice', 2, 20, 3); insert into customer2(cid, name, typ, sport) values(1, 'john',1,'football,baseball'); insert into customer2(cid, name, typ, sport) values(2, 'paul','soho','cricket'); insert into customer2(cid, name, typ, sport) values(3, 'ringo','enterprise',''); diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 385e90c0f23..1eacdf2ad60 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -101,6 +101,19 @@ func (rp *ReplicatorPlan) buildFromFields(tableName string, lastpk *sqltypes.Res } for _, field := range fields { colName := sqlparser.NewColIdent(field.Name) + isGenerated := false + for _, colInfo := range tpb.columnInfos { + if !strings.EqualFold(colInfo.Name, field.Name) { + continue + } + if colInfo.IsGenerated { + isGenerated = true + } + break + } + if isGenerated { + continue + } cexpr := &colExpr{ colName: colName, colType: field.Type, diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 8ec80bc7a25..cce2d933526 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -535,6 +535,9 @@ func (tpb *tablePlanBuilder) generateInsertPart(buf *sqlparser.TrackedBuffer) *s } separator := "" for _, cexpr := range tpb.colExprs { + if tpb.isColumnGenerated(cexpr.colName) { + continue + } buf.Myprintf("%s%v", separator, cexpr.colName) separator = "," } @@ -546,6 +549,9 @@ func (tpb *tablePlanBuilder) generateValuesPart(buf *sqlparser.TrackedBuffer, bv bvf.mode = bvAfter separator := "(" for _, cexpr := range tpb.colExprs { + if tpb.isColumnGenerated(cexpr.colName) { + continue + } buf.Myprintf("%s", separator) separator = "," switch cexpr.operation { @@ -571,6 +577,9 @@ func (tpb *tablePlanBuilder) generateSelectPart(buf *sqlparser.TrackedBuffer, bv buf.WriteString(" select ") separator := "" for _, cexpr := range tpb.colExprs { + if tpb.isColumnGenerated(cexpr.colName) { + continue + } buf.Myprintf("%s", separator) separator = ", " switch cexpr.operation { @@ -604,6 +613,9 @@ func (tpb *tablePlanBuilder) generateOnDupPart(buf *sqlparser.TrackedBuffer) *sq if cexpr.isGrouped || cexpr.isPK { continue } + if tpb.isColumnGenerated(cexpr.colName) { + continue + } buf.Myprintf("%s%v=", separator, cexpr.colName) separator = ", " switch cexpr.operation { @@ -631,6 +643,9 @@ func (tpb *tablePlanBuilder) generateUpdateStatement() *sqlparser.ParsedQuery { if cexpr.isGrouped || cexpr.isPK { continue } + if tpb.isColumnGenerated(cexpr.colName) { + continue + } buf.Myprintf("%s%v=", separator, cexpr.colName) separator = ", " switch cexpr.operation { @@ -748,6 +763,17 @@ func (tpb *tablePlanBuilder) generatePKConstraint(buf *sqlparser.TrackedBuffer, buf.WriteString(")") } +func (tpb *tablePlanBuilder) isColumnGenerated(col sqlparser.ColIdent) bool { + isGenerated := false + for _, colInfo := range tpb.columnInfos { + if col.EqualString(colInfo.Name) && colInfo.IsGenerated { + isGenerated = true + break + } + } + return isGenerated +} + // bindvarFormatter is a dual mode formatter. Its behavior // can be changed dynamically changed to generate bind vars // for the 'before' row or 'after' row by setting its mode diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index 28cfadb672b..cd827ba26e1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -226,12 +226,13 @@ func (vr *vreplicator) replicate(ctx context.Context) error { // ColumnInfo is used to store charset and collation for primary keys where applicable type ColumnInfo struct { - Name string - CharSet string - Collation string - DataType string - ColumnType string - IsPK bool + Name string + CharSet string + Collation string + DataType string + ColumnType string + IsPK bool + IsGenerated bool } func (vr *vreplicator) buildColInfoMap(ctx context.Context) (map[string][]*ColumnInfo, error) { @@ -239,7 +240,7 @@ func (vr *vreplicator) buildColInfoMap(ctx context.Context) (map[string][]*Colum if err != nil { return nil, err } - queryTemplate := "select character_set_name, collation_name, column_name, data_type, column_type from information_schema.columns where table_schema=%s and table_name=%s;" + queryTemplate := "select character_set_name, collation_name, column_name, data_type, column_type, extra from information_schema.columns where table_schema=%s and table_name=%s;" colInfoMap := make(map[string][]*ColumnInfo) for _, td := range schema.TableDefinitions { @@ -264,6 +265,7 @@ func (vr *vreplicator) buildColInfoMap(ctx context.Context) (map[string][]*Colum collation := "" columnName := "" isPK := false + isGenerated := false var dataType, columnType string columnName = row[2].ToString() var currentField *querypb.Field @@ -290,13 +292,18 @@ func (vr *vreplicator) buildColInfoMap(ctx context.Context) (map[string][]*Colum isPK = true } } + extra := row[5].ToString() + if strings.Contains(strings.ToLower(extra), "generated") { + isGenerated = true + } colInfo = append(colInfo, &ColumnInfo{ - Name: columnName, - CharSet: charSet, - Collation: collation, - DataType: dataType, - ColumnType: columnType, - IsPK: isPK, + Name: columnName, + CharSet: charSet, + Collation: collation, + DataType: dataType, + ColumnType: columnType, + IsPK: isPK, + IsGenerated: isGenerated, }) } colInfoMap[td.Name] = colInfo From 8e4c944f32de3d685bc66631185b7f01aae71488 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Fri, 14 May 2021 22:14:19 +0200 Subject: [PATCH 200/310] Update logic to ignore generated columns for additional use cases Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/cluster.go | 5 ++ go/vt/sqlparser/parsed_query.go | 46 ++++++++--- .../vreplication/replicator_plan.go | 13 +-- .../vreplication/table_plan_builder.go | 34 +++++--- .../vreplication/vcopier_test.go | 81 +++++++++++++++++++ 5 files changed, 151 insertions(+), 28 deletions(-) diff --git a/go/test/endtoend/vreplication/cluster.go b/go/test/endtoend/vreplication/cluster.go index e9041cca287..8c90f3f9b41 100644 --- a/go/test/endtoend/vreplication/cluster.go +++ b/go/test/endtoend/vreplication/cluster.go @@ -127,6 +127,11 @@ func getClusterConfig(idx int, dataRootDir string) *ClusterConfig { } func init() { + // for local debugging set this variable so that each run uses VTDATAROOT instead of a random dir + // and also does not teardown the cluster for inspecting logs and the databases + if os.Getenv("VREPLICATION_E2E_DEBUG") != "" { + debug = true + } rand.Seed(time.Now().UTC().UnixNano()) originalVtdataroot = os.Getenv("VTDATAROOT") var mainVtDataRoot string diff --git a/go/vt/sqlparser/parsed_query.go b/go/vt/sqlparser/parsed_query.go index 5ce0581e5a2..7651c4bc481 100644 --- a/go/vt/sqlparser/parsed_query.go +++ b/go/vt/sqlparser/parsed_query.go @@ -32,7 +32,7 @@ import ( ) // ParsedQuery represents a parsed query where -// bind locations are precompued for fast substitutions. +// bind locations are precomputed for fast substitutions. type ParsedQuery struct { Query string bindLocations []bindLocation @@ -86,29 +86,57 @@ func (pq *ParsedQuery) Append(buf *strings.Builder, bindVariables map[string]*qu } // AppendFromRow behaves like Append but takes a querypb.Row directly, assuming that -// the fields in the row are in the same order as the placeholders in this query. -func (pq *ParsedQuery) AppendFromRow(buf *bytes2.Buffer, fields []*querypb.Field, row *querypb.Row) error { +// the fields in the row are in the same order as the placeholders in this query. The fields might include generated +// columns which are dropped, by checking against skipFields, before binding the variables +// note: there can be more fields than bind locations since extra columns might be requested from the source if not all +// primary keys columns are not in the select list, for example. Also some values in the row may not correspond for +// values from the database on the source: sum/count for aggregation queries, for example +func (pq *ParsedQuery) AppendFromRow(buf *bytes2.Buffer, fields []*querypb.Field, row *querypb.Row, skipFields map[string]bool) error { if len(fields) < len(pq.bindLocations) { - return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "wrong number of fields: got %d fields for %d bind locations ", len(fields), len(pq.bindLocations)) + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "wrong number of fields: got %d fields for %d bind locations ", + len(fields), len(pq.bindLocations)) } + + type colInfo struct { + typ querypb.Type + length int64 + offset int64 + } + rowInfo := make([]*colInfo, 0) + + offset := int64(0) + for i, field := range fields { // collect info required for fields to be bound + length := row.Lengths[i] + if !skipFields[strings.ToLower(field.Name)] { + rowInfo = append(rowInfo, &colInfo{ + typ: field.Type, + length: length, + offset: offset, + }) + } + if length > 0 { + offset += row.Lengths[i] + } + } + + // bind field values to locations var offsetQuery int - var offsetRow int64 for i, loc := range pq.bindLocations { + col := rowInfo[i] buf.WriteString(pq.Query[offsetQuery:loc.offset]) - typ := fields[i].Type + typ := col.typ if typ == querypb.Type_TUPLE { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unexpected Type_TUPLE for value %d", i) } - length := row.Lengths[i] + length := col.length if length < 0 { // -1 means a null variable; serialize it directly buf.WriteString("null") } else { - vv := sqltypes.MakeTrusted(typ, row.Values[offsetRow:offsetRow+length]) + vv := sqltypes.MakeTrusted(typ, row.Values[col.offset:col.offset+col.length]) vv.EncodeSQLBytes2(buf) - offsetRow += length } offsetQuery = loc.offset + loc.length diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 1eacdf2ad60..9558533decd 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -94,15 +94,15 @@ func (rp *ReplicatorPlan) buildExecutionPlan(fieldEvent *binlogdatapb.FieldEvent // requires us to wait for the field info sent by the source. func (rp *ReplicatorPlan) buildFromFields(tableName string, lastpk *sqltypes.Result, fields []*querypb.Field) (*TablePlan, error) { tpb := &tablePlanBuilder{ - name: sqlparser.NewTableIdent(tableName), - lastpk: lastpk, - columnInfos: rp.ColInfoMap[tableName], - stats: rp.stats, + name: sqlparser.NewTableIdent(tableName), + lastpk: lastpk, + colInfos: rp.ColInfoMap[tableName], + stats: rp.stats, } for _, field := range fields { colName := sqlparser.NewColIdent(field.Name) isGenerated := false - for _, colInfo := range tpb.columnInfos { + for _, colInfo := range tpb.colInfos { if !strings.EqualFold(colInfo.Name, field.Name) { continue } @@ -196,6 +196,7 @@ type TablePlan struct { // a primary key column (row move). PKReferences []string Stats *binlogplayer.Stats + FieldsToSkip map[string]bool } // MarshalJSON performs a custom JSON Marshalling. @@ -233,7 +234,7 @@ func (tp *TablePlan) applyBulkInsert(sqlbuffer *bytes2.Buffer, rows *binlogdatap if i > 0 { sqlbuffer.WriteString(", ") } - if err := tp.BulkInsertValues.AppendFromRow(sqlbuffer, tp.Fields, row); err != nil { + if err := tp.BulkInsertValues.AppendFromRow(sqlbuffer, tp.Fields, row, tp.FieldsToSkip); err != nil { return nil, err } } diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index cce2d933526..38b69f1060e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -47,13 +47,13 @@ type tablePlanBuilder struct { // selColumns keeps track of the columns we want to pull from source. // If Lastpk is set, we compare this list against the table's pk and // add missing references. - selColumns map[string]bool - colExprs []*colExpr - onInsert insertType - pkCols []*colExpr - lastpk *sqltypes.Result - columnInfos []*ColumnInfo - stats *binlogplayer.Stats + selColumns map[string]bool + colExprs []*colExpr + onInsert insertType + pkCols []*colExpr + lastpk *sqltypes.Result + colInfos []*ColumnInfo + stats *binlogplayer.Stats } // colExpr describes the processing to be performed to @@ -231,10 +231,10 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf From: sel.From, Where: sel.Where, }, - selColumns: make(map[string]bool), - lastpk: lastpk, - columnInfos: colInfoMap[tableName], - stats: stats, + selColumns: make(map[string]bool), + lastpk: lastpk, + colInfos: colInfoMap[tableName], + stats: stats, } if err := tpb.analyzeExprs(sel.SelectExprs); err != nil { @@ -295,6 +295,13 @@ func (tpb *tablePlanBuilder) generate() *TablePlan { bvf := &bindvarFormatter{} + fieldsToSkip := make(map[string]bool) + for _, colInfo := range tpb.colInfos { + if colInfo.IsGenerated { + fieldsToSkip[colInfo.Name] = true + } + } + return &TablePlan{ TargetName: tpb.name.String(), Lastpk: tpb.lastpk, @@ -306,6 +313,7 @@ func (tpb *tablePlanBuilder) generate() *TablePlan { Delete: tpb.generateDeleteStatement(), PKReferences: pkrefs, Stats: tpb.stats, + FieldsToSkip: fieldsToSkip, } } @@ -726,7 +734,7 @@ func (tpb *tablePlanBuilder) generateWhere(buf *sqlparser.TrackedBuffer, bvf *bi } func (tpb *tablePlanBuilder) getCharsetAndCollation(pkname string) (charSet string, collation string) { - for _, colInfo := range tpb.columnInfos { + for _, colInfo := range tpb.colInfos { if colInfo.IsPK && strings.EqualFold(colInfo.Name, pkname) { if colInfo.CharSet != "" { charSet = fmt.Sprintf(" _%s ", colInfo.CharSet) @@ -765,7 +773,7 @@ func (tpb *tablePlanBuilder) generatePKConstraint(buf *sqlparser.TrackedBuffer, func (tpb *tablePlanBuilder) isColumnGenerated(col sqlparser.ColIdent) bool { isGenerated := false - for _, colInfo := range tpb.columnInfos { + for _, colInfo := range tpb.colInfos { if col.EqualString(colInfo.Name) && colInfo.IsGenerated { isGenerated = true break diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index 326f9386bb0..d2f61982222 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -1280,3 +1280,84 @@ func TestPlayerCopyTableCancel(t *testing.T) { {"2", "bbb"}, }) } + +func TestPlayerCopyTablesWithGeneratedColumn(t *testing.T) { + flavor := strings.ToLower(env.Flavor) + // Disable tests on percona (which identifies as mysql56) and mariadb platforms in CI since they + // generated columns support was added in 5.7 and mariadb added mysql compatible generated columns in 10.2 + if strings.Contains(flavor, "56") || strings.Contains(flavor, "maria") { + return + } + defer deleteTablet(addTablet(100)) + + execStatements(t, []string{ + "create table src1(id int, val varbinary(128), val2 varbinary(128) as (concat(id, val)), val3 varbinary(128) as (concat(val, id)), id2 int, primary key(id))", + "insert into src1(id, val, id2) values(2, 'bbb', 20), (1, 'aaa', 10)", + fmt.Sprintf("create table %s.dst1(id int, val varbinary(128), val2 varbinary(128) as (concat(id, val)), val3 varbinary(128), id2 int, primary key(id))", vrepldb), + "create table src2(id int, val varbinary(128), val2 varbinary(128) as (concat(id, val)), val3 varbinary(128) as (concat(val, id)), id2 int, primary key(id))", + "insert into src2(id, val, id2) values(2, 'bbb', 20), (1, 'aaa', 10)", + fmt.Sprintf("create table %s.dst2(val3 varbinary(128), val varbinary(128), id2 int)", vrepldb), + }) + defer execStatements(t, []string{ + "drop table src1", + fmt.Sprintf("drop table %s.dst1", vrepldb), + "drop table src2", + fmt.Sprintf("drop table %s.dst2", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "dst1", + Filter: "select * from src1", + }, { + Match: "dst2", + Filter: "select val3, val, id2 from src2", + }}, + } + + bls := &binlogdatapb.BinlogSource{ + Keyspace: env.KeyspaceName, + Shard: env.ShardName, + Filter: filter, + OnDdl: binlogdatapb.OnDDLAction_IGNORE, + } + query := binlogplayer.CreateVReplicationState("test", bls, "", binlogplayer.VReplicationInit, playerEngine.dbName) + qr, err := playerEngine.Exec(query) + if err != nil { + t.Fatal(err) + } + defer func() { + query := fmt.Sprintf("delete from _vt.vreplication where id = %d", qr.InsertID) + if _, err := playerEngine.Exec(query); err != nil { + t.Fatal(err) + } + expectDeleteQueries(t) + }() + + expectNontxQueries(t, []string{ + // Create the list of tables to copy and transition to Copying state. + "/insert into _vt.vreplication", + "/update _vt.vreplication set message=", + "/insert into _vt.copy_state", + "/update _vt.vreplication set state", + // The first fast-forward has no starting point. So, it just saves the current position. + "insert into dst1(id,val,val3,id2) values (1,'aaa','aaa1',10), (2,'bbb','bbb2',20)", + `/update _vt.copy_state set lastpk='fields: rows: ' where vrepl_id=.*`, + // copy of dst1 is done: delete from copy_state. + "/delete from _vt.copy_state.*dst1", + "insert into dst2(val3,val,id2) values ('aaa1','aaa',10), ('bbb2','bbb',20)", + `/update _vt.copy_state set lastpk='fields: rows: ' where vrepl_id=.*`, + // copy of dst2 is done: delete from copy_state. + "/delete from _vt.copy_state.*dst2", + "/update _vt.vreplication set state", + }) + expectData(t, "dst1", [][]string{ + {"1", "aaa", "1aaa", "aaa1", "10"}, + {"2", "bbb", "2bbb", "bbb2", "20"}, + }) + expectData(t, "dst2", [][]string{ + {"aaa1", "aaa", "10"}, + {"bbb2", "bbb", "20"}, + }) +} From 46f534726d7e39efd31c07dab2df673aca8db465 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sat, 15 May 2021 11:33:47 +0200 Subject: [PATCH 201/310] Add vstreamer test to confirm generated columns are sent in events Signed-off-by: Rohit Nayak Signed-off-by: Rohit Nayak --- .../vreplication/vcopier_test.go | 2 +- .../tabletserver/vstreamer/vstreamer_test.go | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go index d2f61982222..c6aed04523e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_test.go @@ -1285,7 +1285,7 @@ func TestPlayerCopyTablesWithGeneratedColumn(t *testing.T) { flavor := strings.ToLower(env.Flavor) // Disable tests on percona (which identifies as mysql56) and mariadb platforms in CI since they // generated columns support was added in 5.7 and mariadb added mysql compatible generated columns in 10.2 - if strings.Contains(flavor, "56") || strings.Contains(flavor, "maria") { + if !strings.Contains(flavor, "mysql57") && !strings.Contains(flavor, "mysql80") { return } defer deleteTablet(addTablet(100)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index e30f4b82719..0fbff975571 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -1922,6 +1922,54 @@ func TestFilteredMultipleWhere(t *testing.T) { runCases(t, filter, testcases, "", nil) } +// TestGeneratedColumns just confirms that generated columns are sent in a vstream as expected +func TestGeneratedColumns(t *testing.T) { + flavor := strings.ToLower(env.Flavor) + // Disable tests on percona (which identifies as mysql56) and mariadb platforms in CI since they + // generated columns support was added in 5.7 and mariadb added mysql compatible generated columns in 10.2 + if !strings.Contains(flavor, "mysql57") && !strings.Contains(flavor, "mysql80") { + return + } + execStatements(t, []string{ + "create table t1(id int, val varbinary(6), val2 varbinary(6) as (concat(id, val)), val3 varbinary(6) as (concat(val, id)), id2 int, primary key(id))", + }) + defer execStatements(t, []string{ + "drop table t1", + }) + engine.se.Reload(context.Background()) + queries := []string{ + "begin", + "insert into t1(id, val, id2) values (1, 'aaa', 10)", + "insert into t1(id, val, id2) values (2, 'bbb', 20)", + "commit", + } + + fe := &TestFieldEvent{ + table: "t1", + db: "vttest", + cols: []*TestColumn{ + {name: "id", dataType: "INT32", colType: "", len: 11, charset: 63}, + {name: "val", dataType: "VARBINARY", colType: "", len: 6, charset: 63}, + {name: "val2", dataType: "VARBINARY", colType: "", len: 6, charset: 63}, + {name: "val3", dataType: "VARBINARY", colType: "", len: 6, charset: 63}, + {name: "id2", dataType: "INT32", colType: "", len: 11, charset: 63}, + }, + } + + testcases := []testcase{{ + input: queries, + output: [][]string{{ + `begin`, + fe.String(), + `type:ROW row_event: > > `, + `type:ROW row_event: > > `, + `gtid`, + `commit`, + }}, + }} + runCases(t, nil, testcases, "current", nil) +} + func runCases(t *testing.T, filter *binlogdatapb.Filter, testcases []testcase, position string, tablePK []*binlogdatapb.TableLastPK) { ctx, cancel := context.WithCancel(context.Background()) From 38de519945251360be5d818278e520277cd89411 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sun, 16 May 2021 17:09:05 +0200 Subject: [PATCH 202/310] Add vplayer test for generated columns Signed-off-by: Rohit Nayak --- .../vreplication/vplayer_flaky_test.go | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index f5aaaea0228..630310a3a89 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -2618,6 +2618,89 @@ func TestVReplicationLogs(t *testing.T) { } } +func TestGeneratedColumns(t *testing.T) { + defer deleteTablet(addTablet(100)) + + execStatements(t, []string{ + "create table t1(id int, val varbinary(6), val2 varbinary(6) as (concat(id, val)), val3 varbinary(6) as (concat(val, id)), id2 int, primary key(id))", + fmt.Sprintf("create table %s.t1(id int, val varbinary(6), val2 varbinary(6) as (concat(id, val)), val3 varbinary(6), id2 int, primary key(id))", vrepldb), + "create table t2(id int, val varbinary(128), val2 varbinary(128) as (concat(id, val)) stored, val3 varbinary(128) as (concat(val, id)), id2 int, primary key(id))", + fmt.Sprintf("create table %s.t2(id int, val3 varbinary(128), val varbinary(128), id2 int, primary key(id))", vrepldb), + }) + defer execStatements(t, []string{ + "drop table t1", + fmt.Sprintf("drop table %s.t1", vrepldb), + "drop table t2", + fmt.Sprintf("drop table %s.t2", vrepldb), + }) + env.SchemaEngine.Reload(context.Background()) + + filter := &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: "select * from t1", + }, { + Match: "t2", + Filter: "select id, val3, val, id2 from t2", + }}, + } + bls := &binlogdatapb.BinlogSource{ + Keyspace: env.KeyspaceName, + Shard: env.ShardName, + Filter: filter, + OnDdl: binlogdatapb.OnDDLAction_IGNORE, + } + cancel, _ := startVReplication(t, bls, "") + defer cancel() + + testcases := []struct { + input string + output string + table string + data [][]string + }{{ + input: "insert into t1(id, val, id2) values (1, 'aaa', 10)", + output: "insert into t1(id,val,val3,id2) values (1,'aaa','aaa1',10)", + table: "t1", + data: [][]string{ + {"1", "aaa", "1aaa", "aaa1", "10"}, + }, + }, { + input: "update t1 set val = 'bbb', id2 = 11 where id = 1", + output: "update t1 set val='bbb', val3='bbb1', id2=11 where id=1", + table: "t1", + data: [][]string{ + {"1", "bbb", "1bbb", "bbb1", "11"}, + }, + }, { + input: "insert into t2(id, val, id2) values (1, 'aaa', 10)", + output: "insert into t2(id,val3,val,id2) values (1,'aaa1','aaa',10)", + table: "t2", + data: [][]string{ + {"1", "aaa1", "aaa", "10"}, + }, + }, { + input: "update t2 set val = 'bbb', id2 = 11 where id = 1", + output: "update t2 set val3='bbb1', val='bbb', id2=11 where id=1", + table: "t2", + data: [][]string{ + {"1", "bbb1", "bbb", "11"}, + }, + }} + + for _, tcases := range testcases { + execStatements(t, []string{tcases.input}) + output := []string{ + tcases.output, + } + expectNontxQueries(t, output) + time.Sleep(1 * time.Second) + if tcases.table != "" { + expectData(t, tcases.table, tcases.data) + } + } +} + func expectJSON(t *testing.T, table string, values [][]string, id int, exec func(ctx context.Context, query string) (*sqltypes.Result, error)) { t.Helper() From 7789c30528deac4371a8a393d16d03c2d4f51c3a Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Sun, 16 May 2021 17:30:33 +0200 Subject: [PATCH 203/310] Add vplayer test for generated columns Signed-off-by: Rohit Nayak --- .../tabletmanager/vreplication/vplayer_flaky_test.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go index 630310a3a89..bf4d20a98f3 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer_flaky_test.go @@ -2619,6 +2619,12 @@ func TestVReplicationLogs(t *testing.T) { } func TestGeneratedColumns(t *testing.T) { + flavor := strings.ToLower(env.Flavor) + // Disable tests on percona (which identifies as mysql56) and mariadb platforms in CI since they + // generated columns support was added in 5.7 and mariadb added mysql compatible generated columns in 10.2 + if !strings.Contains(flavor, "mysql57") && !strings.Contains(flavor, "mysql80") { + return + } defer deleteTablet(addTablet(100)) execStatements(t, []string{ @@ -2694,7 +2700,6 @@ func TestGeneratedColumns(t *testing.T) { tcases.output, } expectNontxQueries(t, output) - time.Sleep(1 * time.Second) if tcases.table != "" { expectData(t, tcases.table, tcases.data) } From 6d9e3cbe5eea10bb4f361f8a746d1de3bbdfb6e8 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Mon, 7 Jun 2021 11:16:07 +0200 Subject: [PATCH 204/310] Improve comment Signed-off-by: Rohit Nayak --- go/vt/sqlparser/parsed_query.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/sqlparser/parsed_query.go b/go/vt/sqlparser/parsed_query.go index 7651c4bc481..1fff8b37c3d 100644 --- a/go/vt/sqlparser/parsed_query.go +++ b/go/vt/sqlparser/parsed_query.go @@ -89,7 +89,7 @@ func (pq *ParsedQuery) Append(buf *strings.Builder, bindVariables map[string]*qu // the fields in the row are in the same order as the placeholders in this query. The fields might include generated // columns which are dropped, by checking against skipFields, before binding the variables // note: there can be more fields than bind locations since extra columns might be requested from the source if not all -// primary keys columns are not in the select list, for example. Also some values in the row may not correspond for +// primary keys columns are present in the target table, for example. Also some values in the row may not correspond for // values from the database on the source: sum/count for aggregation queries, for example func (pq *ParsedQuery) AppendFromRow(buf *bytes2.Buffer, fields []*querypb.Field, row *querypb.Row, skipFields map[string]bool) error { if len(fields) < len(pq.bindLocations) { From d0714c7721e76cf021cf23a9b45d480079b8875e Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Mon, 7 Jun 2021 14:40:37 +0200 Subject: [PATCH 205/310] Fix merge Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/helper.go | 4 ++-- go/test/endtoend/vreplication/vreplication_test_env.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go/test/endtoend/vreplication/helper.go b/go/test/endtoend/vreplication/helper.go index 15726e2dd36..01a80b27982 100644 --- a/go/test/endtoend/vreplication/helper.go +++ b/go/test/endtoend/vreplication/helper.go @@ -189,11 +189,11 @@ func validateDryRunResults(t *testing.T, output string, want []string) { } if !match { fail = true - t.Logf("want %s, got %s\n", w, gotDryRun[i]) + t.Fatalf("want %s, got %s\n", w, gotDryRun[i]) } } if fail { - t.Fatal("Dry run results don't match") + t.Fatalf("Dry run results don't match, want %s, got %s", want, gotDryRun) } } diff --git a/go/test/endtoend/vreplication/vreplication_test_env.go b/go/test/endtoend/vreplication/vreplication_test_env.go index 240649ce7ba..244025b83de 100644 --- a/go/test/endtoend/vreplication/vreplication_test_env.go +++ b/go/test/endtoend/vreplication/vreplication_test_env.go @@ -49,10 +49,10 @@ var dryRunResultsReadCustomerShard = []string{ var dryRunResultsSwitchWritesM2m3 = []string{ "Lock keyspace merchant", "Stop streams on keyspace merchant", - "/ Id 2 Keyspace customer Shard -80 Rules rules:{match:\"morders\" filter:\"select * from orders where in_keyrange(mname, 'merchant.md5', '-80')\"} at Position ", - "/ Id 2 Keyspace customer Shard -80 Rules rules:{match:\"morders\" filter:\"select * from orders where in_keyrange(mname, 'merchant.md5', '80-')\"} at Position ", - "/ Id 3 Keyspace customer Shard 80- Rules rules:{match:\"morders\" filter:\"select * from orders where in_keyrange(mname, 'merchant.md5', '-80')\"} at Position ", - "/ Id 3 Keyspace customer Shard 80- Rules rules:{match:\"morders\" filter:\"select * from orders where in_keyrange(mname, 'merchant.md5', '80-')\"} at Position ", + "/ Id 2 Keyspace customer Shard -80 Rules rules:{match:\"morders\" filter:\"select oid, cid, mname, pid, price, qty, total from orders where in_keyrange(mname, 'merchant.md5', '-80')\"} at Position ", + "/ Id 2 Keyspace customer Shard -80 Rules rules:{match:\"morders\" filter:\"select oid, cid, mname, pid, price, qty, total from orders where in_keyrange(mname, 'merchant.md5', '80-')\"} at Position ", + "/ Id 3 Keyspace customer Shard 80- Rules rules:{match:\"morders\" filter:\"select oid, cid, mname, pid, price, qty, total from orders where in_keyrange(mname, 'merchant.md5', '-80')\"} at Position ", + "/ Id 3 Keyspace customer Shard 80- Rules rules:{match:\"morders\" filter:\"select oid, cid, mname, pid, price, qty, total from orders where in_keyrange(mname, 'merchant.md5', '80-')\"} at Position ", "/ Id 4 Keyspace customer Shard -80 Rules rules:{match:\"msales\" filter:\"select mname as merchant_name, count(*) as kount, sum(price) as amount from orders where in_keyrange(mname, 'merchant.md5', '-80') group by merchant_name\"} at Position ", "/ Id 4 Keyspace customer Shard -80 Rules rules:{match:\"msales\" filter:\"select mname as merchant_name, count(*) as kount, sum(price) as amount from orders where in_keyrange(mname, 'merchant.md5', '80-') group by merchant_name\"} at Position ", "/ Id 5 Keyspace customer Shard 80- Rules rules:{match:\"msales\" filter:\"select mname as merchant_name, count(*) as kount, sum(price) as amount from orders where in_keyrange(mname, 'merchant.md5', '-80') group by merchant_name\"} at Position ", From 43c1fbb59f2ba9206cd5fb26cb208333fa316c3e Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Mon, 7 Jun 2021 19:06:45 -0400 Subject: [PATCH 206/310] [trace] Add support for turning on logging in tracing plugins with the standard logging infrastructure Signed-off-by: Andrew Mason --- go/trace/logger.go | 32 ++++++++++++++++++++++++++++++++ go/trace/plugin_datadog.go | 12 +++++++++--- go/trace/plugin_jaeger.go | 9 ++++++++- go/trace/trace.go | 1 + 4 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 go/trace/logger.go diff --git a/go/trace/logger.go b/go/trace/logger.go new file mode 100644 index 00000000000..158fab3c8b8 --- /dev/null +++ b/go/trace/logger.go @@ -0,0 +1,32 @@ +/* +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 trace + +import "vitess.io/vitess/go/vt/log" + +// traceLogger wraps the standard vitess log package to satisfy the datadog and +// jaeger logger interfaces. +type traceLogger struct{} + +// Log is part of the ddtrace.Logger interface. Datadog only ever logs errors. +func (*traceLogger) Log(msg string) { log.Errorf(msg) } + +// Error is part of the jaeger.Logger interface. +func (*traceLogger) Error(msg string) { log.Errorf(msg) } + +// Infof is part of the jaeger.Logger interface. +func (*traceLogger) Infof(msg string, args ...interface{}) { log.Infof(msg, args...) } diff --git a/go/trace/plugin_datadog.go b/go/trace/plugin_datadog.go index 45b743c408e..f222af1cbeb 100644 --- a/go/trace/plugin_datadog.go +++ b/go/trace/plugin_datadog.go @@ -20,12 +20,18 @@ func newDatadogTracer(serviceName string) (tracingService, io.Closer, error) { return nil, nil, fmt.Errorf("need host and port to datadog agent to use datadog tracing") } - t := opentracer.New( - ddtracer.WithAgentAddr(*dataDogHost+":"+*dataDogPort), + opts := []ddtracer.StartOption{ + ddtracer.WithAgentAddr(*dataDogHost + ":" + *dataDogPort), ddtracer.WithServiceName(serviceName), ddtracer.WithDebugMode(true), ddtracer.WithSampler(ddtracer.NewRateSampler(samplingRate.Get())), - ) + } + + if *enableLogging { + opts = append(opts, ddtracer.WithLogger(&traceLogger{})) + } + + t := opentracer.New(opts...) opentracing.SetGlobalTracer(t) diff --git a/go/trace/plugin_jaeger.go b/go/trace/plugin_jaeger.go index ba64e277bdf..38781ed8d5b 100644 --- a/go/trace/plugin_jaeger.go +++ b/go/trace/plugin_jaeger.go @@ -98,7 +98,14 @@ func newJagerTracerFromEnv(serviceName string) (tracingService, io.Closer, error log.Infof("Tracing sampler type %v (param: %v)", cfg.Sampler.Type, cfg.Sampler.Param) - tracer, closer, err := cfg.NewTracer() + var opts []config.Option + if *enableLogging { + opts = append(opts, config.Logger(&traceLogger{})) + } else if cfg.Reporter.LogSpans { + log.Warningf("JAEGER_REPORTER_LOG_SPANS was set, but -tracing-enable-logging was not; spans will not be logged") + } + + tracer, closer, err := cfg.NewTracer(opts...) if err != nil { return nil, &nilCloser{}, err diff --git a/go/trace/trace.go b/go/trace/trace.go index 0038051468a..181d3964e57 100644 --- a/go/trace/trace.go +++ b/go/trace/trace.go @@ -133,6 +133,7 @@ var currentTracer tracingService = noopTracingServer{} var ( tracingServer = flag.String("tracer", "noop", "tracing service to use") + enableLogging = flag.Bool("tracing-enable-logging", false, "whether to enable logging in the tracing service") ) // StartTracing enables tracing for a named service From ba65125b8044d6070780a604042a5ffc91d388b0 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Mon, 7 Jun 2021 19:12:10 -0400 Subject: [PATCH 207/310] [vtadmin] expose trace logging flag in vtadmin entrypoint Signed-off-by: Andrew Mason --- go/cmd/vtadmin/main.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/go/cmd/vtadmin/main.go b/go/cmd/vtadmin/main.go index 706fefd04fa..d1ee284b59f 100644 --- a/go/cmd/vtadmin/main.go +++ b/go/cmd/vtadmin/main.go @@ -123,9 +123,10 @@ func main() { rootCmd.Flags().Var(&clusterFileConfig, "cluster-config", "path to a yaml cluster configuration. see clusters.example.yaml") // (TODO:@amason) provide example config. rootCmd.Flags().Var(&defaultClusterConfig, "cluster-defaults", "default options for all clusters") - rootCmd.Flags().AddGoFlag(flag.Lookup("tracer")) // defined in go/vt/trace - rootCmd.Flags().AddGoFlag(flag.Lookup("tracing-sampling-type")) // defined in go/vt/trace - rootCmd.Flags().AddGoFlag(flag.Lookup("tracing-sampling-rate")) // defined in go/vt/trace + rootCmd.Flags().AddGoFlag(flag.Lookup("tracer")) // defined in go/vt/trace + rootCmd.Flags().AddGoFlag(flag.Lookup("tracing-enable-logging")) // defined in go/vt/trace + rootCmd.Flags().AddGoFlag(flag.Lookup("tracing-sampling-type")) // defined in go/vt/trace + rootCmd.Flags().AddGoFlag(flag.Lookup("tracing-sampling-rate")) // defined in go/vt/trace rootCmd.Flags().BoolVar(&opts.EnableTracing, "grpc-tracing", false, "whether to enable tracing on the gRPC server") rootCmd.Flags().BoolVar(&httpOpts.EnableTracing, "http-tracing", false, "whether to enable tracing on the HTTP server") From 732a088431f12aebe81d24154fc03b8c2dd7b85a Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 8 Jun 2021 10:26:25 -0400 Subject: [PATCH 208/310] [vtctldclient] Update help text for legacy shim Also remove the custom help func hack, because it turns out we don't actually need it (thank goodness) Signed-off-by: Andrew Mason --- .../internal/command/legacy_shim.go | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/go/cmd/vtctldclient/internal/command/legacy_shim.go b/go/cmd/vtctldclient/internal/command/legacy_shim.go index 0d6bd8494b6..f4036fd26ae 100644 --- a/go/cmd/vtctldclient/internal/command/legacy_shim.go +++ b/go/cmd/vtctldclient/internal/command/legacy_shim.go @@ -23,7 +23,6 @@ import ( "strings" "github.com/spf13/cobra" - "k8s.io/apimachinery/pkg/util/sets" "vitess.io/vitess/go/cmd/vtctldclient/cli" "vitess.io/vitess/go/vt/log" @@ -38,13 +37,41 @@ var ( // RPCs. This allows users to use a single binary to make RPCs against both // the new and old vtctld gRPC APIs. LegacyVtctlCommand = &cobra.Command{ - Use: "LegacyVtctlCommand", + Use: "LegacyVtctlCommand -- [flags ...] [args ...]", Short: "Invoke a legacy vtctlclient command. Flag parsing is best effort.", Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { cli.FinishedParsing(cmd) return runLegacyCommand(args) }, + Long: strings.TrimSpace(` +LegacyVtctlCommand uses the legacy vtctl grpc client to make an ExecuteVtctlCommand +rpc to a vtctld. + +This command exists to support a smooth transition of any scripts that relied on +vtctlclient during the migration to the new vtctldclient, and will be removed, +following the Vitess project's standard deprecation cycle, once all commands +have been migrated to the new VtctldServer api. + +To see the list of available legacy commands, run "LegacyVtctlCommand -- help". +Note that, as with the old client, this requires a running server, as the flag +parsing and help/usage text generation, is done server-side. + +Also note that, in order to defer that flag parsing to the server side, you must +use the double-dash ("--") after the LegacyVtctlCommand subcommand string, or +the client-side flag parsing library we are using will attempt to parse those +flags (and fail). +`), + Example: strings.TrimSpace(` +LegacyVtctlCommand help # displays this help message +LegacyVtctlCommand -- help # displays help for supported legacy vtctl commands + +# When using legacy command that take arguments, a double dash must be used +# before the first flag argument, like in the first example. The double dash may +# be used, however, at any point after the "LegacyVtctlCommand" string, as in +# the second example. +LegacyVtctlCommand AddCellInfo -- -server_address "localhost:1234" -root "/vitess/cell1" +LegacyVtctlCommand -- AddCellInfo -server_address "localhost:5678" -root "/vitess/cell1"`), } ) @@ -73,29 +100,5 @@ func runLegacyCommand(args []string) error { } func init() { - LegacyVtctlCommand.SetHelpFunc(func(cmd *cobra.Command, args []string) { - // PreRun (and PersistentPreRun) do not run when a Help command is - // being executed, so we need to duplicate the `--server` flag check - // here before we attempt to invoke the legacy help command. - if err := ensureServerArg(); err != nil { - log.Error(err) - return - } - - realArgs := cmd.Flags().Args() - - if len(realArgs) == 0 { - realArgs = append(realArgs, "help") - } - - argSet := sets.NewString(realArgs...) - if !argSet.HasAny("help", "-h", "--help") { - // Cobra tends to swallow the help flag, so we need to put it back - // into the arg slice that we pass to runLegacyCommand. - realArgs = append(realArgs, "-h") - } - - _ = runLegacyCommand(realArgs) - }) Root.AddCommand(LegacyVtctlCommand) } From 6b52e982ccdf1c20b1b11d84693e5d57da6b46b6 Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Tue, 8 Jun 2021 17:20:51 +0200 Subject: [PATCH 209/310] Address review comments Signed-off-by: Rohit Nayak --- .../tabletmanager/vreplication/table_plan_builder.go | 6 ++---- go/vt/vttablet/tabletmanager/vreplication/vreplicator.go | 6 +++--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 38b69f1060e..9d094b7d462 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -772,14 +772,12 @@ func (tpb *tablePlanBuilder) generatePKConstraint(buf *sqlparser.TrackedBuffer, } func (tpb *tablePlanBuilder) isColumnGenerated(col sqlparser.ColIdent) bool { - isGenerated := false for _, colInfo := range tpb.colInfos { if col.EqualString(colInfo.Name) && colInfo.IsGenerated { - isGenerated = true - break + return true } } - return isGenerated + return false } // bindvarFormatter is a dual mode formatter. Its behavior diff --git a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go index cd827ba26e1..2c12568f527 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vreplicator.go @@ -224,7 +224,7 @@ func (vr *vreplicator) replicate(ctx context.Context) error { } } -// ColumnInfo is used to store charset and collation for primary keys where applicable +// ColumnInfo is used to store charset and collation type ColumnInfo struct { Name string CharSet string @@ -292,8 +292,8 @@ func (vr *vreplicator) buildColInfoMap(ctx context.Context) (map[string][]*Colum isPK = true } } - extra := row[5].ToString() - if strings.Contains(strings.ToLower(extra), "generated") { + extra := strings.ToLower(row[5].ToString()) + if strings.Contains(extra, "generated") || strings.Contains(extra, "virtual") { isGenerated = true } colInfo = append(colInfo, &ColumnInfo{ From 3f0d6bfceb7700ac1a517542c4355cb65b160fa7 Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Tue, 8 Jun 2021 14:37:34 -0700 Subject: [PATCH 210/310] Adds padding when doing keyrange comparisons Signed-off-by: Rafael Chacon --- go/vt/key/key.go | 26 +++++- go/vt/key/key_test.go | 161 ++++++++++++++++++++++++++++++++++ go/vt/topotools/split_test.go | 12 +++ 3 files changed, 195 insertions(+), 4 deletions(-) diff --git a/go/vt/key/key.go b/go/vt/key/key.go index ed488257830..e271886012e 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -194,8 +194,26 @@ func KeyRangeEqual(left, right *topodatapb.KeyRange) bool { if right == nil { return len(left.Start) == 0 && len(left.End) == 0 } - return bytes.Equal(left.Start, right.Start) && - bytes.Equal(left.End, right.End) + return bytes.Equal(addPadding(left.Start), addPadding(right.Start)) && + bytes.Equal(addPadding(left.End), addPadding(right.End)) +} + +// addPadding adds padding to make sure keyrange represents an 8 byte integer. +// From Vitess docs: +// A hash vindex produces an 8-byte number. +// This means that all numbers less than 0x8000000000000000 will fall in shard -80. +// Any number with the highest bit set will be >= 0x8000000000000000, and will therefore +// belong to shard 80-. +// This means that from a keyrange perspective -80 == 00-80 == 0000-8000 == 000000-800000 +// If we don't do this padding, we could run into issues when transitioning from keyranges +// that use 2 bytes to 4 bytes. +func addPadding(bytes []byte) []byte { + paddedRange := bytes + + for i := len(bytes); i < 8; i++ { + paddedRange = append(paddedRange, 0) + } + return paddedRange } // KeyRangeStartSmaller returns true if right's keyrange start is _after_ left's start @@ -217,7 +235,7 @@ func KeyRangeStartEqual(left, right *topodatapb.KeyRange) bool { if right == nil { return len(left.Start) == 0 } - return bytes.Equal(left.Start, right.Start) + return bytes.Equal(addPadding(left.Start), addPadding(right.Start)) } // KeyRangeEndEqual returns true if both key ranges have the same end @@ -228,7 +246,7 @@ func KeyRangeEndEqual(left, right *topodatapb.KeyRange) bool { if right == nil { return len(left.End) == 0 } - return bytes.Equal(left.End, right.End) + return bytes.Equal(addPadding(left.End), addPadding(right.End)) } // For more info on the following functions, see: diff --git a/go/vt/key/key_test.go b/go/vt/key/key_test.go index f92d746f6e8..d8d98e92f2b 100644 --- a/go/vt/key/key_test.go +++ b/go/vt/key/key_test.go @@ -241,6 +241,167 @@ func TestKeyRangeAdd(t *testing.T) { } } +func TestKeyRangeEndEqual(t *testing.T) { + testcases := []struct { + first string + second string + out bool + }{{ + first: "", + second: "", + out: true, + }, { + first: "", + second: "-80", + out: false, + }, { + first: "40-", + second: "10-", + out: true, + }, { + first: "-8000", + second: "-80", + out: true, + }, { + first: "-8000", + second: "-8000000000000000", + out: true, + }, { + first: "-80", + second: "-8000", + out: true, + }} + stringToKeyRange := func(spec string) *topodatapb.KeyRange { + if spec == "" { + return nil + } + parts := strings.Split(spec, "-") + if len(parts) != 2 { + panic("invalid spec") + } + kr, err := ParseKeyRangeParts(parts[0], parts[1]) + if err != nil { + panic(err) + } + return kr + } + + for _, tcase := range testcases { + first := stringToKeyRange(tcase.first) + second := stringToKeyRange(tcase.second) + out := KeyRangeEndEqual(first, second) + if out != tcase.out { + t.Fatalf("KeyRangeEndEqual(%q, %q) expected %t, got %t", tcase.first, tcase.second, tcase.out, out) + } + } +} + +func TestKeyRangeStartEqual(t *testing.T) { + testcases := []struct { + first string + second string + out bool + }{{ + first: "", + second: "", + out: true, + }, { + first: "", + second: "-80", + out: true, + }, { + first: "40-", + second: "20-", + out: false, + }, { + first: "-8000", + second: "-80", + out: true, + }, { + first: "-8000", + second: "-8000000000000000", + out: true, + }, { + first: "-80", + second: "-8000", + out: true, + }} + stringToKeyRange := func(spec string) *topodatapb.KeyRange { + if spec == "" { + return nil + } + parts := strings.Split(spec, "-") + if len(parts) != 2 { + panic("invalid spec") + } + kr, err := ParseKeyRangeParts(parts[0], parts[1]) + if err != nil { + panic(err) + } + return kr + } + + for _, tcase := range testcases { + first := stringToKeyRange(tcase.first) + second := stringToKeyRange(tcase.second) + out := KeyRangeStartEqual(first, second) + if out != tcase.out { + t.Fatalf("KeyRangeStartEqual(%q, %q) expected %t, got %t", tcase.first, tcase.second, tcase.out, out) + } + } +} + +func TestKeyRangeEqual(t *testing.T) { + testcases := []struct { + first string + second string + out bool + }{{ + first: "", + second: "", + out: true, + }, { + first: "", + second: "-80", + out: false, + }, { + first: "-8000", + second: "-80", + out: true, + }, { + first: "-8000", + second: "-8000000000000000", + out: true, + }, { + first: "-80", + second: "-8000", + out: true, + }} + stringToKeyRange := func(spec string) *topodatapb.KeyRange { + if spec == "" { + return nil + } + parts := strings.Split(spec, "-") + if len(parts) != 2 { + panic("invalid spec") + } + kr, err := ParseKeyRangeParts(parts[0], parts[1]) + if err != nil { + panic(err) + } + return kr + } + + for _, tcase := range testcases { + first := stringToKeyRange(tcase.first) + second := stringToKeyRange(tcase.second) + out := KeyRangeEqual(first, second) + if out != tcase.out { + t.Fatalf("KeyRangeEqual(%q, %q) expected %t, got %t", tcase.first, tcase.second, tcase.out, out) + } + } +} + func TestEvenShardsKeyRange_Error(t *testing.T) { testCases := []struct { i, n int diff --git a/go/vt/topotools/split_test.go b/go/vt/topotools/split_test.go index 137eb4ce18a..0ba13a3524d 100644 --- a/go/vt/topotools/split_test.go +++ b/go/vt/topotools/split_test.go @@ -105,6 +105,18 @@ func TestValidateForReshard(t *testing.T) { sources: []string{"-80", "80-"}, targets: []string{"-40", "40-"}, out: "", + }, { + sources: []string{"52-53"}, + targets: []string{"5200-5240", "5240-5280", "5280-52c0", "52c0-5300"}, + out: "", + }, { + sources: []string{"5200-5300"}, + targets: []string{"520000-524000", "524000-528000", "528000-52c000", "52c000-530000"}, + out: "", + }, { + sources: []string{"-80", "80-"}, + targets: []string{"-4000000000000000", "4000000000000000-8000000000000000", "8000000000000000-80c0000000000000", "80c0000000000000-"}, + out: "", }, { sources: []string{"80-", "-80"}, targets: []string{"-40", "40-"}, From 1a4bf681a549b3e676cb7b09d61b6a8b8669b76a Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Tue, 8 Jun 2021 15:56:12 -0700 Subject: [PATCH 211/310] Change name to be less confusing Signed-off-by: Rafael Chacon --- go/vt/key/key.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/vt/key/key.go b/go/vt/key/key.go index e271886012e..57af2e570e9 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -207,13 +207,13 @@ func KeyRangeEqual(left, right *topodatapb.KeyRange) bool { // This means that from a keyrange perspective -80 == 00-80 == 0000-8000 == 000000-800000 // If we don't do this padding, we could run into issues when transitioning from keyranges // that use 2 bytes to 4 bytes. -func addPadding(bytes []byte) []byte { - paddedRange := bytes +func addPadding(kr []byte) []byte { + paddedKr := kr - for i := len(bytes); i < 8; i++ { - paddedRange = append(paddedRange, 0) + for i := len(kr); i < 8; i++ { + paddedKr = append(paddedKr, 0) } - return paddedRange + return paddedKr } // KeyRangeStartSmaller returns true if right's keyrange start is _after_ left's start From 08eef0cb8163d2481ab0f1149d00d21b979b1a8b Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Wed, 9 Jun 2021 13:24:41 +0530 Subject: [PATCH 212/310] added function to check when the docker image is ready Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver.go | 43 +++++++++++++++++++- go/test/endtoend/docker/vttestserver_test.go | 13 +++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/go/test/endtoend/docker/vttestserver.go b/go/test/endtoend/docker/vttestserver.go index 81f92661489..994c55b155d 100644 --- a/go/test/endtoend/docker/vttestserver.go +++ b/go/test/endtoend/docker/vttestserver.go @@ -17,12 +17,14 @@ limitations under the License. package docker import ( + "encoding/json" "fmt" "os" "os/exec" "path" "strconv" "strings" + "time" ) const ( @@ -63,7 +65,7 @@ func (v *vttestserver) startDockerImage() error { cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("NUM_SHARDS=%s", strings.Join(convertToStringSlice(v.numShards), ","))) cmd.Args = append(cmd.Args, "-e", "MYSQL_BIND_HOST=0.0.0.0") cmd.Args = append(cmd.Args, "-e", fmt.Sprintf("MYSQL_MAX_CONNECTIONS=%d", v.mysqlMaxConnecetions)) - cmd.Args = append(cmd.Args, `--health-cmd="mysqladmin ping -h127.0.0.1 -P33577"`) + cmd.Args = append(cmd.Args, "--health-cmd", "mysqladmin ping -h127.0.0.1 -P33577") cmd.Args = append(cmd.Args, "--health-interval=5s") cmd.Args = append(cmd.Args, "--health-timeout=2s") cmd.Args = append(cmd.Args, "--health-retries=5") @@ -76,6 +78,45 @@ func (v *vttestserver) startDockerImage() error { return nil } +// dockerStatus is a struct used to unmarshal json output from `docker inspect` +type dockerStatus struct { + State struct { + Health struct { + Status string + } + } +} + +// waitUntilDockerHealthy waits until the docker image is healthy. It takes in as argument the amount of seconds to wait before timeout +func (v *vttestserver) waitUntilDockerHealthy(timeoutDelay int) error { + timeOut := time.After(time.Duration(timeoutDelay) * time.Second) + + for { + select { + case <-timeOut: + // return error due to timeout + return fmt.Errorf("timed out waiting for docker image to start") + case <-time.After(time.Second): + cmd := exec.Command("docker", "inspect", "vttestserver-end2end-test") + out, err := cmd.Output() + if err != nil { + return err + } + var x []dockerStatus + err = json.Unmarshal(out, &x) + if err != nil { + return err + } + if len(x) > 0 { + status := x[0].State.Health.Status + if status == "healthy" { + return nil + } + } + } + } +} + // convertToStringSlice converts an integer slice to string slice func convertToStringSlice(intSlice []int) []string { var stringSlice []string diff --git a/go/test/endtoend/docker/vttestserver_test.go b/go/test/endtoend/docker/vttestserver_test.go index 4226f0c0c0a..797e8f2e5c7 100644 --- a/go/test/endtoend/docker/vttestserver_test.go +++ b/go/test/endtoend/docker/vttestserver_test.go @@ -21,7 +21,6 @@ import ( "fmt" "os" "testing" - "time" "github.com/google/go-cmp/cmp" @@ -53,7 +52,8 @@ func TestUnsharded(t *testing.T) { defer vtest.teardown() // wait for the docker to be setup - time.Sleep(10 * time.Second) + err = vtest.waitUntilDockerHealthy(10) + require.NoError(t, err) ctx := context.Background() vttestParams := mysql.ConnParams{ @@ -83,7 +83,8 @@ func TestSharded(t *testing.T) { defer vtest.teardown() // wait for the docker to be setup - time.Sleep(10 * time.Second) + err = vtest.waitUntilDockerHealthy(10) + require.NoError(t, err) ctx := context.Background() vttestParams := mysql.ConnParams{ @@ -115,7 +116,8 @@ func TestMysqlMaxCons(t *testing.T) { defer vtest.teardown() // wait for the docker to be setup - time.Sleep(10 * time.Second) + err = vtest.waitUntilDockerHealthy(10) + require.NoError(t, err) ctx := context.Background() vttestParams := mysql.ConnParams{ @@ -147,7 +149,8 @@ func TestLargeNumberOfKeyspaces(t *testing.T) { defer vtest.teardown() // wait for the docker to be setup - time.Sleep(15 * time.Second) + err = vtest.waitUntilDockerHealthy(15) + require.NoError(t, err) ctx := context.Background() vttestParams := mysql.ConnParams{ From ce857aabd75cb3d48e0c2eb4b84b7a44ce9f8fb5 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Wed, 9 Jun 2021 17:10:53 +0300 Subject: [PATCH 213/310] Updates and Corrections to v9 Release Notes Signed-off-by: Alkin Tezuysal --- doc/releasenotes/9_0_0_release_notes.md | 130 +++++++++++++++--------- 1 file changed, 84 insertions(+), 46 deletions(-) diff --git a/doc/releasenotes/9_0_0_release_notes.md b/doc/releasenotes/9_0_0_release_notes.md index 7d8b5f99e24..4b6f0b13808 100644 --- a/doc/releasenotes/9_0_0_release_notes.md +++ b/doc/releasenotes/9_0_0_release_notes.md @@ -21,6 +21,7 @@ Vitess 9.0 is not compatible with the previous release of the Vitess Kubernetes * Bug fix regression in /healthz #7090 * Fix metadata related operation hangs when zk down #7228 * Fix accidentally-broken legacy vtctl output format #7285 +* Healthcheck: use isIncluded correctly to fix replica/rdonly routing bug #6904 ## Functionality Added or Changed @@ -68,26 +69,31 @@ Vitess 9.0 is not compatible with the previous release of the Vitess Kubernetes * VTGate: Cache only dml and select plans #7196 * VTGate: Planning and Parsing Support for Alter Table #7199 * VTGate: Add FindAllShardsInKeyspace to vtctldserver #7201 +* VTGate: Initial implementation of vtctld service #7128 * VTGate: improve-log: FAILED_PRECONDITION #7215 -* VTGate: Planner refactoring #7103 -* VTGate: Migrate `vtctlclient InitShardMaster` => `vtctldclient InitShardPrimary` #7220 -* VTGate: Add Planning and Parsing Support for Truncate, Rename, Drop Index and Flush #7242 -* VTGate: Fix create table format function to include if not exists #7250 -* VTGate: Added default databases when calling 'show databases' #7256 -* VTGate : Add Update.AddWhere to mirror Select.AddWhere #7277 -* VTGate :Rremoved resolver usage from StreamExecute #7281 -* VTGate: Adding a MySQL connection at Vtgate to run queries on it directly in case of testing mode #7291 -* VTGate: Added vitess_version as variable #7295 * VTGate: Default to false for system settings to be changed per session at the database connection level #7299 -* VTGate: Gen4: Add Limit clause support #7312 -* VTGate: Gen4: Handling subquery in query graph #7313 -* VTGate: Addition of @@enable_system_settings #7300 * VTGate: Route INFORMATION_SCHEMA queries #6932 * VTGate: Adds Planning and Parsing Support for Create Index of MySQL 5.7 #7024 * VTGate: Log sql which exceeds max memory rows #7055 +* VTGate: Enable Client Session Tracking feature in mysql protocol #6783 +* VTGate: Show columns from table_name targeted like select queries #6825 +* VTGate: This PR adds logic to simplify subquery expressions that are simple to +* VTGate: Adding MySQL Check Constraints #6865 +* VTGate: Manage read your own writes system settings #6871 +* VTGate: Allow table_schema comparisons #6887 +* VTGate: Additional options support for SELECT INTO and LOAD DATA #6872 +* VTGate: Fixes vtgate which throws an error in case of empty statements #6947 +* VTGate: [Forward Port] #6940 - Fix error handling in olap mode #6949 +* VTGate: Adds Planning and Parsing Support for Create View of MySQL 5.7 #7060 +* VTGate: fix error: cannot run Select on table "dual" #7118 +* VTGate: Allow system table to be set as default database #7150 +* VTGate: Move auto_increment from reserved to non reserved keyword #7162 +* VTGate: Add only expr of aliasedExpr to weightstring function #7165 +* VTGate: [9.0] don't try to compare varchars in vtgate #7271 * VTExplain: Add sequence table support for vtexplain #7186 * VSchema: Support back-quoted names #7073 * Healthcheck: healthy list should be recomputed when a tablet is removed #7176 +* Healthcheck: Hellcatlk wants to merge 1 commit into master from master #6953 ### Set Statement Support @@ -108,18 +114,18 @@ Set statement support has been added in Vitess. There are [some system variables * VReplication: MoveTables: delete routing rules and update vschema on Complete and Abort #7234 * VReplication: V2 Workflow Start: wait for streams to start and report errors if any while starting a workflow #7248 * VReplication: Ignore temp tables created by onlineddl #7159 -* VReplication V2 Workflows: rename Abort to Cancel #7276 -* VReplication DryRun: Report current dry run results for v2 commands #7255 -* VReplication: Miscellaneous improvements #7275 -* VReplication: Tablet throttle support "/throttle/check-self" available on all tablets #7319 -* VStreamer Events: remove preceding zeroes from decimals in Row Events #7297 -* Workflow Show: use timeUpdated to calculate vreplication lag #7342 -* vtctl: Add missing err checks for VReplication v2 #7361 +* VReplication: Set time zone to UTC while streaming rows #6845 +* VReplication: Materialization and character sets: Add test to verify/demo a workaround for charset issues while using string functions in filters #6847 +* VReplication: Tool to diagnose vreplication issues in production #6892 * VStreamer Field Event: add allowed values for set/enum #6981 * VDiff: lock keyspace while snapshoting, restart target in case of errors #7012 +* VDiff: make enums comparable #6880 +* VDiff: add ability to limit number of rows to compare #6890 +* VDiff/Tablet Picker: fix issue where vdiff sleeps occasionally for tablet picker retry interval #6944 * [vtctld]: fix error state in Workflow Show #6970 * [vtctld] Workflow command: minor fixes #7008 -* [vtctl] Add missing err checks for VReplication v2 #7361 +* MoveTables: validate that source tables exist, move all tables #7018 +* SwitchWrites bug: reverse replication workflows can have wrong start positions #7169 ### VTTablet @@ -129,7 +135,6 @@ Set statement support has been added in Vitess. There are [some system variables * VTTablet: Adds better errors when there are timeouts in resource pools #7002 * VTTablet: Return to re-using server IDs for binlog connections #6941 * VTTablet: Correctly initialize the TabletType stats #6989 -* Backup: Use provided xtrabackup_root_path to find xbstream #7359 * Backup: Use pargzip instead of pgzip for compression. #7037 * Backup: Add s3 server-side encryption and decryption with customer provided key #7088 @@ -155,7 +160,12 @@ Automatically terminate migrations run by a failed tablet * Online DDL: Adding @@session_uuid to vtgate; used as 'context' #7263 * Online DDL: ignore errors if extracted gh-ost binary is identical to installed binary #6928 * Online DDL: Table lifecycle: skip time hint for unspecified states #7151 - +* Online DDL: Migration uses low priority throttling #6830 +* Online DDL: Fix parsing of online-ddl command line options #6900 +* OnlineDDL bugfix: make sure schema is applied on tablet #6910 +* OnlineDDL: request_context/migration_context #7082 +* OnlineDDL: Fix missed rename in onlineddl_test #7148 +* OnlineDDL: Online DDL endtoend tests to support MacOS #7168 ### VTadmin @@ -164,21 +174,8 @@ Automatically terminate migrations run by a failed tablet * VTadmin: Add cluster protos to discovery and vtsql package constructors #7224 * VTadmin: Add static file service discovery implementation #7229 * VTadmin: Query vtadmin-api from vtadmin-web with fetch + react-query #7239 -* VTadmin: Add vtctld proxy to vtadmin API, add GetKeyspaces endpoint #7266 -* VTadmin: [vtctld] Expose vtctld gRPC port in local Docker example + update VTAdmin README #7306 -* VTadmin: Add CSS variables + fonts to VTAdmin #7309 -* VTadmin: Add React Router + a skeleton /debug page to VTAdmin #7310 -* VTadmin: Add NavRail component #7316 -* VTadmin: Add Button + Icon components #7350 +* VTadmin: Move allow_alias option in MySqlFlag enum to precede the aliased IDs #7166 * [vtctld]: vtctldclient generator #7238 -* [vtctld] Migrate cell getters #7302 -* [vtctld] Migrate tablet getters #7311 -* [vtctld] Migrate GetSchema #7346 -* [vtctld] vtctldclient command pkg #7321 -* [vtctld] Add GetSrvVSchema command #7334 -* [vtctld] Migrate ListBackups as GetBackups in new vtctld server #7352 - Merged -* [vtctld] Migrate GetVSchema to VtctldServer #7360 ### Other @@ -187,12 +184,13 @@ Automatically terminate migrations run by a failed tablet * Fix incorrect comments #7257 * Fix comment for IDPool #7212 * IsInternalOperationTableName: see if a table is used internally by vitess #7104 +* Add timeout for mysqld_shutdown #6849 +* Should receive healthcheck updates from all tablets in cells_to_watch #6852 +* Workflow listall with no workflows was missing newline #6853 +* Allow incomplete SNAPSHOT keyspaces #6863 ## Examples / Tutorials -* Update demo #7205 -* Delete select_commerce_data.sql #7245 -* Docker/vttestserver: Add MYSQL_BIND_HOST env #7293 * Examples/operator: fix tags and add vtorc example #7358 * local docker: copy examples/common into /vt/common to match MoveTables user guide #7252 * Update docker-compose examples to take advantage of improvements in Vitess #7009 @@ -202,7 +200,18 @@ Automatically terminate migrations run by a failed tablet * Vitess Slack Guidelines v1.0 #6961 * Do vschema_customer_sharded.json before create_customer_sharded.sql #7210 * Added readme for the demo example #7226 -* Pull Request template: link to contribution guide #7314 +* Adding @shlomi-noach to CODEOWNERS #6855 +* Add Rohit Nayak to maintainers #6903 +* 7.0.3 Release Notes #6902 +* 8_0_0 Release Notes #6958 +* Update maintainers of Vitess #7093 +* Updating Email Address #7095 +* Update morgo changes #7105 +* Move PR template to .github directory #7126 +* Fix trivial typo #7179 +* Add @ajm188 + @doeg to CODEOWNERS for vtctld service files #7202 +* Add @ajm188 + @doeg as vtadmin codeowners #7223:w + ## Build Environment Changes @@ -224,16 +233,23 @@ Automatically terminate migrations run by a failed tablet * Add unit test case to improve test coverage for go/sqltypes/result.go #7227 * Update Golang to 1.15 #7204 * Add linter configuration #7247 -* Tracking failed check runs #7026 -* Github Actions CI Builds: convert matrix strategy for unit and cluster tests to individual tests #7258 -* Add Update.AddWhere to mirror Select.AddWhere #7277 -* Descriptive names for CI checks #7289 -* Testing upgrade path from / downgrade path to v8.0.0 #7294 -* Add mysqlctl to docker images #7326 +* Modify targets to restore behavior of make install #6842 +* Download zookeeper 3.4.14 from archive site #6865 +* Bump junit from 4.12 to 4.13.1 in /java #6870 +* Fix ListBackups for gcp and az to work with root directory #6873 +* Pulling bootstrap resources from vitess-resources #6875 +* [Java] Bump SNAPSHOT version to 9.0 after Vitess release 8.0 #6907 +* Change dependencies for lite builds #6933 +* Truncate logged query in dbconn.go. #6959 +* [GO] go mod tidy #7137 +* goimport proto files correctly #7264 +* Cherry pick version of #7233 for release-9.0 #7265 +* Update Java version to 9.0 #7369 ## Functionality Neutral Changes * Healthcheck: add unit test for multi-cell replica configurations #6978 +* Healthcheck: Correct Health Check for Non-Serving Types #6908 * Adds timeout to checking for tablets. #7106 * Remove deprecated vtctl commands, flags and vttablet rpcs #7115 * Fixes comment to mention the existence of reference tables. #7122 @@ -242,4 +258,26 @@ Automatically terminate migrations run by a failed tablet * action_repository: no need for http.Request #7124 * Testing version upgrade/downgrade path from/to 8.0 #7323 * Use `context` from Go's standard library #7235 +* Update `operator.yaml` backup engine description #6832 +* Docker - upgrade to Debian Buster #6833 +* Updating azblob to remove directory after removing backup #6836 +* Fixing some flaky tests #6874 +* Flaky test: attempt to fix TestConnection in go/test/endtoend/messaging #6879 +* Stabilize test #6882 +* Tablet streaming health fix: never silently skip health state changes #6885 +* Add owners to /go/mysql #6886 +* Fixes a bug in Load From statement #6911 +* Query consolidator: fix to ignore leading margin comments #6917 +* Updates to Contacts section as Reporting #7023 +* Create pull_request_template #7027 +* Fixed pull request template path #7062 + +## Backport +* Backport: [vtctld] Fix accidentally-broken legacy vtctl output format #7292 +* Backport #7276: Vreplication V2 Workflows: rename Abort to Cancel #7339 +* Backport #7297: VStreamer Events: remove preceding zeroes from decimals in Row Events +* Backport #7255: VReplication DryRun: Report current dry run results for v2 commands #7345 +* Backport #7275: VReplication: Miscellaneous improvements #7349 +* Backport 7342: Workflow Show: use timeUpdated to calculate vreplication lag #7354 +* Backport 7361: vtctl: Add missing err checks for VReplication v2 #7363 From 248909bfdd6a204fec4a0d2ec4158b390ded5aad Mon Sep 17 00:00:00 2001 From: Rafael Chacon Date: Wed, 9 Jun 2021 10:59:08 -0700 Subject: [PATCH 214/310] Avoid races Signed-off-by: Rafael Chacon --- go/vt/key/key.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/go/vt/key/key.go b/go/vt/key/key.go index 57af2e570e9..523d154042b 100644 --- a/go/vt/key/key.go +++ b/go/vt/key/key.go @@ -205,10 +205,14 @@ func KeyRangeEqual(left, right *topodatapb.KeyRange) bool { // Any number with the highest bit set will be >= 0x8000000000000000, and will therefore // belong to shard 80-. // This means that from a keyrange perspective -80 == 00-80 == 0000-8000 == 000000-800000 -// If we don't do this padding, we could run into issues when transitioning from keyranges +// If we don't add this padding, we could run into issues when transitioning from keyranges // that use 2 bytes to 4 bytes. func addPadding(kr []byte) []byte { - paddedKr := kr + paddedKr := make([]byte, 8) + + for i := 0; i < len(kr); i++ { + paddedKr = append(paddedKr, kr[i]) + } for i := len(kr); i < 8; i++ { paddedKr = append(paddedKr, 0) From c3fb79c44f6d45413075c1629ae94a7272a7f857 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Wed, 9 Jun 2021 15:12:25 -0400 Subject: [PATCH 215/310] Correct copyright year and comment typo Signed-off-by: Andrew Mason --- go/cmd/vtctldclient/plugin_grpcvtctlclient.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/cmd/vtctldclient/plugin_grpcvtctlclient.go b/go/cmd/vtctldclient/plugin_grpcvtctlclient.go index e08d657f428..48c631a8baa 100644 --- a/go/cmd/vtctldclient/plugin_grpcvtctlclient.go +++ b/go/cmd/vtctldclient/plugin_grpcvtctlclient.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. @@ -16,7 +16,7 @@ limitations under the License. package main -// Imports and register the gRPC vtctl client. +// Imports and registers the gRPC vtctl client. import ( _ "vitess.io/vitess/go/vt/vtctl/grpcvtctlclient" From cfed06207fce627e331bf45b4e6c9c3d9479c181 Mon Sep 17 00:00:00 2001 From: Florent Poinsard Date: Thu, 10 Jun 2021 07:56:41 +0200 Subject: [PATCH 216/310] Fixing TestVSchemaTrackerInitAndUpdate E2E test Signed-off-by: Florent Poinsard --- go/test/endtoend/vtgate/misc_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index d863af2a47a..ebd5eb7b141 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -669,13 +669,13 @@ func TestVSchemaTrackerInitAndUpdate(t *testing.T) { require.NoError(t, err) defer conn.Close() - assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("vstream_test")]]`) + assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("vstream_test")]]`) // Init _ = exec(t, conn, "create table test_sc (id bigint primary key)") assertMatchesWithTimeout(t, conn, "SHOW VSCHEMA TABLES", - `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("test_sc")] [VARCHAR("vstream_test")]]`, + `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("test_sc")] [VARCHAR("vstream_test")]]`, 100*time.Millisecond, 3*time.Second, "test_sc not in vschema tables") @@ -684,7 +684,7 @@ func TestVSchemaTrackerInitAndUpdate(t *testing.T) { _ = exec(t, conn, "create table test_sc1 (id bigint primary key)") assertMatchesWithTimeout(t, conn, "SHOW VSCHEMA TABLES", - `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("test_sc")] [VARCHAR("test_sc1")] [VARCHAR("vstream_test")]]`, + `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("test_sc")] [VARCHAR("test_sc1")] [VARCHAR("vstream_test")]]`, 100*time.Millisecond, 3*time.Second, "test_sc1 not in vschema tables") From 4213c523228958611d4d1edbf6b0f6e8d528782a Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 10 Jun 2021 13:39:16 +0530 Subject: [PATCH 217/310] fixed error messages and reorganized tests wrt schema tracker Signed-off-by: GuptaManan100 --- go/mysql/sql_error.go | 1 + go/test/endtoend/vtgate/misc_test.go | 84 ----- .../schematracker/schematracker_test.go | 107 ------- .../schematracker/sharded/st_sharded_test.go | 298 ++++++++++++++++++ .../unsharded/st_unsharded_test.go | 159 ++++++++++ go/vt/vterrors/constants.go | 6 + go/vt/vterrors/state.go | 1 + go/vt/vtgate/engine/insert.go | 2 +- go/vt/vtgate/planbuilder/dml.go | 2 +- 9 files changed, 467 insertions(+), 193 deletions(-) delete mode 100644 go/test/endtoend/vtgate/schematracker/schematracker_test.go create mode 100644 go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go create mode 100644 go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go diff --git a/go/mysql/sql_error.go b/go/mysql/sql_error.go index b2d12af0c49..369e7a6f0eb 100644 --- a/go/mysql/sql_error.go +++ b/go/mysql/sql_error.go @@ -190,6 +190,7 @@ var stateToMysqlCode = map[vterrors.State]struct { vterrors.WrongValueForVar: {num: ERWrongValueForVar, state: SSClientError}, vterrors.ServerNotAvailable: {num: ERServerIsntAvailable, state: SSNetError}, vterrors.CantDoThisInTransaction: {num: ERCantDoThisDuringAnTransaction, state: SSCantDoThisDuringAnTransaction}, + vterrors.RequiresPrimaryKey: {num: ERRequiresPrimaryKey, state: SSClientError}, vterrors.NoSuchSession: {num: ERUnknownComError, state: SSNetError}, } diff --git a/go/test/endtoend/vtgate/misc_test.go b/go/test/endtoend/vtgate/misc_test.go index ebd5eb7b141..d4c3d5a7949 100644 --- a/go/test/endtoend/vtgate/misc_test.go +++ b/go/test/endtoend/vtgate/misc_test.go @@ -20,7 +20,6 @@ import ( "context" "fmt" "testing" - "time" "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" @@ -651,73 +650,6 @@ func TestQueryAndSubQWithLimit(t *testing.T) { assert.Equal(t, 10, len(result.Rows)) } -func TestSchemaTracker(t *testing.T) { - defer cluster.PanicHandler(t) - ctx := context.Background() - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - // this query only works if we know which table the testId belongs to. The vschema does not contain - // this info, so we are testing that the schema tracker has added column info to the vschema - _, err = conn.ExecuteFetch(`select testId from t8 join t2`, 1000, true) - require.NoError(t, err) -} - -func TestVSchemaTrackerInitAndUpdate(t *testing.T) { - ctx := context.Background() - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - - assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("vstream_test")]]`) - - // Init - _ = exec(t, conn, "create table test_sc (id bigint primary key)") - assertMatchesWithTimeout(t, conn, - "SHOW VSCHEMA TABLES", - `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("test_sc")] [VARCHAR("vstream_test")]]`, - 100*time.Millisecond, - 3*time.Second, - "test_sc not in vschema tables") - - // Tables Update via health check. - _ = exec(t, conn, "create table test_sc1 (id bigint primary key)") - assertMatchesWithTimeout(t, conn, - "SHOW VSCHEMA TABLES", - `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("test_sc")] [VARCHAR("test_sc1")] [VARCHAR("vstream_test")]]`, - 100*time.Millisecond, - 3*time.Second, - "test_sc1 not in vschema tables") -} - -func TestVSchemaTrackedForNewTables(t *testing.T) { - ctx := context.Background() - conn, err := mysql.Connect(ctx, &vtParams) - require.NoError(t, err) - defer conn.Close() - - // create a new table which is not part of the VSchema - exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) - - // wait for vttablet's schema reload interval to pass - time.Sleep(5 * time.Second) - - // check if the new table is part of the schema - assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("aggr_test")] [VARCHAR("dual")] [VARCHAR("new_table_tracked")] [VARCHAR("t1")] [VARCHAR("t1_id2_idx")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t3")] [VARCHAR("t3_id7_idx")] [VARCHAR("t4")] [VARCHAR("t4_id2_idx")] [VARCHAR("t5_null_vindex")] [VARCHAR("t6")] [VARCHAR("t6_id2_idx")] [VARCHAR("t7_fk")] [VARCHAR("t7_xxhash")] [VARCHAR("t7_xxhash_idx")] [VARCHAR("t8")] [VARCHAR("t9")] [VARCHAR("vstream_test")]]`) - - // DML on new table - assertMatches(t, conn, "select id from new_table_tracked", `[]`) // select - exec(t, conn, `insert into new_table_tracked(id) values(0),(1)`) // insert initial data - assertMatches(t, conn, "select id from new_table_tracked", `[[INT64(0)] [INT64(1)]]`) // select - assertMatches(t, conn, "select id from new_table_tracked where id = 1 ", `[[INT64(1)]]`) // select with WHERE clause - - exec(t, conn, `update new_table_tracked set name = "newName1" where id = 1`) // update - assertMatches(t, conn, "select name from new_table_tracked where id = 1 ", `[[VARCHAR("newName1")]]`) - - exec(t, conn, "delete from new_table_tracked where id = 0") // delete - assertMatches(t, conn, "select id from new_table_tracked", `[[INT64(1)]]`) -} - func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) @@ -728,22 +660,6 @@ func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { } } -func assertMatchesWithTimeout(t *testing.T, conn *mysql.Conn, query, expected string, r time.Duration, d time.Duration, failureMsg string) { - t.Helper() - timeout := time.After(d) - diff := "actual and expectation does not match" - for len(diff) > 0 { - select { - case <-timeout: - require.Fail(t, failureMsg, diff) - case <-time.After(r): - qr := exec(t, conn, `SHOW VSCHEMA TABLES`) - diff = cmp.Diff(expected, - fmt.Sprintf("%v", qr.Rows)) - } - - } -} func assertMatchesNoOrder(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) diff --git a/go/test/endtoend/vtgate/schematracker/schematracker_test.go b/go/test/endtoend/vtgate/schematracker/schematracker_test.go deleted file mode 100644 index dbc9dab3dee..00000000000 --- a/go/test/endtoend/vtgate/schematracker/schematracker_test.go +++ /dev/null @@ -1,107 +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 schematracker - -import ( - "context" - "fmt" - "testing" - "time" - - "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 ( - hostname = "localhost" - keyspaceName = "ks" - cell = "zone1" - sqlSchema = ` - create table main ( - id bigint, - val varchar(128), - primary key(id) - ) Engine=InnoDB; -` -) - -func TestNewUnshardedTable(t *testing.T) { - defer cluster.PanicHandler(t) - var err error - - // initialize our cluster - clusterInstance := cluster.NewCluster(cell, hostname) - defer clusterInstance.Teardown() - - // Start topo server - err = clusterInstance.StartTopo() - require.NoError(t, err) - - // create keyspace - keyspace := &cluster.Keyspace{ - Name: keyspaceName, - SchemaSQL: sqlSchema, - } - - // enabling and setting the schema reload time to one second - clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "0.1"} - err = clusterInstance.StartUnshardedKeyspace(*keyspace, 1, false) - require.NoError(t, err) - - // Start vtgate with the schema_change_signal flag - clusterInstance.VtGateExtraArgs = []string{"-schema_change_signal"} - err = clusterInstance.StartVtgate() - require.NoError(t, err) - - // create a sql connection - ctx := context.Background() - conn, err := mysql.Connect(ctx, &mysql.ConnParams{ - Host: clusterInstance.Hostname, - Port: clusterInstance.VtgateMySQLPort, - }) - require.NoError(t, err) - defer conn.Close() - - // ensuring our initial table "main" is in the schema - qr := exec(t, conn, "SHOW VSCHEMA TABLES") - got := fmt.Sprintf("%v", qr.Rows) - want := `[[VARCHAR("dual")] [VARCHAR("main")]]` - require.Equal(t, want, got) - - // create a new table which is not part of the VSchema - exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) - - // waiting for the vttablet's schema_reload interval to kick in - time.Sleep(5 * time.Second) - - // ensuring our new table is in the schema - qr = exec(t, conn, "SHOW VSCHEMA TABLES") - got = fmt.Sprintf("%v", qr.Rows) - want = `[[VARCHAR("dual")] [VARCHAR("main")] [VARCHAR("new_table_tracked")]]` - assert.Equal(t, want, got) -} - -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, "for query: "+query) - return qr -} diff --git a/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go new file mode 100644 index 00000000000..a41616bb663 --- /dev/null +++ b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go @@ -0,0 +1,298 @@ +/* +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 sharded + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + + "vitess.io/vitess/go/test/utils" + + "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 + vtParams mysql.ConnParams + KeyspaceName = "ks" + Cell = "test" + SchemaSQL = ` +create table t2( + id3 bigint, + id4 bigint, + primary key(id3) +) Engine=InnoDB; + +create table t2_id4_idx( + id bigint not null auto_increment, + id4 bigint, + id3 bigint, + primary key(id), + key idx_id4(id4) +) Engine=InnoDB; + +create table t8( + id8 bigint, + testId bigint, + primary key(id8) +) Engine=InnoDB; +` + + VSchema = ` +{ + "sharded": true, + "vindexes": { + "unicode_loose_xxhash" : { + "type": "unicode_loose_xxhash" + }, + "unicode_loose_md5" : { + "type": "unicode_loose_md5" + }, + "hash": { + "type": "hash" + }, + "xxhash": { + "type": "xxhash" + }, + "t2_id4_idx": { + "type": "lookup_hash", + "params": { + "table": "t2_id4_idx", + "from": "id4", + "to": "id3", + "autocommit": "true" + }, + "owner": "t2" + } + }, + "tables": { + "t2": { + "column_vindexes": [ + { + "column": "id3", + "name": "hash" + }, + { + "column": "id4", + "name": "t2_id4_idx" + } + ] + }, + "t2_id4_idx": { + "column_vindexes": [ + { + "column": "id4", + "name": "hash" + } + ] + }, + "t8": { + "column_vindexes": [ + { + "column": "id8", + "name": "hash" + } + ] + } + } +}` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitCode := func() int { + clusterInstance = cluster.NewCluster(Cell, "localhost") + defer clusterInstance.Teardown() + + // Start topo server + err := clusterInstance.StartTopo() + if err != nil { + return 1 + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: KeyspaceName, + SchemaSQL: SchemaSQL, + VSchema: VSchema, + } + clusterInstance.VtGateExtraArgs = []string{"-schema_change_signal", "-vschema_ddl_authorized_users", "%"} + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "0.1"} + err = clusterInstance.StartKeyspace(*keyspace, []string{"-80", "80-"}, 1, true) + if err != nil { + return 1 + } + + // Start vtgate + err = clusterInstance.StartVtgate() + if err != nil { + return 1 + } + + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + return m.Run() + }() + os.Exit(exitCode) +} + +func TestSchemaTracker(t *testing.T) { + defer cluster.PanicHandler(t) + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + // this query only works if we know which table the testId belongs to. The vschema does not contain + // this info, so we are testing that the schema tracker has added column info to the vschema + _, err = conn.ExecuteFetch(`select testId from t8 join t2`, 1000, true) + require.NoError(t, err) +} + +func TestVSchemaTrackerInitAndUpdate(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + assertMatches(t, conn, "SHOW VSCHEMA TABLES", `[[VARCHAR("dual")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t8")]]`) + + // Init + _ = exec(t, conn, "create table test_sc (id bigint primary key)") + assertMatchesWithTimeout(t, conn, + "SHOW VSCHEMA TABLES", + `[[VARCHAR("dual")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t8")] [VARCHAR("test_sc")]]`, + 100*time.Millisecond, + 3*time.Second, + "test_sc not in vschema tables") + + // Tables Update via health check. + _ = exec(t, conn, "create table test_sc1 (id bigint primary key)") + assertMatchesWithTimeout(t, conn, + "SHOW VSCHEMA TABLES", + `[[VARCHAR("dual")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t8")] [VARCHAR("test_sc")] [VARCHAR("test_sc1")]]`, + 100*time.Millisecond, + 3*time.Second, + "test_sc1 not in vschema tables") + + _ = exec(t, conn, "drop table test_sc, test_sc1") + assertMatchesWithTimeout(t, conn, + "SHOW VSCHEMA TABLES", + `[[VARCHAR("dual")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t8")]]`, + 100*time.Millisecond, + 3*time.Second, + "test_sc and test_sc_1 should not be in vschema tables") + +} + +func TestVSchemaTrackedForNewTables(t *testing.T) { + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + // create a new table which is not part of the VSchema + exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) + + // wait for vttablet's schema reload interval to pass + assertMatchesWithTimeout(t, conn, + "SHOW VSCHEMA TABLES", + `[[VARCHAR("dual")] [VARCHAR("new_table_tracked")] [VARCHAR("t2")] [VARCHAR("t2_id4_idx")] [VARCHAR("t8")]]`, + 100*time.Millisecond, + 3*time.Second, + "test_sc not in vschema tables") + + assertMatches(t, conn, "select id from new_table_tracked", `[]`) // select + assertMatches(t, conn, "select id from new_table_tracked where id = 5", `[]`) // select + // DML on new table + // insert initial data ,update and delete will fail since we have not added a primary vindex + errorMessage := "table 'new_table_tracked' does not have a primary vindex (errno 1173) (sqlstate 42000)" + assertError(t, conn, `insert into new_table_tracked(id) values(0),(1)`, errorMessage) + assertError(t, conn, `update new_table_tracked set name = "newName1"`, errorMessage) + assertError(t, conn, "delete from new_table_tracked", errorMessage) + + exec(t, conn, `select name from new_table_tracked join t8`) + + // add a primary vindex for the table + exec(t, conn, "alter vschema on ks.new_table_tracked add vindex hash(id) using hash") + time.Sleep(1 * time.Second) + exec(t, conn, `insert into new_table_tracked(id) values(0),(1)`) + exec(t, conn, `insert into t8(id8) values(2)`) + defer exec(t, conn, `delete from t8`) + assertMatchesNoOrder(t, conn, `select id from new_table_tracked join t8`, `[[INT64(0)] [INT64(1)]]`) +} + +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) + } +} + +func assertMatchesWithTimeout(t *testing.T, conn *mysql.Conn, query, expected string, r time.Duration, d time.Duration, failureMsg string) { + t.Helper() + timeout := time.After(d) + diff := "actual and expectation does not match" + for len(diff) > 0 { + select { + case <-timeout: + require.Fail(t, failureMsg, diff) + case <-time.After(r): + qr := exec(t, conn, query) + diff = cmp.Diff(expected, + fmt.Sprintf("%v", qr.Rows)) + } + + } +} +func assertMatchesNoOrder(t *testing.T, conn *mysql.Conn, query, expected string) { + t.Helper() + qr := exec(t, conn, query) + actual := fmt.Sprintf("%v", qr.Rows) + assert.Equal(t, utils.SortString(expected), utils.SortString(actual), "for query: [%s] expected \n%s \nbut actual \n%s", query, expected, actual) +} + +func assertError(t *testing.T, conn *mysql.Conn, query, errorMessage string) { + t.Helper() + _, err := conn.ExecuteFetch(query, 1000, true) + require.Error(t, err) + assert.Contains(t, err.Error(), errorMessage) +} + +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, "for query: "+query) + return qr +} diff --git a/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go b/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go new file mode 100644 index 00000000000..a479d85959b --- /dev/null +++ b/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go @@ -0,0 +1,159 @@ +/* +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 unsharded + +import ( + "context" + "flag" + "fmt" + "os" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "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 + vtParams mysql.ConnParams + keyspaceName = "ks" + cell = "zone1" + sqlSchema = ` + create table main ( + id bigint, + val varchar(128), + primary key(id) + ) Engine=InnoDB; +` +) + +func TestMain(m *testing.M) { + defer cluster.PanicHandler(nil) + flag.Parse() + + exitCode := func() int { + clusterInstance = cluster.NewCluster(cell, "localhost") + defer clusterInstance.Teardown() + + // Start topo server + err := clusterInstance.StartTopo() + if err != nil { + return 1 + } + + // Start keyspace + keyspace := &cluster.Keyspace{ + Name: keyspaceName, + SchemaSQL: sqlSchema, + } + clusterInstance.VtTabletExtraArgs = []string{"-queryserver-config-schema-change-signal", "-queryserver-config-schema-change-signal-interval", "0.1"} + err = clusterInstance.StartUnshardedKeyspace(*keyspace, 0, false) + if err != nil { + return 1 + } + + // Start vtgate + clusterInstance.VtGateExtraArgs = []string{"-schema_change_signal", "-vschema_ddl_authorized_users", "%"} + err = clusterInstance.StartVtgate() + if err != nil { + return 1 + } + + vtParams = mysql.ConnParams{ + Host: clusterInstance.Hostname, + Port: clusterInstance.VtgateMySQLPort, + } + return m.Run() + }() + os.Exit(exitCode) +} + +func TestNewUnshardedTable(t *testing.T) { + defer cluster.PanicHandler(t) + + // create a sql connection + ctx := context.Background() + conn, err := mysql.Connect(ctx, &vtParams) + require.NoError(t, err) + defer conn.Close() + + // ensuring our initial table "main" is in the schema + qr := exec(t, conn, "SHOW VSCHEMA TABLES") + got := fmt.Sprintf("%v", qr.Rows) + want := `[[VARCHAR("dual")] [VARCHAR("main")]]` + require.Equal(t, want, got) + + // create a new table which is not part of the VSchema + exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) + defer exec(t, conn, `drop table new_table_tracked`) + + // waiting for the vttablet's schema_reload interval to kick in + assertMatchesWithTimeout(t, conn, + "SHOW VSCHEMA TABLES", + `[[VARCHAR("dual")] [VARCHAR("main")] [VARCHAR("new_table_tracked")]]`, + 100*time.Millisecond, + 3*time.Second, + "new_table_tracked not in vschema tables") + + assertMatches(t, conn, "select id from new_table_tracked", `[]`) // select + assertMatches(t, conn, "select id from new_table_tracked where id = 5", `[]`) // select + // DML on new table + // insert initial data ,update and delete for the new table + exec(t, conn, `insert into new_table_tracked(id) values(0),(1)`) + exec(t, conn, `update new_table_tracked set name = "newName1"`) + exec(t, conn, "delete from new_table_tracked where id = 0") + assertMatches(t, conn, `select * from new_table_tracked`, `[[INT64(1) VARCHAR("newName1")]]`) +} + +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) + } +} + +func assertMatchesWithTimeout(t *testing.T, conn *mysql.Conn, query, expected string, r time.Duration, d time.Duration, failureMsg string) { + t.Helper() + timeout := time.After(d) + diff := "actual and expectation does not match" + for len(diff) > 0 { + select { + case <-timeout: + require.Fail(t, failureMsg, diff) + case <-time.After(r): + qr := exec(t, conn, query) + diff = cmp.Diff(expected, + fmt.Sprintf("%v", qr.Rows)) + } + + } +} + +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, "for query: "+query) + return qr +} diff --git a/go/vt/vterrors/constants.go b/go/vt/vterrors/constants.go index d66a97464d7..2fcbfda13d5 100644 --- a/go/vt/vterrors/constants.go +++ b/go/vt/vterrors/constants.go @@ -32,3 +32,9 @@ const WrongTablet = "wrong tablet type" // RxWrongTablet regex for invalid tablet type error var RxWrongTablet = regexp.MustCompile("(wrong|invalid) tablet type") + +// Constants for error messages +const ( + // PrimaryVindexNotSet is the error message to be used when there is no primary vindex found on a table + PrimaryVindexNotSet = "table '%s' does not have a primary vindex" +) diff --git a/go/vt/vterrors/state.go b/go/vt/vterrors/state.go index 8b4e8b9b4aa..29575de8dd5 100644 --- a/go/vt/vterrors/state.go +++ b/go/vt/vterrors/state.go @@ -43,6 +43,7 @@ const ( InnodbReadOnly WrongNumberOfColumnsInSelect CantDoThisInTransaction + RequiresPrimaryKey // not found BadDb diff --git a/go/vt/vtgate/engine/insert.go b/go/vt/vtgate/engine/insert.go index 4774cad2a64..00188b9921c 100644 --- a/go/vt/vtgate/engine/insert.go +++ b/go/vt/vtgate/engine/insert.go @@ -395,7 +395,7 @@ func (ins *Insert) getInsertShardedRoute(vcursor VCursor, bindVars map[string]*q // results in an error. For 'ignore' type inserts, the keyspace // id is returned as nil, which is used later to drop the corresponding rows. if len(vindexRowsValues) == 0 || len(ins.Table.ColumnVindexes) == 0 { - return nil, nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] table without a primary vindex is not expectedd") + return nil, nil, vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.RequiresPrimaryKey, vterrors.PrimaryVindexNotSet, ins.Table.Name) } keyspaceIDs, err := ins.processPrimary(vcursor, vindexRowsValues[0], ins.Table.ColumnVindexes[0]) if err != nil { diff --git a/go/vt/vtgate/planbuilder/dml.go b/go/vt/vtgate/planbuilder/dml.go index 42530579faf..cbd16542737 100644 --- a/go/vt/vtgate/planbuilder/dml.go +++ b/go/vt/vtgate/planbuilder/dml.go @@ -56,7 +56,7 @@ func getDMLRouting(where *sqlparser.Where, table *vindexes.Table) (engine.DMLOpc } } if ksidVindex == nil { - return engine.Scatter, nil, "", nil, nil, vterrors.New(vtrpcpb.Code_INTERNAL, "table without a primary vindex is not expected") + return engine.Scatter, nil, "", nil, nil, vterrors.NewErrorf(vtrpcpb.Code_FAILED_PRECONDITION, vterrors.RequiresPrimaryKey, vterrors.PrimaryVindexNotSet, table.Name) } return engine.Scatter, ksidVindex, ksidCol, nil, nil, nil } From f7962766e159f41a19b790829d382a3089285c26 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 10 Jun 2021 11:10:07 +0300 Subject: [PATCH 218/310] experiment: support online ddl convert from latin1 to utf8 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/constants.go | 9 ++++ .../vrepl_suite/onlineddl_vrepl_suite_test.go | 2 +- go/vt/vttablet/onlineddl/vrepl.go | 34 +++++++++--- go/vt/vttablet/onlineddl/vrepl/types.go | 3 ++ .../vreplication/table_plan_builder.go | 53 +++++++++++++++++++ .../tabletmanager/vreplication/vcopier.go | 2 + .../tabletserver/vstreamer/planbuilder.go | 19 ++++++- .../tabletserver/vstreamer/rowstreamer.go | 10 +++- 8 files changed, 123 insertions(+), 9 deletions(-) diff --git a/go/mysql/constants.go b/go/mysql/constants.go index 68c94d9bff3..b2d4c86db1d 100644 --- a/go/mysql/constants.go +++ b/go/mysql/constants.go @@ -626,6 +626,15 @@ var CharacterSetMap = map[string]uint8{ "eucjpms": 97, } +// ReverseCharacterSetMap maps a charset integer code to charset name +var ReverseCharacterSetMap = map[uint8]string{} + +func init() { + for c, i := range CharacterSetMap { + ReverseCharacterSetMap[i] = c + } +} + // IsNum returns true if a MySQL type is a numeric value. // It is the same as IS_NUM defined in mysql.h. func IsNum(typ uint8) bool { diff --git a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go index d96cfcfff22..68f71c8d683 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go @@ -60,7 +60,7 @@ var ( ) const ( - testDataPath = "testdata" + testDataPath = "tmptestdata" defaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" ) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index bd4b976abcb..54aee9a9909 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -215,6 +215,9 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect if strings.Contains(columnType, "float") { column.Type = vrepl.FloatColumnType } + if strings.Contains(columnType, "int") { + column.Type = vrepl.IntegerColumnType + } if strings.HasPrefix(columnType, "enum") { column.Type = vrepl.EnumColumnType column.EnumValues = vrepl.ParseEnumValues(columnType) @@ -224,11 +227,15 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { - if !strings.HasPrefix(charset, "utf8") { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) - } + // if !strings.HasPrefix(charset, "utf8") { + // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) + // } column.Charset = charset } + if collation := row.AsString("COLLATION_NAME", ""); collation != "" { + column.Type = vrepl.StringColumnType + column.Collation = collation + } } } return nil @@ -386,9 +393,24 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } switch col.Type { case vrepl.JSONColumnType: - sb.WriteString("convert(") - sb.WriteString(escapeName(name)) - sb.WriteString(" using utf8mb4)") + sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) + case vrepl.StringColumnType: + targetCol := v.targetSharedColumns.GetColumn(targetName) + if targetCol == nil { + return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) + } + if col.Collation != targetCol.Collation { + fmt.Printf("============ collcation change: %s => %s\n", col.Collation, targetCol.Collation) + if strings.HasPrefix(targetCol.Charset, "utf8") { + // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) + sb.WriteString(fmt.Sprintf("convert(convert(convert(%s USING %s) USING binary) USING %s)", escapeName(name), col.Charset, targetCol.Charset)) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + } else { + sb.WriteString(fmt.Sprintf("convert(%s, char character set %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + } + } else { + sb.WriteString(escapeName(name)) + } default: sb.WriteString(escapeName(name)) } diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index f4ff965a381..665906434cd 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -41,6 +41,8 @@ const ( JSONColumnType FloatColumnType BinaryColumnType + StringColumnType + IntegerColumnType ) // Column represents a table column @@ -48,6 +50,7 @@ type Column struct { Name string IsUnsigned bool Charset string + Collation string Type ColumnType EnumValues string EnumToTextConversion bool diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 66c57ca09d0..0b929989185 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -186,6 +186,7 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKeyInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. + fmt.Printf("============ filter: %v\n", filter) switch { case filter == "": buf := sqlparser.NewTrackedBuffer(nil) @@ -237,6 +238,9 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey stats: stats, } + for _, s := range sel.SelectExprs { + fmt.Printf("============ SelectExpr: %v\n", sqlparser.String(s)) + } if err := tpb.analyzeExprs(sel.SelectExprs); err != nil { return nil, err } @@ -268,7 +272,9 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey }, }) } + fmt.Printf("============ sendSelect.SelectExprs [3]: %v\n", sqlparser.String(tpb.sendSelect.SelectExprs)) sendRule.Filter = sqlparser.String(tpb.sendSelect) + fmt.Printf("============ sendRule.Filter: %v\n", sendRule.Filter) tablePlan := tpb.generate() tablePlan.SendRule = sendRule @@ -338,6 +344,7 @@ func analyzeSelectFrom(query string) (sel *sqlparser.Select, from string, err er func (tpb *tablePlanBuilder) analyzeExprs(selExprs sqlparser.SelectExprs) error { for _, selExpr := range selExprs { cexpr, err := tpb.analyzeExpr(selExpr) + fmt.Printf("============ selExpr: %v, cexpr.expr: %v\n", sqlparser.String(selExpr), sqlparser.String(cexpr.expr)) if err != nil { return err } @@ -364,6 +371,52 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr colName: as, references: make(map[string]bool), } + if expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok { + fmt.Printf("============ ConvertUsingExpr: %v\n", sqlparser.String(expr)) + selExpr := &sqlparser.ConvertUsingExpr{ + Type: "binary", + Expr: &sqlparser.ColName{Name: as}, + } + fmt.Printf("============ ConvertUsingExpr generated: %v\n", sqlparser.String(selExpr)) + cexpr.expr = expr + cexpr.operation = opExpr + tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) + return cexpr, nil + } + if expr, ok := aliased.Expr.(*sqlparser.ConvertExpr); ok { + // convertAsBinary := fmt.Sprintf("convert(%s, binary) as %s", sqlparser.String(as), sqlparser.String(as)) + // fmt.Printf("============ convertAsBinary: %v\n", convertAsBinary) + // convertAsBinaryExpr, err := sqlparser.Parse(convertAsBinary) + // fmt.Printf("============ convertAsBinaryExpr, err: %v, %v\n", convertAsBinaryExpr, err) + // if err != nil { + // return nil, err + // } + // expr, ok := convertAsBinaryExpr.(*sqlparser.ConvertExpr) + fmt.Printf("============ ConvertExpr: %v\n", sqlparser.String(expr)) + fmt.Printf("============ ConvertExpr.Type: %v\n", expr.Type) + fmt.Printf("============ ConvertExpr.Type.Type: %v\n", expr.Type.Type) + fmt.Printf("============ ConvertExpr.Type.Charset: %v\n", expr.Type.Charset) + fmt.Printf("============ ConvertExpr.Expr: %v\n", expr.Expr) + // expr.Type:= + // type ConvertType struct { + // Type string + // Length *Literal + // Scale *Literal + // Operator ConvertTypeOperator + // Charset string + // } + // expr.Type = &sqlparser.ConvertType{Type: "binary"} + // expr.Expr = as + selExpr := &sqlparser.ConvertExpr{ + Type: &sqlparser.ConvertType{Type: "binary"}, + Expr: &sqlparser.ColName{Name: as}, + } + fmt.Printf("============ ConvertExpr generated: %v\n", sqlparser.String(selExpr)) + cexpr.expr = expr + cexpr.operation = opExpr + tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) + return cexpr, nil + } if expr, ok := aliased.Expr.(*sqlparser.FuncExpr); ok { if expr.Distinct { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index a16cb1ba528..3cef585455e 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -200,6 +200,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma log.Infof("Copying table %s, lastpk: %v", tableName, copyState[tableName]) + fmt.Printf("============ buildReplicatorPlan( ivc.vr.source.Filter: %v\n", vc.vr.source.Filter) plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.pkInfoMap, nil, vc.vr.stats) if err != nil { return err @@ -222,6 +223,7 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma var updateCopyState *sqlparser.ParsedQuery var bv map[string]*querypb.BindVariable var sqlbuffer bytes2.Buffer + fmt.Printf("============ VStreamRows( initialPlan.SendRule.Filter: %v\n", initialPlan.SendRule.Filter) err = vc.vr.sourceVStreamer.VStreamRows(ctx, initialPlan.SendRule.Filter, lastpkpb, func(rows *binlogdatapb.VStreamRowsResponse) error { for { select { diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index eed93df1106..80dd00b8102 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -48,6 +48,8 @@ type Plan struct { // in the stream. ColExprs []ColExpr + convertToBinary map[string]bool + // Filters is the list of filters to be applied to the columns // of the table. Filters []Filter @@ -323,12 +325,14 @@ func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, erro } plan := &Plan{ - Table: ti, + Table: ti, + convertToBinary: map[string]bool{}, } if err := plan.analyzeWhere(vschema, sel.Where); err != nil { log.Errorf("%s", err.Error()) return nil, err } + fmt.Printf("========= buildTablePlan.analyzeExprs: sel.SelectExprs: %v, %v\n", len(sel.SelectExprs), sqlparser.String(sel.SelectExprs)) if err := plan.analyzeExprs(vschema, sel.SelectExprs); err != nil { log.Errorf("%s", err.Error()) return nil, err @@ -456,6 +460,7 @@ func (plan *Plan) analyzeExprs(vschema *localVSchema, selExprs sqlparser.SelectE } func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err error) { + fmt.Printf("========= Plan: analyzeExpr selExpr s: %v\n", sqlparser.String(selExpr)) aliased, ok := selExpr.(*sqlparser.AliasedExpr) if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(selExpr)) @@ -520,6 +525,18 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp ColNum: -1, FixedValue: sqltypes.NewInt64(num), }, nil + case *sqlparser.ConvertExpr, *sqlparser.ConvertUsingExpr: + colnum, err := findColumn(plan.Table, aliased.As) + fmt.Printf("========= findColumn2: %v, %v \n", colnum, err) + if err != nil { + return ColExpr{}, err + } + field := plan.Table.Fields[colnum] + plan.convertToBinary[field.Name] = true + return ColExpr{ + ColNum: colnum, + Field: field, + }, nil default: log.Infof("Unsupported expression: %v", inner) return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(aliased.Expr)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index b605bd8ad80..89c0c3190fa 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -113,6 +113,7 @@ func (rs *rowStreamer) Stream() error { func (rs *rowStreamer) buildPlan() error { // This pre-parsing is required to extract the table name // and create its metadata. + fmt.Printf("========= analyzeSelect: %v\n", rs.query) _, fromTable, err := analyzeSelect(rs.query) if err != nil { return err @@ -139,6 +140,7 @@ func (rs *rowStreamer) buildPlan() error { return err } rs.sendQuery, err = rs.buildSelect() + fmt.Printf("================= rs.sendQuery: %v\n", rs.sendQuery) if err != nil { return err } @@ -169,7 +171,13 @@ func (rs *rowStreamer) buildSelect() (string, error) { buf.Myprintf("select ") prefix := "" for _, col := range rs.plan.Table.Fields { - buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) + if rs.plan.convertToBinary[col.Name] { + // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) + buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) + } else { + buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) + } prefix = ", " } buf.Myprintf(" from %v", sqlparser.NewTableIdent(rs.plan.Table.Name)) From 6087205c7e4b72d44b694b58624b55df3e49b09e Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 10 Jun 2021 13:44:16 +0530 Subject: [PATCH 219/310] update names of tests Signed-off-by: GuptaManan100 --- go/test/endtoend/vtgate/main_test.go | 14 -------------- .../schematracker/sharded/st_sharded_test.go | 7 ++++--- .../schematracker/unsharded/st_unsharded_test.go | 11 ++++++++++- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/go/test/endtoend/vtgate/main_test.go b/go/test/endtoend/vtgate/main_test.go index dd17f6192fc..a8b8baea1d8 100644 --- a/go/test/endtoend/vtgate/main_test.go +++ b/go/test/endtoend/vtgate/main_test.go @@ -142,12 +142,6 @@ create table t8( testId bigint, primary key(id8) ) Engine=InnoDB; - -create table t9( - id9 bigint, - testId bigint, - primary key(id9) -) Engine=InnoDB; ` VSchema = ` @@ -390,14 +384,6 @@ create table t9( "name": "hash" } ] - }, - "t9": { - "column_vindexes": [ - { - "column": "id9", - "name": "hash" - } - ] } } }` diff --git a/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go index a41616bb663..08901571299 100644 --- a/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go +++ b/go/test/endtoend/vtgate/schematracker/sharded/st_sharded_test.go @@ -165,7 +165,7 @@ func TestMain(m *testing.M) { os.Exit(exitCode) } -func TestSchemaTracker(t *testing.T) { +func TestAmbiguousColumnJoin(t *testing.T) { defer cluster.PanicHandler(t) ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) @@ -177,7 +177,7 @@ func TestSchemaTracker(t *testing.T) { require.NoError(t, err) } -func TestVSchemaTrackerInitAndUpdate(t *testing.T) { +func TestInitAndUpdate(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -213,7 +213,7 @@ func TestVSchemaTrackerInitAndUpdate(t *testing.T) { } -func TestVSchemaTrackedForNewTables(t *testing.T) { +func TestDMLOnNewTable(t *testing.T) { ctx := context.Background() conn, err := mysql.Connect(ctx, &vtParams) require.NoError(t, err) @@ -276,6 +276,7 @@ func assertMatchesWithTimeout(t *testing.T, conn *mysql.Conn, query, expected st } } + func assertMatchesNoOrder(t *testing.T, conn *mysql.Conn, query, expected string) { t.Helper() qr := exec(t, conn, query) diff --git a/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go b/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go index a479d85959b..e4ced166703 100644 --- a/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go +++ b/go/test/endtoend/vtgate/schematracker/unsharded/st_unsharded_test.go @@ -104,7 +104,6 @@ func TestNewUnshardedTable(t *testing.T) { // create a new table which is not part of the VSchema exec(t, conn, `create table new_table_tracked(id bigint, name varchar(100), primary key(id)) Engine=InnoDB`) - defer exec(t, conn, `drop table new_table_tracked`) // waiting for the vttablet's schema_reload interval to kick in assertMatchesWithTimeout(t, conn, @@ -122,6 +121,16 @@ func TestNewUnshardedTable(t *testing.T) { exec(t, conn, `update new_table_tracked set name = "newName1"`) exec(t, conn, "delete from new_table_tracked where id = 0") assertMatches(t, conn, `select * from new_table_tracked`, `[[INT64(1) VARCHAR("newName1")]]`) + + exec(t, conn, `drop table new_table_tracked`) + + // waiting for the vttablet's schema_reload interval to kick in + assertMatchesWithTimeout(t, conn, + "SHOW VSCHEMA TABLES", + `[[VARCHAR("dual")] [VARCHAR("main")]]`, + 100*time.Millisecond, + 3*time.Second, + "new_table_tracked not in vschema tables") } func assertMatches(t *testing.T, conn *mysql.Conn, query, expected string) { From 61245df267a2242bbaca3b942e4c4ad8e39f2fe8 Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 10 Jun 2021 13:54:06 +0530 Subject: [PATCH 220/310] removed unnecessary channel close Signed-off-by: GuptaManan100 --- go/vt/vtgate/schema/tracker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/vt/vtgate/schema/tracker.go b/go/vt/vtgate/schema/tracker.go index f819bbcd368..eeb13992f1f 100644 --- a/go/vt/vtgate/schema/tracker.go +++ b/go/vt/vtgate/schema/tracker.go @@ -93,7 +93,7 @@ func (t *Tracker) Start() { ksUpdater := t.getKeyspaceUpdateController(th) ksUpdater.add(th) case <-ctx.Done(): - close(t.ch) + // closing of the channel happens outside the scope of the tracker. It is the responsibility of the one who created this tracker. return } } From 1013d7939eef921dd4c85ac07c59d6f35d40f92c Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Thu, 10 Jun 2021 12:36:54 +0300 Subject: [PATCH 221/310] temporary test data Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../__expect_failure | 1 + .../fail-alter-charset-non-utf8/alter | 1 + .../fail-alter-charset-non-utf8/create.sql | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure new file mode 100644 index 00000000000..925d0d81ded --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure @@ -0,0 +1 @@ +Vitess does not support charset diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter new file mode 100644 index 00000000000..b5ec82b1a8b --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter @@ -0,0 +1 @@ +MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql new file mode 100644 index 00000000000..9db84563248 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql @@ -0,0 +1,24 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + t1 varchar(128) charset latin1 collate latin1_swedish_ci, + t2 varchar(128) charset latin1 collate latin1_swedish_ci, + tutf8 varchar(128) charset utf8, + tutf8mb4 varchar(128) charset utf8mb4, + primary key(id) +) auto_increment=1; + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); + insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); + insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); +end ;; From 03c1a5b298ee9cbfc727f6cdb36278166473548b Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 10 Jun 2021 15:16:55 +0530 Subject: [PATCH 222/310] fixed test configuration Signed-off-by: GuptaManan100 --- test/config.json | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/test/config.json b/test/config.json index 088d815ea74..ea76ab1b113 100644 --- a/test/config.json +++ b/test/config.json @@ -606,9 +606,36 @@ "RetryMax": 0, "Tags": [] }, - "vtgate_schematracker": { + "vtgate_schematracker_loadkeyspace": { "File": "unused.go", - "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker"], + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/loadkeyspace"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_schematracker_restarttablet": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/restarttablet"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_schematracker_sharded": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/sharded"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_schematracker_unsharded": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schematracker/unsharded"], "Command": [], "Manual": false, "Shard": "17", From 15fd287bfb523d94ea30263c2397fcbc33b93c2e Mon Sep 17 00:00:00 2001 From: GuptaManan100 Date: Thu, 10 Jun 2021 15:20:35 +0530 Subject: [PATCH 223/310] logged error in teardown Signed-off-by: GuptaManan100 --- go/test/endtoend/docker/vttestserver.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/go/test/endtoend/docker/vttestserver.go b/go/test/endtoend/docker/vttestserver.go index 994c55b155d..e6bc93d4e6c 100644 --- a/go/test/endtoend/docker/vttestserver.go +++ b/go/test/endtoend/docker/vttestserver.go @@ -25,6 +25,8 @@ import ( "strconv" "strings" "time" + + "vitess.io/vitess/go/vt/log" ) const ( @@ -52,7 +54,10 @@ func newVttestserver(dockerImage string, keyspaces []string, numShards []int, my func (v *vttestserver) teardown() { cmd := exec.Command("docker", "rm", "--force", "vttestserver-end2end-test") - _ = cmd.Run() + err := cmd.Run() + if err != nil { + log.Errorf("docker teardown failed :- %s", err.Error()) + } } // startDockerImage starts the docker image for the vttestserver From 0026d1c499c709c671abdacf27fe4a65b1fcd8eb Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 10 Jun 2021 16:10:57 +0530 Subject: [PATCH 224/310] move tests out of loaded shard 17 Signed-off-by: Harshit Gangal --- .../cluster_endtoend_vtgate_buffer.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_concurrentdml.yml | 50 +++++++++++++++++++ ...cluster_endtoend_vtgate_readafterwrite.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_reservedconn.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_schema.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_sequence.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_setstatement.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_topo.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_transaction.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_unsharded.yml | 50 +++++++++++++++++++ .../cluster_endtoend_vtgate_vschema.yml | 50 +++++++++++++++++++ .../cluster_endtoend_xb_recovery.yml | 50 +++++++++++++++++++ test/ci_workflow_gen.go | 12 +++++ test/config.json | 28 +++++------ 14 files changed, 626 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/cluster_endtoend_vtgate_buffer.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_concurrentdml.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_readafterwrite.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_reservedconn.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_schema.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_sequence.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_setstatement.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_topo.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_transaction.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_unsharded.yml create mode 100644 .github/workflows/cluster_endtoend_vtgate_vschema.yml create mode 100644 .github/workflows/cluster_endtoend_xb_recovery.yml diff --git a/.github/workflows/cluster_endtoend_vtgate_buffer.yml b/.github/workflows/cluster_endtoend_vtgate_buffer.yml new file mode 100644 index 00000000000..93c30528bd2 --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_buffer.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_buffer) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_buffer) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_buffer diff --git a/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml new file mode 100644 index 00000000000..4045c90ad7a --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_concurrentdml.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_concurrentdml) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_concurrentdml) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_concurrentdml diff --git a/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml new file mode 100644 index 00000000000..04102581bcd --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_readafterwrite.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_readafterwrite) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_readafterwrite) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_readafterwrite diff --git a/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml new file mode 100644 index 00000000000..eaf68bd7dfc --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_reservedconn.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_reservedconn) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_reservedconn) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_reservedconn diff --git a/.github/workflows/cluster_endtoend_vtgate_schema.yml b/.github/workflows/cluster_endtoend_vtgate_schema.yml new file mode 100644 index 00000000000..0fdb3a3f0c9 --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_schema.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_schema) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_schema) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_schema diff --git a/.github/workflows/cluster_endtoend_vtgate_sequence.yml b/.github/workflows/cluster_endtoend_vtgate_sequence.yml new file mode 100644 index 00000000000..a8f4f550610 --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_sequence.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_sequence) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_sequence) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_sequence diff --git a/.github/workflows/cluster_endtoend_vtgate_setstatement.yml b/.github/workflows/cluster_endtoend_vtgate_setstatement.yml new file mode 100644 index 00000000000..2b168bdbbb0 --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_setstatement.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_setstatement) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_setstatement) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_setstatement diff --git a/.github/workflows/cluster_endtoend_vtgate_topo.yml b/.github/workflows/cluster_endtoend_vtgate_topo.yml new file mode 100644 index 00000000000..92b2c3407d0 --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_topo.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_topo) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_topo) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_topo diff --git a/.github/workflows/cluster_endtoend_vtgate_transaction.yml b/.github/workflows/cluster_endtoend_vtgate_transaction.yml new file mode 100644 index 00000000000..45d658266e6 --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_transaction.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_transaction) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_transaction) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_transaction diff --git a/.github/workflows/cluster_endtoend_vtgate_unsharded.yml b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml new file mode 100644 index 00000000000..18f69aae1dc --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_unsharded.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_unsharded) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_unsharded) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_unsharded diff --git a/.github/workflows/cluster_endtoend_vtgate_vschema.yml b/.github/workflows/cluster_endtoend_vtgate_vschema.yml new file mode 100644 index 00000000000..aa8c3ed1c7a --- /dev/null +++ b/.github/workflows/cluster_endtoend_vtgate_vschema.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (vtgate_vschema) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (vtgate_vschema) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_vschema diff --git a/.github/workflows/cluster_endtoend_xb_recovery.yml b/.github/workflows/cluster_endtoend_xb_recovery.yml new file mode 100644 index 00000000000..ec15f6b9b84 --- /dev/null +++ b/.github/workflows/cluster_endtoend_xb_recovery.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (xb_recovery) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (xb_recovery) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard xb_recovery diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index a1279a073b9..26d971b4eda 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -67,6 +67,18 @@ var ( "tabletmanager_throttler_custom_config", "tabletmanager_tablegc", "vtorc", + "vtgate_buffer", + "vtgate_concurrentdml", + "vtgate_schema", + "vtgate_sequence", + "vtgate_setstatement", + "vtgate_reservedconn", + "vtgate_transaction", + "vtgate_unsharded", + "vtgate_vschema", + "vtgate_readafterwrite", + "vtgate_topo", + "xb_recovery", } // TODO: currently some percona tools including xtrabackup are installed on all clusters, we can possibly optimize // this by only installing them in the required clusters diff --git a/test/config.json b/test/config.json index 1cae4d07ff7..da49acc2202 100644 --- a/test/config.json +++ b/test/config.json @@ -584,7 +584,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/buffer"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_buffer", "RetryMax": 0, "Tags": [] }, @@ -593,7 +593,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/concurrentdml"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_concurrentdml", "RetryMax": 0, "Tags": [] }, @@ -602,7 +602,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/schema"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_schema", "RetryMax": 0, "Tags": [] }, @@ -611,7 +611,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sequence"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_sequence", "RetryMax": 0, "Tags": [] }, @@ -620,7 +620,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_setstatement", "RetryMax": 0, "Tags": [] }, @@ -629,7 +629,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect1"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_reservedconn", "RetryMax": 0, "Tags": [] }, @@ -638,7 +638,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn/reconnect2"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_reservedconn", "RetryMax": 0, "Tags": [] }, @@ -647,7 +647,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/transaction"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_transaction", "RetryMax": 0, "Tags": [] }, @@ -656,7 +656,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/unsharded"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_unsharded", "RetryMax": 0, "Tags": [] }, @@ -665,7 +665,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/vschema"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_vschema", "RetryMax": 0, "Tags": [] }, @@ -674,7 +674,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/readafterwrite"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_readafterwrite", "RetryMax": 0, "Tags": [] }, @@ -701,7 +701,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/topotest/etcd2"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_topo", "RetryMax": 0, "Tags": [] }, @@ -710,7 +710,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "vtgate_topo", "RetryMax": 0, "Tags": [] }, @@ -737,7 +737,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/recovery/xtrabackup"], "Command": [], "Manual": false, - "Shard": "17", + "Shard": "xb_recovery", "RetryMax": 0, "Tags": [] }, From 19457309f6929e0e03f1db8cd15d279d9aa077cb Mon Sep 17 00:00:00 2001 From: Rohit Nayak Date: Thu, 10 Jun 2021 15:16:10 +0200 Subject: [PATCH 225/310] Add VReplication lag metric in the form of a gauge for easier display in VTAdmin Signed-off-by: Rohit Nayak --- go/vt/binlog/binlogplayer/binlog_player.go | 5 +++++ .../vttablet/tabletmanager/vreplication/stats.go | 15 +++++++++++++++ .../tabletmanager/vreplication/vplayer.go | 4 ++++ 3 files changed, 24 insertions(+) diff --git a/go/vt/binlog/binlogplayer/binlog_player.go b/go/vt/binlog/binlogplayer/binlog_player.go index 5683f5dd2cd..313fd8ef83a 100644 --- a/go/vt/binlog/binlogplayer/binlog_player.go +++ b/go/vt/binlog/binlogplayer/binlog_player.go @@ -98,6 +98,9 @@ type Stats struct { CopyLoopCount *stats.Counter ErrorCounts *stats.CountersWithMultiLabels NoopQueryCount *stats.CountersWithSingleLabel + + VReplicationLags *stats.Timings + VReplicationLagRates *stats.Rates } // RecordHeartbeat updates the time the last heartbeat from vstreamer was seen @@ -154,6 +157,8 @@ func NewStats() *Stats { bps.CopyLoopCount = stats.NewCounter("", "") bps.ErrorCounts = stats.NewCountersWithMultiLabels("", "", []string{"type"}) bps.NoopQueryCount = stats.NewCountersWithSingleLabel("", "", "Statement", "") + bps.VReplicationLags = stats.NewTimings("", "", "") + bps.VReplicationLagRates = stats.NewRates("", bps.VReplicationLags, 15*60/5, 5*time.Second) return bps } diff --git a/go/vt/vttablet/tabletmanager/vreplication/stats.go b/go/vt/vttablet/tabletmanager/vreplication/stats.go index b0a571ebb58..4cb4a9fe3c1 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/stats.go +++ b/go/vt/vttablet/tabletmanager/vreplication/stats.go @@ -113,6 +113,21 @@ func (st *vrStats) register() { return result }) + stats.NewRateFunc( + "VReplicationLag", + "vreplication lag per stream", + func() map[string][]float64 { + st.mu.Lock() + defer st.mu.Unlock() + result := make(map[string][]float64) + for _, ct := range st.controllers { + for k, v := range ct.blpStats.VReplicationLagRates.Get() { + result[k] = v + } + } + return result + }) + stats.Publish("VReplicationSource", stats.StringMapFunc(func() map[string]string { st.mu.Lock() defer st.mu.Unlock() diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 9933d0db7d5..f4a273f1e0b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "math" + "strconv" "strings" "time" @@ -331,6 +332,7 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { // TODO(sougou): if we also stored the time of the last event, we // can estimate this value more accurately. defer vp.vr.stats.SecondsBehindMaster.Set(math.MaxInt64) + defer vp.vr.stats.VReplicationLags.Add(strconv.Itoa(int(vp.vr.id)), math.MaxInt64) var sbm int64 = -1 for { // check throttler. @@ -347,6 +349,7 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { if len(items) == 0 { behind := time.Now().UnixNano() - vp.lastTimestampNs - vp.timeOffsetNs vp.vr.stats.SecondsBehindMaster.Set(behind / 1e9) + vp.vr.stats.VReplicationLags.Add(strconv.Itoa(int(vp.vr.id)), time.Duration(behind/1e9)*time.Second) } // Empty transactions are saved at most once every idleTimeout. // This covers two situations: @@ -401,6 +404,7 @@ func (vp *vplayer) applyEvents(ctx context.Context, relay *relayLog) error { } if sbm >= 0 { vp.vr.stats.SecondsBehindMaster.Set(sbm) + vp.vr.stats.VReplicationLags.Add(strconv.Itoa(int(vp.vr.id)), time.Duration(sbm)*time.Second) } } From a30e98e5a50d1dcfd5cddec219627f70ccd6c439 Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Thu, 10 Jun 2021 16:52:23 +0300 Subject: [PATCH 226/310] Review updates Signed-off-by: Alkin Tezuysal --- doc/releasenotes/9_0_0_release_notes.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/releasenotes/9_0_0_release_notes.md b/doc/releasenotes/9_0_0_release_notes.md index 4b6f0b13808..6dc076df1ce 100644 --- a/doc/releasenotes/9_0_0_release_notes.md +++ b/doc/releasenotes/9_0_0_release_notes.md @@ -90,6 +90,9 @@ Vitess 9.0 is not compatible with the previous release of the Vitess Kubernetes * VTGate: Move auto_increment from reserved to non reserved keyword #7162 * VTGate: Add only expr of aliasedExpr to weightstring function #7165 * VTGate: [9.0] don't try to compare varchars in vtgate #7271 +* VTGate: Load Data From S3 #6823 +* VTGate: Unnest simple subqueries #6831 +* VTGate: Adding MySQL Check Constraints #6869 * VTExplain: Add sequence table support for vtexplain #7186 * VSchema: Support back-quoted names #7073 * Healthcheck: healthy list should be recomputed when a tablet is removed #7176 @@ -117,6 +120,7 @@ Set statement support has been added in Vitess. There are [some system variables * VReplication: Set time zone to UTC while streaming rows #6845 * VReplication: Materialization and character sets: Add test to verify/demo a workaround for charset issues while using string functions in filters #6847 * VReplication: Tool to diagnose vreplication issues in production #6892 +* VReplication: Allow multiple blacklists for master #6816 * VStreamer Field Event: add allowed values for set/enum #6981 * VDiff: lock keyspace while snapshoting, restart target in case of errors #7012 * VDiff: make enums comparable #6880 @@ -245,6 +249,7 @@ Automatically terminate migrations run by a failed tablet * goimport proto files correctly #7264 * Cherry pick version of #7233 for release-9.0 #7265 * Update Java version to 9.0 #7369 +* Adding curl as dependency #6965 ## Functionality Neutral Changes @@ -280,4 +285,4 @@ Automatically terminate migrations run by a failed tablet * Backport #7275: VReplication: Miscellaneous improvements #7349 * Backport 7342: Workflow Show: use timeUpdated to calculate vreplication lag #7354 * Backport 7361: vtctl: Add missing err checks for VReplication v2 #7363 - +* Backport 7297: VStreamer Events: remove preceding zeroes from decimals in Row Events #7340 From 48e970f9664bbedbd54a08705eb26c0f35c0108e Mon Sep 17 00:00:00 2001 From: Andres Taylor Date: Thu, 10 Jun 2021 15:53:45 +0200 Subject: [PATCH 227/310] first failing expand star test Signed-off-by: Andres Taylor --- go/vt/vtgate/planbuilder/route_planning.go | 7 +++++ .../vtgate/planbuilder/route_planning_test.go | 30 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/go/vt/vtgate/planbuilder/route_planning.go b/go/vt/vtgate/planbuilder/route_planning.go index 6ed1768f407..75c4d2b4de3 100644 --- a/go/vt/vtgate/planbuilder/route_planning.go +++ b/go/vt/vtgate/planbuilder/route_planning.go @@ -55,6 +55,8 @@ func newBuildSelectPlan(sel *sqlparser.Select, vschema ContextVSchema) (engine.P return nil, err } + sel = expandStar(sel, semTable, vschema) + qgraph, err := createQGFromSelect(sel, semTable) if err != nil { return nil, err @@ -97,6 +99,11 @@ func newBuildSelectPlan(sel *sqlparser.Select, vschema ContextVSchema) (engine.P return plan.Primitive(), nil } +func expandStar(sel *sqlparser.Select, semTable *semantics.SemTable, vschema semantics.SchemaInformation) *sqlparser.Select { + // TODO we could store in semTable whether there are any * in the query that needs expanding or not + return sel +} + func planLimit(limit *sqlparser.Limit, plan logicalPlan) (logicalPlan, error) { if limit == nil { return plan, nil diff --git a/go/vt/vtgate/planbuilder/route_planning_test.go b/go/vt/vtgate/planbuilder/route_planning_test.go index 70161799c35..ecf861474b9 100644 --- a/go/vt/vtgate/planbuilder/route_planning_test.go +++ b/go/vt/vtgate/planbuilder/route_planning_test.go @@ -20,6 +20,10 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/vtgate/semantics" "github.com/stretchr/testify/assert" @@ -122,3 +126,29 @@ func TestClone(t *testing.T) { assert.NotNil(t, clonedRP.vindexPreds[0].foundVindex) assert.Nil(t, original.vindexPreds[0].foundVindex) } + +func TestExpandStar(t *testing.T) { + ast, err := sqlparser.Parse("select * from tbl") + require.NoError(t, err) + schemaInfo := &fakeSI{ + tables: map[string]*vindexes.Table{ + "tbl": { + Columns: []vindexes.Column{{ + Name: sqlparser.NewColIdent("a"), + Type: sqltypes.VarChar, + }, { + Name: sqlparser.NewColIdent("b"), + Type: sqltypes.VarChar, + }, { + Name: sqlparser.NewColIdent("c"), + Type: sqltypes.VarChar, + }}, + ColumnListAuthoritative: true, + }, + }, + } + semState, err := semantics.Analyze(ast, "db", schemaInfo) + require.NoError(t, err) + expanded := expandStar(ast.(*sqlparser.Select), semState, schemaInfo) + assert.Equal(t, "select tbl.a, tbl.b, tbl.c from tbl", sqlparser.String(expanded)) +} From 172d139ed7152dd7200d92c6c458dbc33517e4e9 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 10 Jun 2021 19:54:39 +0530 Subject: [PATCH 228/310] split shard 15 tests Signed-off-by: Harshit Gangal --- .../workflows/cluster_endtoend_resharding.yml | 50 +++++++++++++++++++ .../cluster_endtoend_resharding_bytes.yml | 50 +++++++++++++++++++ test/ci_workflow_gen.go | 2 + test/config.json | 4 +- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/cluster_endtoend_resharding.yml create mode 100644 .github/workflows/cluster_endtoend_resharding_bytes.yml diff --git a/.github/workflows/cluster_endtoend_resharding.yml b/.github/workflows/cluster_endtoend_resharding.yml new file mode 100644 index 00000000000..6a724008a16 --- /dev/null +++ b/.github/workflows/cluster_endtoend_resharding.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (resharding) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (resharding) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard resharding diff --git a/.github/workflows/cluster_endtoend_resharding_bytes.yml b/.github/workflows/cluster_endtoend_resharding_bytes.yml new file mode 100644 index 00000000000..11d45b08538 --- /dev/null +++ b/.github/workflows/cluster_endtoend_resharding_bytes.yml @@ -0,0 +1,50 @@ +# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" + +name: Cluster (resharding_bytes) +on: [push, pull_request] +jobs: + + build: + name: Run endtoend tests on Cluster (resharding_bytes) + runs-on: ubuntu-18.04 + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.15 + + - name: Tune the OS + run: | + echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range + + # TEMPORARY WHILE GITHUB FIXES THIS https://github.com/actions/virtual-environments/issues/3185 + - name: Add the current IP address, long hostname and short hostname record to /etc/hosts file + run: | + echo -e "$(ip addr show eth0 | grep "inet\b" | awk '{print $2}' | cut -d/ -f1)\t$(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts + # DON'T FORGET TO REMOVE CODE ABOVE WHEN ISSUE IS ADRESSED! + + - name: Check out code + uses: actions/checkout@v2 + + - name: Get dependencies + run: | + sudo apt-get update + sudo apt-get install -y mysql-server mysql-client make unzip g++ etcd curl git wget eatmydata + sudo service mysql stop + sudo service etcd stop + sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/ + sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld + go mod download + + wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get install -y gnupg2 + sudo dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb + sudo apt-get update + sudo apt-get install percona-xtrabackup-24 + + - name: Run cluster endtoend test + timeout-minutes: 30 + run: | + source build.env + eatmydata -- go run test.go -docker=false -print-log -follow -shard resharding_bytes diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index 26d971b4eda..83797ab5fe1 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -79,6 +79,8 @@ var ( "vtgate_readafterwrite", "vtgate_topo", "xb_recovery", + "resharding", + "resharding_bytes", } // TODO: currently some percona tools including xtrabackup are installed on all clusters, we can possibly optimize // this by only installing them in the required clusters diff --git a/test/config.json b/test/config.json index da49acc2202..cf98ec5ef84 100644 --- a/test/config.json +++ b/test/config.json @@ -418,7 +418,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/sharding/resharding/v3"], "Command": [], "Manual": false, - "Shard": "15", + "Shard": "resharding", "RetryMax": 0, "Tags": [ "worker_test" @@ -429,7 +429,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/sharding/resharding/string"], "Command": [], "Manual": false, - "Shard": "15", + "Shard": "resharding_bytes", "RetryMax": 0, "Tags": [ "worker_test" From 639106cab999b6aeb98997703df44affc8dc92bb Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 10 Jun 2021 20:14:59 +0530 Subject: [PATCH 229/310] added missing tests to CI Signed-off-by: Harshit Gangal --- ...e.yml => cluster_endtoend_vtgate_gen4.yml} | 6 +- ...yml => cluster_endtoend_vtgate_vindex.yml} | 6 +- test/ci_workflow_gen.go | 10 ++-- test/config.json | 60 ++++++++++++++++++- 4 files changed, 68 insertions(+), 14 deletions(-) rename .github/workflows/{cluster_endtoend_vtgate_sequence.yml => cluster_endtoend_vtgate_gen4.yml} (93%) rename .github/workflows/{cluster_endtoend_vtgate_setstatement.yml => cluster_endtoend_vtgate_vindex.yml} (92%) diff --git a/.github/workflows/cluster_endtoend_vtgate_sequence.yml b/.github/workflows/cluster_endtoend_vtgate_gen4.yml similarity index 93% rename from .github/workflows/cluster_endtoend_vtgate_sequence.yml rename to .github/workflows/cluster_endtoend_vtgate_gen4.yml index a8f4f550610..6afb9f56767 100644 --- a/.github/workflows/cluster_endtoend_vtgate_sequence.yml +++ b/.github/workflows/cluster_endtoend_vtgate_gen4.yml @@ -1,11 +1,11 @@ # DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" -name: Cluster (vtgate_sequence) +name: Cluster (vtgate_gen4) on: [push, pull_request] jobs: build: - name: Run endtoend tests on Cluster (vtgate_sequence) + name: Run endtoend tests on Cluster (vtgate_gen4) runs-on: ubuntu-18.04 steps: @@ -47,4 +47,4 @@ jobs: timeout-minutes: 30 run: | source build.env - eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_sequence + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_gen4 diff --git a/.github/workflows/cluster_endtoend_vtgate_setstatement.yml b/.github/workflows/cluster_endtoend_vtgate_vindex.yml similarity index 92% rename from .github/workflows/cluster_endtoend_vtgate_setstatement.yml rename to .github/workflows/cluster_endtoend_vtgate_vindex.yml index 2b168bdbbb0..e157c39db7b 100644 --- a/.github/workflows/cluster_endtoend_vtgate_setstatement.yml +++ b/.github/workflows/cluster_endtoend_vtgate_vindex.yml @@ -1,11 +1,11 @@ # DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows" -name: Cluster (vtgate_setstatement) +name: Cluster (vtgate_vindex) on: [push, pull_request] jobs: build: - name: Run endtoend tests on Cluster (vtgate_setstatement) + name: Run endtoend tests on Cluster (vtgate_vindex) runs-on: ubuntu-18.04 steps: @@ -47,4 +47,4 @@ jobs: timeout-minutes: 30 run: | source build.env - eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_setstatement + eatmydata -- go run test.go -docker=false -print-log -follow -shard vtgate_vindex diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index 83797ab5fe1..dc79e4b043a 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -69,15 +69,15 @@ var ( "vtorc", "vtgate_buffer", "vtgate_concurrentdml", - "vtgate_schema", - "vtgate_sequence", - "vtgate_setstatement", + "vtgate_gen4", + "vtgate_readafterwrite", "vtgate_reservedconn", + "vtgate_schema", + "vtgate_topo", "vtgate_transaction", "vtgate_unsharded", + "vtgate_vindex", "vtgate_vschema", - "vtgate_readafterwrite", - "vtgate_topo", "xb_recovery", "resharding", "resharding_bytes", diff --git a/test/config.json b/test/config.json index cf98ec5ef84..f9f099fa51f 100644 --- a/test/config.json +++ b/test/config.json @@ -611,7 +611,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/sequence"], "Command": [], "Manual": false, - "Shard": "vtgate_sequence", + "Shard": "17", "RetryMax": 0, "Tags": [] }, @@ -620,7 +620,7 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/reservedconn"], "Command": [], "Manual": false, - "Shard": "vtgate_setstatement", + "Shard": "vtgate_reservedconn", "RetryMax": 0, "Tags": [] }, @@ -651,6 +651,15 @@ "RetryMax": 0, "Tags": [] }, + "vtgate_transaction_rollback": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/transaction/rollback"], + "Command": [], + "Manual": false, + "Shard": "vtgate_transaction", + "RetryMax": 0, + "Tags": [] + }, "vtgate_unsharded": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/unsharded"], @@ -678,6 +687,33 @@ "RetryMax": 0, "Tags": [] }, + "vtgate_dbddlplugin": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/createdb_plugin"], + "Command": [], + "Manual": false, + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_gen4": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/gen4"], + "Command": [], + "Manual": false, + "Shard": "vtgate_gen4", + "RetryMax": 0, + "Tags": [] + }, + "vtgate_watchkeyspace": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/keyspace_watches"], + "Command": [], + "Manual": false, + "Shard": "vtgate_topo", + "RetryMax": 0, + "Tags": [] + }, "topo_zk2": { "File": "unused.go", "Args": ["vitess.io/vitess/go/test/endtoend/topotest/zk2", "--topo-flavor=zk2"], @@ -710,7 +746,25 @@ "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/errors_as_warnings"], "Command": [], "Manual": false, - "Shard": "vtgate_topo", + "Shard": "17", + "RetryMax": 0, + "Tags": [] + }, + "prefixfanout": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/prefixfanout"], + "Command": [], + "Manual": false, + "Shard": "vtgate_vindex", + "RetryMax": 0, + "Tags": [] + }, + "vindex_bindvars": { + "File": "unused.go", + "Args": ["vitess.io/vitess/go/test/endtoend/vtgate/vindex_bindvars"], + "Command": [], + "Manual": false, + "Shard": "vtgate_vindex", "RetryMax": 0, "Tags": [] }, From ba8f8c4e080c58469ea26d268903feae76af5979 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Thu, 10 Jun 2021 21:04:59 +0530 Subject: [PATCH 230/310] clear data in tables after test Signed-off-by: Harshit Gangal --- .../vtgate/transaction/rollback/txn_rollback_shutdown_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/test/endtoend/vtgate/transaction/rollback/txn_rollback_shutdown_test.go b/go/test/endtoend/vtgate/transaction/rollback/txn_rollback_shutdown_test.go index 04ee7760064..9b4640a8272 100644 --- a/go/test/endtoend/vtgate/transaction/rollback/txn_rollback_shutdown_test.go +++ b/go/test/endtoend/vtgate/transaction/rollback/txn_rollback_shutdown_test.go @@ -160,5 +160,5 @@ func TestErrorInAutocommitSession(t *testing.T) { // if we have properly working autocommit code, both the successful inserts should be visible to a second // connection, even if we have not done an explicit commit - assert.Equal(t, `[[INT64(1) VARCHAR("foo")] [INT64(2) VARCHAR("baz")]]`, fmt.Sprintf("%v", result.Rows)) + assert.Equal(t, `[[INT64(1) VARCHAR("foo")] [INT64(2) VARCHAR("baz")] [INT64(3) VARCHAR("mark")] [INT64(4) VARCHAR("doug")]]`, fmt.Sprintf("%v", result.Rows)) } From a64711dcc90b8dc42a2b8621dbd264356361b1f5 Mon Sep 17 00:00:00 2001 From: Alex Charis Date: Thu, 10 Jun 2021 20:31:20 +0000 Subject: [PATCH 231/310] [parser] use table_alias for ENGINE option in CREATE TABLE stmt Signed-off-by: Alex Charis --- go/vt/sqlparser/sql.go | 6862 ++++++++++++++++++++-------------------- go/vt/sqlparser/sql.y | 6 +- 2 files changed, 3426 insertions(+), 3442 deletions(-) diff --git a/go/vt/sqlparser/sql.go b/go/vt/sqlparser/sql.go index eb09e595182..6548352b6e9 100644 --- a/go/vt/sqlparser/sql.go +++ b/go/vt/sqlparser/sql.go @@ -1007,22 +1007,22 @@ var yyExca = [...]int{ 147, 118, 263, 118, 318, 118, - -2, 342, + -2, 341, -1, 53, - 34, 490, - 169, 490, - 181, 490, - 214, 504, - 215, 504, - -2, 492, + 34, 489, + 169, 489, + 181, 489, + 214, 503, + 215, 503, + -2, 491, -1, 58, - 171, 514, - -2, 512, + 171, 513, + -2, 511, -1, 84, - 58, 582, - -2, 590, + 58, 581, + -2, 589, -1, 97, - 168, 956, + 168, 955, -2, 91, -1, 99, 1, 113, @@ -1031,43 +1031,43 @@ var yyExca = [...]int{ -1, 109, 174, 244, 175, 244, - -2, 336, + -2, 335, -1, 128, 147, 118, 263, 118, 318, 118, - -2, 351, + -2, 350, -1, 564, + 154, 976, + -2, 972, + -1, 565, 154, 977, -2, 973, - -1, 565, - 154, 978, - -2, 974, -1, 584, + 58, 582, + -2, 594, + -1, 585, 58, 583, -2, 595, - -1, 585, - 58, 584, - -2, 596, -1, 606, - 122, 1326, + 122, 1325, -2, 84, -1, 607, - 122, 1207, + 122, 1206, -2, 85, -1, 613, - 122, 1258, - -2, 950, + 122, 1257, + -2, 949, -1, 754, - 122, 1144, - -2, 947, + 122, 1143, + -2, 946, -1, 790, 180, 38, 185, 38, -2, 255, -1, 867, - 1, 389, - 480, 389, + 1, 388, + 480, 388, -2, 118, -1, 1108, 1, 285, @@ -1079,629 +1079,531 @@ var yyExca = [...]int{ -1, 1184, 174, 244, 175, 244, - -2, 336, + -2, 335, -1, 1193, 180, 39, 185, 39, -2, 256, - -1, 1401, - 154, 982, - -2, 976, - -1, 1494, + -1, 1402, + 154, 981, + -2, 975, + -1, 1493, 76, 66, 84, 66, -2, 70, - -1, 1515, + -1, 1514, 1, 286, 480, 286, -2, 118, - -1, 1948, - 5, 843, - 18, 843, - 20, 843, - 32, 843, - 85, 843, - -2, 622, - -1, 2182, - 48, 918, - -2, 912, + -1, 1947, + 5, 842, + 18, 842, + 20, 842, + 32, 842, + 85, 842, + -2, 621, + -1, 2181, + 48, 917, + -2, 911, } const yyPrivate = 57344 -const yyLast = 29562 +const yyLast = 29529 var yyAct = [...]int{ - 564, 2102, 2278, 2007, 2235, 2222, 2212, 2159, 2248, 927, - 1772, 1779, 83, 3, 1734, 2183, 2129, 1824, 1928, 1701, - 1583, 1780, 1009, 2099, 577, 1929, 1438, 1056, 507, 1735, - 2121, 1512, 522, 1925, 1721, 1828, 1553, 1548, 505, 1804, - 1805, 1868, 1568, 536, 1806, 1887, 1661, 757, 878, 165, - 1491, 1940, 165, 1191, 470, 165, 1581, 907, 820, 1299, - 486, 137, 165, 1395, 1614, 1798, 123, 1387, 1090, 611, - 165, 1555, 1100, 1209, 785, 1567, 1473, 586, 1093, 1440, - 1063, 1480, 1083, 1165, 1066, 1061, 1086, 1421, 498, 1048, - 33, 1364, 486, 571, 945, 486, 165, 486, 761, 791, - 509, 608, 1084, 1198, 1296, 764, 1565, 1282, 1456, 1544, - 788, 765, 786, 787, 81, 1099, 1496, 1073, 79, 925, - 1304, 1183, 106, 100, 107, 101, 863, 493, 798, 140, - 1097, 1160, 1022, 8, 7, 1534, 6, 1848, 1847, 1612, - 78, 1025, 1268, 1875, 1876, 167, 168, 169, 1353, 2131, - 1352, 1435, 1436, 1351, 1350, 1349, 1348, 496, 2267, 497, - 1699, 1341, 773, 2179, 2078, 1976, 768, 2155, 108, 758, - 572, 593, 597, 2154, 824, 102, 2097, 946, 823, 2098, - 2294, 2245, 2286, 1560, 822, 1533, 1651, 2293, 80, 445, - 825, 494, 2205, 2103, 1600, 2244, 2204, 836, 837, 1904, - 840, 841, 842, 843, 1558, 2040, 846, 847, 848, 849, - 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, - 860, 801, 605, 779, 1174, 778, 946, 612, 1700, 102, - 84, 1954, 777, 1855, 872, 873, 1874, 1854, 780, 802, - 826, 827, 828, 956, 549, 1649, 555, 556, 553, 554, - 1497, 552, 551, 550, 1765, 866, 1506, 1764, 161, 923, - 1766, 557, 558, 1955, 1956, 833, 897, 86, 87, 88, - 89, 90, 91, 1437, 1788, 97, 838, 568, 162, 1507, - 1508, 440, 774, 103, 839, 125, 1557, 781, 1101, 775, - 1102, 474, 956, 102, 567, 35, 145, 898, 72, 39, - 40, 570, 2168, 971, 970, 980, 981, 973, 974, 975, - 976, 977, 978, 979, 972, 891, 2031, 982, 2209, 167, - 168, 169, 2009, 902, 903, 862, 885, 135, 1342, 1343, - 1344, 886, 124, 952, 1527, 1526, 944, 885, 777, 884, - 769, 883, 886, 777, 861, 772, 473, 2029, 771, 770, - 142, 1288, 143, 484, 1340, 488, 922, 112, 113, 134, - 133, 160, 482, 1625, 1623, 1624, 1258, 1052, 1829, 1582, - 2003, 1851, 71, 899, 1620, 1627, 1615, 1628, 2004, 1629, - 2292, 914, 952, 916, 920, 2268, 1283, 900, 901, 906, - 868, 892, 2092, 1863, 1619, 775, 776, 1630, 2010, 845, - 474, 844, 1398, 474, 2011, 1617, 2151, 865, 1259, 904, - 1260, 129, 110, 136, 117, 109, 502, 130, 131, 905, - 913, 915, 146, 1584, 1474, 809, 807, 818, 1621, 1177, - 817, 816, 151, 118, 815, 1618, 1784, 814, 813, 812, - 165, 1975, 165, 811, 806, 165, 782, 121, 119, 114, - 115, 116, 120, 895, 819, 473, 1497, 111, 473, 2282, - 1559, 762, 1867, 918, 762, 760, 122, 2289, 2284, 794, - 762, 486, 486, 486, 793, 2203, 951, 948, 949, 950, - 955, 957, 954, 1853, 953, 1297, 1783, 1775, 1566, 486, - 486, 947, 864, 1289, 800, 881, 474, 887, 888, 889, - 890, 599, 776, 938, 1197, 1196, 919, 776, 911, 1888, - 835, 1864, 912, 800, 1606, 1293, 800, 932, 924, 1650, - 810, 808, 917, 2169, 921, 951, 948, 949, 950, 955, - 957, 954, 1776, 953, 2210, 829, 2236, 1983, 138, 1850, - 947, 800, 1913, 1912, 910, 1911, 1702, 1704, 1172, 1171, - 1170, 473, 1840, 1890, 1778, 1870, 1294, 1773, 1168, 444, - 1869, 1870, 439, 1602, 1680, 2190, 1869, 99, 165, 1862, - 2060, 1774, 1861, 994, 995, 1953, 1726, 1669, 1677, 1287, - 1270, 1269, 1271, 1272, 1273, 800, 1054, 1592, 894, 1502, - 1077, 929, 930, 1007, 132, 876, 486, 882, 1513, 165, - 896, 165, 165, 874, 486, 992, 126, 871, 982, 127, - 486, 2280, 1452, 608, 2281, 1892, 2279, 1896, 1761, 1891, - 972, 1889, 1371, 982, 941, 939, 1894, 940, 1010, 73, - 1336, 1782, 1781, 2199, 799, 1893, 1369, 1370, 1368, 880, - 803, 793, 962, 94, 1784, 1703, 800, 908, 1895, 1897, - 804, 1082, 1053, 799, 1049, 1906, 799, 821, 834, 803, - 793, 1284, 1305, 1285, 1067, 1938, 1286, 1616, 805, 804, - 973, 974, 975, 976, 977, 978, 979, 972, 1817, 1290, - 982, 799, 1024, 1027, 1029, 1031, 1032, 1034, 1036, 1037, - 95, 1601, 1028, 1030, 1046, 1033, 1035, 1103, 1038, 942, - 1783, 975, 976, 977, 978, 979, 972, 994, 995, 982, - 139, 144, 141, 147, 148, 149, 150, 152, 153, 154, - 155, 994, 995, 1422, 1599, 799, 156, 157, 158, 159, - 1597, 867, 793, 796, 797, 809, 762, 807, 2261, 612, - 790, 794, 1777, 1958, 971, 970, 980, 981, 973, 974, - 975, 976, 977, 978, 979, 972, 879, 165, 982, 789, - 959, 1161, 167, 168, 169, 1070, 1389, 909, 2228, 1098, - 1169, 2226, 1594, 167, 168, 169, 962, 1793, 2006, 2277, - 2230, 2231, 1306, 1277, 2290, 2227, 799, 595, 71, 486, - 1675, 1193, 2077, 793, 796, 797, 1598, 762, 1674, 1202, - 1367, 790, 794, 1206, 1662, 1055, 486, 486, 1422, 486, - 1687, 486, 486, 1594, 486, 486, 486, 486, 486, 486, - 960, 961, 959, 2076, 1390, 960, 961, 959, 1908, 486, - 1203, 961, 959, 165, 1242, 1794, 1189, 1596, 962, 1175, - 1176, 1275, 1981, 962, 1276, 1782, 1781, 598, 962, 1255, - 2287, 1182, 1201, 499, 2291, 1237, 1238, 1802, 1784, 2273, - 486, 603, 165, 980, 981, 973, 974, 975, 976, 977, - 978, 979, 972, 1295, 1454, 982, 1239, 165, 2288, 1801, - 1211, 1563, 1212, 1265, 1214, 1216, 1278, 2274, 1220, 1222, - 1224, 1226, 1228, 165, 1167, 1263, 1262, 1245, 1246, 1676, - 165, 1200, 1274, 1251, 1252, 1179, 1180, 1261, 1178, 165, + 564, 2101, 2277, 1771, 2006, 2234, 2128, 2221, 2158, 1778, + 2182, 83, 3, 1927, 2211, 536, 1700, 1823, 2098, 1582, + 1439, 2247, 1733, 1928, 1009, 1734, 1056, 1532, 1547, 1924, + 1803, 927, 1779, 1511, 577, 2120, 522, 1867, 1827, 757, + 505, 1567, 1552, 1804, 507, 1490, 1939, 1805, 137, 165, + 1388, 1886, 165, 1720, 470, 165, 1660, 1090, 878, 1580, + 486, 1300, 165, 1797, 1613, 611, 1063, 123, 1554, 1209, + 165, 1396, 1100, 1093, 785, 1083, 1566, 1472, 1066, 907, + 1084, 1061, 586, 820, 1191, 1479, 1441, 1086, 1048, 1365, + 498, 33, 486, 595, 1422, 486, 165, 486, 509, 571, + 81, 945, 1564, 1198, 1283, 1455, 1543, 1297, 764, 791, + 786, 787, 761, 1099, 765, 1097, 1399, 1073, 1305, 788, + 1495, 1183, 79, 608, 106, 925, 863, 493, 1022, 140, + 1160, 8, 1165, 7, 78, 798, 6, 1847, 1846, 1611, + 107, 1025, 1269, 1874, 1875, 2130, 1354, 100, 101, 1353, + 946, 1436, 1437, 1352, 1351, 1350, 1349, 1342, 496, 499, + 497, 1533, 167, 168, 169, 593, 597, 2266, 108, 758, + 1698, 572, 773, 768, 2178, 102, 2077, 825, 2154, 2153, + 1975, 824, 2096, 1132, 823, 2097, 537, 34, 2293, 2244, + 2292, 494, 1559, 549, 80, 555, 556, 553, 554, 1650, + 552, 551, 550, 2204, 2285, 2102, 1599, 605, 2243, 822, + 557, 558, 946, 1557, 2203, 445, 956, 1903, 2039, 1174, + 84, 34, 836, 837, 1699, 840, 841, 842, 843, 102, + 801, 846, 847, 848, 849, 850, 851, 852, 853, 854, + 855, 856, 857, 858, 859, 860, 802, 779, 778, 826, + 827, 828, 1953, 612, 774, 1954, 1955, 86, 87, 88, + 89, 90, 91, 1496, 780, 97, 573, 1101, 162, 1102, + 1854, 440, 833, 1438, 1853, 1506, 1507, 1873, 956, 1648, + 777, 35, 872, 873, 72, 39, 40, 866, 1505, 923, + 897, 570, 568, 102, 567, 1556, 902, 903, 1764, 1787, + 1120, 1763, 838, 898, 1765, 891, 952, 2008, 474, 944, + 777, 885, 769, 2208, 1526, 1525, 886, 772, 885, 2030, + 771, 770, 2028, 886, 1343, 1344, 1345, 167, 168, 169, + 839, 884, 484, 883, 914, 862, 916, 775, 482, 1341, + 488, 1624, 1622, 1623, 1133, 2167, 971, 970, 980, 981, + 973, 974, 975, 976, 977, 978, 979, 972, 71, 1052, + 982, 1828, 781, 473, 1289, 1581, 1850, 775, 952, 2002, + 1614, 920, 2291, 913, 915, 777, 861, 2003, 1284, 899, + 868, 892, 904, 2009, 906, 1626, 922, 1627, 1629, 1628, + 900, 901, 905, 1619, 2267, 1146, 1149, 1150, 1151, 1152, + 1153, 1154, 1862, 1155, 1156, 1157, 1158, 1159, 1134, 1135, + 1136, 1137, 1118, 1119, 1147, 845, 1121, 844, 1122, 1123, + 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1138, 1139, + 1140, 1141, 1142, 1143, 1144, 1145, 1618, 1887, 1259, 865, + 165, 2010, 165, 1616, 776, 165, 474, 1620, 2150, 951, + 948, 949, 950, 955, 957, 954, 1974, 953, 2091, 1583, + 809, 911, 807, 918, 947, 912, 1177, 1473, 818, 1558, + 817, 486, 486, 486, 776, 917, 816, 1617, 474, 815, + 1260, 1889, 1261, 814, 813, 812, 811, 806, 782, 486, + 486, 819, 1783, 2202, 800, 762, 2288, 910, 2283, 2281, + 794, 473, 938, 1148, 474, 881, 1290, 887, 888, 889, + 890, 951, 948, 949, 950, 955, 957, 954, 895, 953, + 1852, 762, 1496, 919, 864, 760, 947, 762, 924, 2209, + 1197, 1196, 1649, 473, 793, 1298, 1565, 1701, 1703, 776, + 1866, 1425, 2235, 1891, 599, 1895, 921, 1890, 1863, 1888, + 1605, 1294, 932, 829, 1893, 810, 835, 808, 1982, 473, + 1849, 800, 800, 1892, 1912, 1911, 2168, 1910, 165, 1172, + 1171, 1170, 1839, 1295, 1168, 444, 1894, 1896, 439, 1288, + 1271, 1270, 1272, 1273, 1274, 1054, 1861, 99, 2189, 1860, + 1601, 994, 995, 882, 2059, 963, 486, 929, 930, 165, + 1952, 165, 165, 992, 486, 1725, 1668, 1591, 1501, 1077, + 486, 1679, 800, 874, 871, 73, 1007, 876, 1782, 1774, + 972, 1869, 941, 982, 939, 580, 1868, 940, 1512, 1010, + 1676, 499, 800, 982, 799, 608, 1702, 1760, 1053, 1869, + 1020, 793, 796, 797, 1868, 762, 1082, 908, 1451, 790, + 794, 2279, 880, 894, 2280, 1049, 2278, 926, 926, 926, + 1372, 1285, 2198, 1286, 1775, 896, 1287, 1337, 789, 1067, + 1306, 959, 1059, 1062, 1370, 1371, 1369, 34, 1024, 1027, + 1029, 1031, 1032, 1034, 1036, 1037, 1777, 962, 1453, 1772, + 991, 993, 1028, 1030, 1046, 1033, 1035, 962, 1038, 821, + 1065, 799, 799, 1773, 834, 1905, 971, 970, 980, 981, + 973, 974, 975, 976, 977, 978, 979, 972, 1600, 1937, + 982, 1006, 1615, 1291, 94, 1011, 1012, 1013, 1014, 1015, + 1016, 1017, 1018, 1103, 1021, 1023, 1026, 1026, 1026, 1023, + 1026, 1026, 1023, 1026, 1039, 1040, 1041, 1042, 1043, 1044, + 1045, 867, 799, 1452, 994, 995, 1051, 165, 803, 793, + 34, 1161, 942, 1781, 1780, 612, 1661, 909, 804, 879, + 1169, 95, 799, 994, 995, 1423, 1783, 1686, 803, 793, + 960, 961, 959, 960, 961, 959, 805, 1088, 804, 486, + 1307, 1193, 960, 961, 959, 1055, 961, 959, 962, 1202, + 1907, 962, 1816, 1206, 1423, 1598, 486, 486, 1593, 486, + 962, 486, 486, 962, 486, 486, 486, 486, 486, 486, + 973, 974, 975, 976, 977, 978, 979, 972, 1189, 486, + 982, 1596, 1597, 165, 1242, 970, 980, 981, 973, 974, + 975, 976, 977, 978, 979, 972, 1203, 809, 982, 165, + 807, 1593, 1182, 975, 976, 977, 978, 979, 972, 1782, + 486, 982, 165, 1802, 1175, 1176, 2260, 2286, 1239, 2272, + 1957, 1237, 1238, 1296, 1776, 1595, 1211, 165, 1212, 1070, + 1214, 1216, 800, 1201, 1220, 1222, 1224, 1226, 1228, 960, + 961, 959, 2076, 165, 1167, 2287, 2075, 2273, 2289, 1980, + 165, 1200, 1653, 1654, 1655, 1179, 1278, 962, 1180, 165, 165, 165, 165, 165, 165, 165, 165, 165, 486, 486, - 486, 1915, 1192, 1253, 1247, 1199, 1199, 996, 997, 998, - 999, 1000, 1001, 1002, 1003, 1004, 1005, 600, 601, 1453, - 1309, 1307, 1308, 1244, 1264, 165, 1301, 1313, 1243, 1315, - 1316, 1317, 1318, 1218, 1803, 1312, 1322, 960, 961, 959, - 1457, 1458, 1319, 1320, 1321, 1240, 960, 961, 959, 1916, - 1337, 2276, 2275, 581, 2262, 962, 2256, 2254, 581, 1298, - 960, 961, 959, 1388, 962, 2118, 1065, 960, 961, 959, - 2074, 779, 1391, 778, 1359, 1361, 1362, 102, 962, 1654, - 1655, 1656, 2048, 1961, 1173, 962, 486, 1917, 1360, 1365, - 167, 168, 169, 1347, 1311, 1811, 1799, 1399, 1645, 1610, - 1609, 971, 970, 980, 981, 973, 974, 975, 976, 977, - 978, 979, 972, 1392, 1393, 982, 1446, 1332, 1333, 1334, - 486, 486, 1302, 1266, 1410, 1413, 960, 961, 959, 1254, - 1423, 165, 167, 168, 169, 1250, 1768, 167, 168, 169, - 1249, 1576, 1248, 2145, 962, 486, 1366, 1400, 82, 167, - 168, 169, 165, 1574, 1445, 486, 2149, 1401, 1447, 165, - 80, 165, 1990, 2242, 1010, 2148, 565, 1399, 1459, 165, - 165, 1405, 1595, 167, 168, 169, 486, 1256, 2101, 486, - 1926, 1492, 1990, 2197, 1831, 608, 1429, 1430, 608, 1937, - 486, 971, 970, 980, 981, 973, 974, 975, 976, 977, - 978, 979, 972, 1990, 2192, 982, 1814, 1402, 1990, 2191, - 2173, 581, 2095, 581, 1521, 166, 1465, 1471, 166, 1990, - 2093, 166, 1594, 581, 1937, 1467, 487, 1401, 166, 1594, - 525, 524, 527, 528, 529, 530, 166, 1517, 1495, 526, - 581, 531, 2058, 581, 1722, 486, 1973, 1972, 1969, 1970, - 1516, 1569, 1570, 1571, 1969, 1968, 1573, 1575, 487, 1465, - 581, 487, 166, 487, 1520, 1497, 1849, 1164, 1833, 486, - 1826, 1827, 1469, 1477, 581, 486, 1202, 1550, 1498, 1202, - 1528, 1202, 1529, 1530, 1531, 1532, 1556, 35, 1500, 1593, - 958, 581, 1504, 1164, 1163, 1498, 1109, 1108, 1540, 1541, - 1542, 1543, 1519, 1518, 1722, 1755, 1503, 35, 2055, 1476, - 1466, 612, 1729, 1497, 612, 1477, 1580, 2198, 35, 486, - 958, 1388, 1990, 1971, 1477, 1505, 1388, 1388, 1692, 1587, - 1691, 574, 1590, 1465, 1591, 1594, 1577, 1730, 1455, 1551, - 1433, 1345, 1499, 1292, 1095, 784, 1546, 1547, 2079, 783, - 1501, 1233, 71, 2161, 1562, 1564, 1561, 2136, 2100, 1499, - 1572, 165, 1477, 2071, 71, 2066, 1603, 1497, 165, 963, - 1166, 1551, 1585, 165, 165, 1937, 1604, 165, 801, 165, - 1586, 1589, 1465, 1549, 71, 165, 2005, 1965, 1605, 1535, - 1536, 1537, 165, 1607, 1608, 71, 802, 1834, 2080, 2081, - 2082, 1234, 1235, 1236, 2083, 499, 1199, 1545, 71, 1539, - 1538, 1280, 1194, 1190, 1020, 1162, 96, 1808, 866, 165, - 486, 1482, 1485, 1486, 1487, 1483, 2008, 1484, 1488, 1613, - 2162, 1941, 1942, 1941, 1942, 1560, 1640, 1641, 2258, 2223, - 1988, 1643, 1987, 1986, 1807, 1944, 1059, 1062, 1926, 1230, - 1644, 2084, 2085, 1482, 1485, 1486, 1487, 1483, 1818, 1484, - 1488, 1363, 1634, 1947, 1372, 1373, 1374, 1375, 1376, 1377, - 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1633, - 970, 980, 981, 973, 974, 975, 976, 977, 978, 979, - 972, 1808, 1365, 982, 1406, 1407, 1231, 1232, 1412, 1415, - 1416, 1338, 1746, 591, 587, 1946, 1744, 1747, 1743, 1742, - 1671, 1745, 2270, 1748, 165, 1486, 1487, 2243, 1918, 588, - 1648, 1711, 165, 1425, 1428, 1064, 2059, 1431, 1432, 2184, - 2186, 1993, 1720, 1719, 2214, 1709, 2249, 2272, 2187, 2247, - 1657, 2217, 2213, 1710, 1068, 1069, 590, 165, 589, 1366, - 2181, 1291, 566, 1786, 1524, 1708, 1812, 1418, 165, 165, - 165, 165, 165, 831, 830, 2018, 1731, 1715, 1057, 1807, - 165, 1873, 1419, 572, 165, 931, 1670, 165, 165, 1842, - 1058, 165, 165, 165, 1841, 1736, 1753, 1727, 1686, 103, - 2134, 591, 587, 1963, 1767, 1962, 1588, 1724, 1208, 2053, - 1049, 1706, 1207, 1698, 1195, 1450, 166, 588, 166, 1457, - 1458, 166, 1984, 1637, 2194, 1792, 2156, 1785, 1490, 575, - 576, 1714, 1626, 1653, 578, 1725, 2255, 1756, 2253, 2252, - 1723, 1758, 584, 585, 590, 2218, 589, 487, 487, 487, - 1737, 486, 2216, 1740, 2052, 1791, 165, 1795, 1796, 1797, - 1749, 1754, 1301, 165, 1989, 487, 487, 1770, 1762, 486, - 1759, 1738, 1739, 1718, 1741, 486, 1578, 579, 82, 1202, - 1202, 1717, 1771, 2051, 1921, 486, 1722, 1556, 2260, 2259, - 2260, 1681, 1837, 1678, 1078, 1800, 1071, 1846, 2188, 1960, - 1451, 1830, 574, 80, 85, 77, 1810, 1, 165, 165, - 165, 165, 165, 2225, 457, 1434, 1809, 1047, 469, 1815, - 2221, 1267, 1257, 2104, 165, 165, 2158, 1845, 1996, 1554, - 1844, 792, 1835, 1836, 1182, 1819, 1820, 1821, 128, 1514, - 1515, 2238, 1400, 93, 166, 755, 92, 795, 893, 1579, - 1843, 2096, 1401, 1787, 1525, 1115, 1113, 1114, 1303, 1112, - 486, 1117, 1116, 1111, 1339, 483, 1388, 1489, 163, 1884, - 1104, 1072, 487, 832, 447, 166, 1974, 166, 166, 1335, - 487, 1611, 453, 990, 1716, 1763, 487, 1871, 609, 1886, - 1872, 602, 1865, 1932, 2211, 1877, 486, 2180, 2182, 2130, - 2185, 2178, 2271, 2246, 2193, 1789, 1790, 165, 1522, 1449, - 1060, 2050, 1899, 1920, 1685, 1019, 1420, 486, 535, 1087, - 508, 1444, 1883, 486, 486, 1358, 1884, 523, 520, 521, - 1460, 1728, 964, 1898, 1927, 506, 1354, 1355, 1356, 1357, - 500, 1885, 1924, 1079, 1481, 1479, 165, 1478, 1736, 1635, - 1091, 1943, 1939, 1085, 1464, 1905, 1523, 1852, 2002, 1936, - 943, 583, 495, 767, 1930, 1417, 2167, 164, 1652, 1914, - 443, 2039, 582, 481, 61, 165, 1658, 1659, 1660, 1949, - 443, 1951, 1945, 1952, 38, 490, 2266, 934, 443, 1666, - 1667, 1408, 1409, 592, 32, 31, 1950, 1935, 30, 29, - 28, 23, 22, 1982, 21, 596, 596, 20, 19, 165, - 1684, 1966, 1967, 25, 443, 18, 17, 486, 16, 98, - 48, 1957, 45, 43, 105, 486, 104, 46, 42, 499, - 869, 165, 27, 166, 26, 15, 14, 1978, 13, 12, - 1977, 165, 1995, 11, 10, 9, 5, 4, 1992, 937, - 1997, 24, 1008, 2, 0, 165, 1979, 1980, 165, 0, - 1994, 0, 0, 0, 1991, 487, 1556, 2019, 0, 2000, - 0, 1999, 2043, 0, 0, 0, 0, 0, 0, 0, - 0, 1511, 487, 487, 0, 487, 0, 487, 487, 0, - 487, 487, 487, 487, 487, 487, 2014, 2013, 0, 0, - 2022, 0, 0, 0, 0, 487, 0, 0, 0, 166, - 2016, 2017, 0, 0, 0, 0, 0, 0, 0, 0, - 2027, 971, 970, 980, 981, 973, 974, 975, 976, 977, - 978, 979, 972, 0, 0, 982, 487, 0, 166, 0, - 1552, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1424, 2054, 0, 166, 0, 0, 1736, 2063, 0, 0, - 0, 0, 2024, 2025, 0, 2026, 0, 0, 2028, 166, - 2030, 0, 0, 0, 165, 2069, 166, 165, 165, 165, - 486, 486, 0, 2070, 0, 166, 166, 166, 166, 166, - 166, 166, 166, 166, 487, 487, 487, 2090, 0, 2105, - 486, 486, 486, 0, 0, 0, 0, 2062, 0, 0, - 0, 0, 0, 0, 0, 0, 2111, 0, 0, 0, - 2068, 166, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 580, 486, 486, 486, 165, 0, - 2109, 0, 0, 0, 0, 0, 0, 0, 0, 486, - 0, 486, 0, 0, 2117, 0, 0, 486, 0, 0, - 2137, 0, 486, 0, 2127, 2133, 2125, 2126, 2139, 1879, - 1880, 2135, 0, 0, 2142, 0, 0, 2141, 0, 2144, - 0, 0, 487, 2143, 1900, 1901, 0, 1902, 1903, 1930, - 0, 486, 2049, 1930, 486, 2146, 0, 2147, 1909, 1910, - 2150, 0, 0, 2160, 0, 2152, 2153, 0, 2157, 0, - 0, 0, 0, 0, 0, 0, 487, 487, 0, 0, - 0, 167, 168, 169, 0, 0, 0, 166, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2177, 0, 0, - 0, 487, 0, 0, 2073, 2189, 2075, 0, 166, 0, - 0, 487, 486, 165, 0, 166, 0, 166, 443, 2196, - 443, 0, 0, 443, 486, 166, 166, 0, 0, 2200, - 1930, 0, 487, 0, 0, 487, 0, 0, 0, 0, - 0, 486, 1959, 462, 0, 2208, 487, 0, 2215, 486, - 486, 0, 461, 2219, 2224, 2229, 2237, 2232, 2160, 2239, - 1688, 2110, 0, 459, 0, 0, 0, 1736, 2251, 2250, - 0, 0, 0, 0, 0, 0, 0, 2257, 0, 0, - 0, 0, 161, 0, 2128, 0, 0, 2263, 0, 0, - 0, 1712, 1713, 1062, 0, 0, 2269, 0, 0, 0, - 0, 487, 456, 0, 0, 0, 0, 103, 0, 0, - 0, 468, 0, 2283, 0, 0, 0, 0, 0, 0, - 145, 2285, 0, 0, 0, 487, 0, 0, 0, 0, - 0, 487, 0, 971, 970, 980, 981, 973, 974, 975, - 976, 977, 978, 979, 972, 2020, 443, 982, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, - 0, 1769, 596, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 142, 487, 143, 443, 0, 443, - 1094, 0, 0, 0, 0, 160, 446, 0, 448, 463, - 0, 476, 0, 475, 452, 0, 450, 454, 464, 455, - 0, 449, 0, 460, 0, 0, 451, 465, 466, 480, - 479, 467, 0, 473, 458, 477, 0, 166, 0, 0, - 0, 0, 0, 0, 166, 161, 0, 2037, 2042, 166, - 166, 0, 2072, 166, 0, 166, 0, 0, 0, 0, - 0, 166, 0, 0, 0, 0, 146, 0, 166, 0, - 103, 0, 0, 0, 0, 0, 151, 0, 0, 0, - 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 166, 487, 971, 970, 980, - 981, 973, 974, 975, 976, 977, 978, 979, 972, 0, - 0, 982, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2112, 2113, 2114, 2115, 2116, 0, 0, 0, 2119, - 2120, 0, 0, 0, 0, 0, 0, 142, 0, 143, - 0, 0, 0, 0, 0, 1907, 0, 0, 160, 0, - 0, 0, 0, 0, 0, 443, 0, 0, 0, 478, + 486, 1192, 1245, 1246, 1178, 71, 1098, 2227, 1251, 1252, + 2225, 1914, 1199, 1199, 1276, 1255, 1675, 1368, 1266, 2229, + 2230, 1801, 1302, 1800, 2226, 165, 1562, 167, 168, 169, + 1310, 1390, 167, 168, 169, 1279, 1792, 1314, 1264, 1316, + 1317, 1318, 1319, 1308, 1309, 1263, 1323, 1277, 2290, 1262, + 1456, 1457, 598, 1253, 1304, 1247, 1244, 1313, 2276, 1915, + 1338, 1366, 1299, 1389, 1320, 1321, 1322, 1360, 1362, 1363, + 1243, 1240, 1392, 1218, 1173, 1275, 2275, 102, 2005, 1265, + 2274, 1361, 1348, 1936, 1781, 1780, 486, 2261, 2255, 1391, + 2253, 2117, 1312, 2073, 1793, 779, 778, 1783, 603, 167, + 168, 169, 799, 1767, 960, 961, 959, 2047, 1960, 793, + 796, 797, 1916, 762, 1810, 1393, 1394, 790, 794, 1400, + 486, 486, 962, 1333, 1334, 1335, 167, 168, 169, 1798, + 1575, 165, 1355, 1356, 1357, 1358, 960, 961, 959, 1644, + 1411, 1414, 600, 601, 1367, 486, 1424, 1609, 1608, 1401, + 1445, 1303, 165, 1402, 962, 486, 1444, 1406, 1267, 165, + 1254, 165, 1250, 1674, 1249, 1010, 1248, 581, 1446, 165, + 165, 1673, 167, 168, 169, 2148, 486, 2147, 1458, 486, + 1491, 1989, 2241, 80, 926, 926, 926, 1409, 1410, 1400, + 486, 1989, 2196, 2100, 1430, 1431, 1989, 2191, 960, 961, + 959, 167, 168, 169, 1830, 1573, 1925, 608, 1407, 1408, + 608, 1403, 1413, 1416, 1417, 1936, 962, 1989, 2190, 1470, + 2172, 581, 1813, 1402, 1520, 499, 2054, 1494, 1721, 1516, + 1466, 1534, 1535, 1536, 2094, 581, 35, 1515, 1429, 1989, + 2092, 1432, 1433, 1593, 581, 486, 2057, 581, 1972, 1971, + 1497, 1568, 1569, 1570, 1968, 1969, 1572, 1574, 1968, 1967, + 1464, 581, 35, 581, 1519, 1496, 1848, 1721, 1549, 486, + 1164, 1832, 1468, 1825, 1826, 486, 1202, 1510, 82, 1202, + 2197, 1202, 1476, 581, 1594, 1555, 2135, 1728, 71, 1592, + 1503, 1502, 1499, 525, 524, 527, 528, 529, 530, 1476, + 1518, 1517, 526, 1754, 531, 958, 581, 958, 1579, 1164, + 1163, 1496, 1729, 71, 1498, 1109, 1108, 1475, 1465, 486, + 35, 1389, 1500, 1989, 1497, 1970, 1389, 1389, 1476, 1527, + 1504, 1528, 1529, 1530, 1531, 1691, 1551, 612, 1936, 71, + 612, 1593, 1690, 1545, 1546, 1464, 1464, 1539, 1540, 1541, + 1542, 1561, 1563, 1550, 2078, 1492, 1571, 1233, 1602, 1560, + 1586, 574, 165, 1589, 1593, 1590, 1576, 1454, 1434, 165, + 1476, 1604, 1346, 1293, 165, 165, 1606, 1607, 165, 1603, + 165, 1588, 1584, 1585, 565, 1550, 165, 801, 1498, 1095, + 1464, 784, 783, 165, 2160, 2082, 1496, 71, 2099, 2070, + 2065, 1166, 1548, 802, 2079, 2080, 2081, 1234, 1235, 1236, + 1946, 2004, 1964, 1199, 1833, 1544, 1538, 1537, 1281, 1612, + 165, 486, 980, 981, 973, 974, 975, 976, 977, 978, + 979, 972, 1194, 166, 982, 1190, 166, 1162, 71, 166, + 96, 1806, 2083, 2084, 487, 1807, 166, 1639, 1640, 2007, + 866, 2161, 1642, 1559, 166, 2257, 1481, 1484, 1485, 1486, + 1482, 1643, 1483, 1487, 2222, 1366, 1940, 1941, 1940, 1941, + 1987, 1230, 1986, 1985, 1943, 1925, 487, 1817, 1633, 487, + 166, 487, 1339, 1632, 966, 1745, 969, 1945, 1807, 1742, + 1746, 1741, 983, 984, 985, 986, 987, 988, 989, 2269, + 967, 968, 965, 971, 970, 980, 981, 973, 974, 975, + 976, 977, 978, 979, 972, 165, 2242, 982, 1231, 1232, + 1917, 1670, 1743, 165, 1064, 591, 587, 1744, 1647, 1481, + 1484, 1485, 1486, 1482, 1710, 1483, 1487, 2058, 1992, 1656, + 1747, 588, 1485, 1486, 1719, 1718, 165, 2271, 1367, 2246, + 2248, 2216, 2180, 1707, 2183, 2185, 1292, 165, 165, 165, + 165, 165, 566, 2186, 1730, 1714, 1068, 1069, 590, 165, + 589, 2213, 1785, 165, 1523, 572, 165, 165, 1708, 2212, + 165, 165, 165, 1669, 1752, 1811, 1709, 831, 830, 1419, + 2017, 1723, 1806, 1766, 1665, 1666, 1685, 1687, 1057, 931, + 1735, 1872, 1049, 1697, 1420, 1726, 1841, 1840, 2133, 1705, + 1058, 103, 1962, 1961, 1791, 1683, 1713, 1587, 591, 587, + 1208, 1755, 1207, 1722, 1195, 1757, 1711, 1712, 1062, 1724, + 1404, 1405, 1736, 2052, 588, 1739, 1788, 1789, 1737, 1738, + 486, 1740, 1449, 1769, 1983, 165, 1790, 1302, 1794, 1795, + 1796, 1753, 165, 1748, 1758, 1456, 1457, 1761, 486, 584, + 585, 590, 1636, 589, 486, 2193, 2155, 1667, 1202, 1202, + 573, 1770, 1784, 1489, 486, 1555, 1447, 575, 576, 1717, + 1625, 1652, 1799, 578, 2050, 2254, 1845, 1716, 2252, 2251, + 2217, 2215, 2051, 1988, 1577, 579, 82, 165, 165, 165, + 165, 165, 1808, 1836, 1920, 1721, 1829, 1704, 1814, 2259, + 2258, 2259, 1680, 165, 165, 1677, 1078, 1071, 1844, 2187, + 1809, 1959, 1843, 1450, 1182, 1818, 1819, 1820, 574, 80, + 85, 77, 1088, 1401, 1, 2224, 457, 1402, 1435, 1731, + 1732, 1047, 1842, 1088, 1088, 1088, 1088, 1088, 469, 486, + 2220, 1268, 1834, 1835, 1258, 1389, 2103, 2157, 1995, 1492, + 1553, 792, 1088, 128, 1513, 1514, 1088, 2237, 93, 755, + 1864, 92, 795, 893, 1578, 2095, 1786, 1885, 1524, 1115, + 1883, 1113, 1114, 1112, 1117, 486, 1116, 1111, 1340, 483, + 1488, 163, 1104, 1072, 1876, 832, 165, 447, 1870, 1973, + 1336, 1871, 1610, 453, 990, 1897, 486, 1898, 1715, 1762, + 609, 602, 486, 486, 1931, 2210, 1884, 2179, 2181, 1882, + 2129, 2184, 2177, 2270, 166, 1929, 166, 2245, 2192, 166, + 1904, 1926, 1521, 1448, 1060, 165, 2049, 1883, 1919, 1684, + 1019, 1923, 1421, 1087, 508, 1443, 1359, 523, 520, 521, + 1459, 1727, 964, 1735, 1913, 487, 487, 487, 506, 500, + 1906, 1838, 1079, 1480, 165, 1478, 1944, 1935, 1477, 1634, + 1091, 1942, 1938, 487, 487, 1085, 1463, 1522, 1851, 2001, + 1949, 943, 1934, 583, 495, 767, 1418, 1948, 2166, 1950, + 1651, 1951, 1981, 2038, 582, 1921, 61, 1956, 165, 38, + 490, 2265, 1965, 1966, 934, 592, 486, 32, 31, 30, + 29, 28, 23, 22, 486, 21, 20, 19, 25, 18, + 165, 17, 16, 98, 48, 45, 43, 105, 104, 1977, + 165, 1994, 1976, 46, 42, 869, 27, 26, 1996, 15, + 14, 13, 12, 11, 165, 1990, 10, 165, 9, 5, + 4, 937, 166, 1991, 1555, 1993, 2018, 24, 1008, 2, + 0, 1999, 1998, 0, 0, 0, 0, 0, 0, 0, + 1978, 1979, 0, 0, 0, 0, 2013, 0, 0, 0, + 487, 0, 2012, 166, 0, 166, 166, 0, 487, 0, + 0, 0, 0, 0, 487, 0, 1930, 0, 34, 2021, + 2026, 0, 0, 0, 0, 0, 0, 0, 0, 2015, + 2016, 0, 0, 0, 1663, 0, 0, 0, 1664, 0, + 0, 1088, 0, 2048, 0, 0, 0, 0, 0, 1671, + 1672, 0, 0, 0, 0, 1678, 2053, 0, 1681, 1682, + 0, 0, 2062, 0, 0, 0, 1688, 0, 1689, 0, + 0, 1692, 1693, 1694, 1695, 1696, 0, 0, 0, 0, + 0, 1735, 0, 165, 0, 1706, 165, 165, 165, 486, + 486, 0, 0, 0, 0, 2072, 2069, 2074, 0, 0, + 0, 2040, 2061, 2068, 0, 0, 2089, 0, 2104, 486, + 486, 486, 0, 0, 0, 2067, 0, 0, 0, 0, + 2023, 2024, 0, 2025, 499, 2110, 2027, 0, 2029, 0, + 0, 2063, 1750, 1751, 2064, 0, 0, 2066, 0, 0, + 0, 0, 0, 0, 486, 486, 486, 165, 2108, 0, + 0, 0, 2109, 0, 0, 0, 0, 0, 486, 0, + 486, 166, 0, 0, 0, 0, 486, 2126, 2136, 0, + 1929, 486, 2138, 2116, 1929, 2127, 2132, 0, 2134, 0, + 2124, 2125, 0, 2141, 0, 0, 0, 0, 2143, 0, + 2037, 0, 0, 487, 0, 0, 2140, 2043, 2044, 2045, + 486, 0, 2142, 486, 2149, 0, 2145, 0, 2146, 0, + 487, 487, 0, 487, 2152, 487, 487, 2156, 487, 487, + 487, 487, 487, 487, 0, 2151, 0, 0, 0, 0, + 0, 0, 0, 487, 2159, 0, 0, 166, 0, 535, + 0, 0, 0, 2176, 2131, 499, 0, 0, 0, 2188, + 0, 1929, 0, 166, 0, 0, 0, 0, 0, 0, + 0, 486, 165, 0, 487, 0, 166, 2195, 0, 0, + 0, 0, 0, 486, 0, 0, 0, 0, 2199, 0, + 0, 166, 0, 0, 2207, 0, 0, 0, 164, 0, + 486, 443, 2214, 0, 481, 0, 2223, 166, 486, 486, + 0, 443, 2228, 0, 166, 2231, 2236, 1880, 1881, 443, + 2218, 0, 0, 166, 166, 166, 166, 166, 166, 166, + 166, 166, 487, 487, 487, 2250, 596, 596, 2256, 2159, + 2238, 2249, 1735, 581, 0, 443, 0, 2262, 0, 0, + 0, 1930, 0, 34, 0, 1930, 2268, 0, 0, 166, 971, 970, 980, 981, 973, 974, 975, 976, 977, 978, - 979, 972, 0, 0, 982, 0, 0, 471, 0, 0, - 1922, 534, 138, 0, 0, 0, 0, 0, 0, 0, - 166, 0, 472, 0, 0, 0, 0, 0, 166, 0, - 1205, 0, 0, 0, 0, 0, 0, 0, 0, 146, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 151, - 0, 0, 0, 166, 0, 1205, 1205, 0, 0, 0, - 0, 443, 0, 0, 166, 166, 166, 166, 166, 0, - 0, 485, 0, 0, 0, 0, 166, 0, 0, 0, - 166, 0, 0, 166, 166, 0, 0, 166, 166, 166, - 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 610, 0, 1300, 759, 0, 766, 0, - 0, 0, 2233, 0, 0, 0, 0, 0, 0, 0, - 0, 443, 0, 0, 0, 0, 0, 0, 443, 0, - 0, 0, 0, 0, 0, 0, 0, 1323, 1324, 443, - 443, 443, 443, 443, 443, 443, 0, 487, 0, 0, - 0, 0, 166, 0, 0, 138, 0, 0, 0, 166, - 0, 0, 0, 0, 0, 487, 0, 2036, 0, 0, - 0, 487, 0, 443, 0, 0, 0, 0, 0, 0, - 0, 487, 0, 0, 139, 144, 141, 147, 148, 149, - 150, 152, 153, 154, 155, 0, 2041, 0, 0, 0, - 156, 157, 158, 159, 166, 166, 166, 166, 166, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 499, - 166, 166, 0, 0, 0, 0, 2064, 0, 0, 2065, - 0, 0, 2067, 0, 0, 596, 1300, 0, 0, 0, - 596, 596, 0, 0, 596, 596, 596, 0, 0, 0, - 1205, 0, 0, 0, 0, 0, 487, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 596, 596, 596, 596, 596, 0, 0, 2035, 0, 1442, - 971, 970, 980, 981, 973, 974, 975, 976, 977, 978, - 979, 972, 487, 0, 982, 0, 0, 0, 0, 0, - 443, 0, 0, 166, 0, 0, 1300, 443, 0, 443, - 0, 0, 0, 487, 0, 0, 0, 443, 443, 487, - 487, 0, 0, 0, 0, 2034, 0, 139, 144, 141, - 147, 148, 149, 150, 152, 153, 154, 155, 0, 2132, - 499, 0, 166, 156, 157, 158, 159, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 966, 0, 969, 0, - 0, 0, 0, 0, 983, 984, 985, 986, 987, 988, - 989, 166, 967, 968, 965, 971, 970, 980, 981, 973, - 974, 975, 976, 977, 978, 979, 972, 0, 0, 982, - 971, 970, 980, 981, 973, 974, 975, 976, 977, 978, - 979, 972, 0, 0, 982, 166, 0, 0, 0, 0, - 0, 0, 0, 487, 0, 0, 0, 0, 0, 0, - 0, 487, 0, 0, 0, 0, 0, 166, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 166, 971, 970, - 980, 981, 973, 974, 975, 976, 977, 978, 979, 972, - 0, 166, 982, 0, 166, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1878, 0, 0, 0, 1403, - 1404, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 610, 610, 610, 971, 970, 980, 981, 973, - 974, 975, 976, 977, 978, 979, 972, 0, 0, 982, - 933, 935, 0, 0, 0, 0, 0, 0, 0, 443, - 0, 0, 0, 0, 0, 1448, 443, 0, 0, 0, - 0, 443, 443, 1663, 0, 443, 0, 1638, 0, 0, - 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, - 443, 0, 0, 971, 970, 980, 981, 973, 974, 975, - 976, 977, 978, 979, 972, 0, 0, 982, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, - 166, 0, 0, 166, 166, 166, 487, 487, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 487, 487, 487, 0, - 0, 0, 0, 0, 0, 0, 0, 1075, 0, 0, - 0, 0, 0, 0, 0, 610, 0, 0, 0, 0, - 0, 1105, 0, 0, 0, 596, 596, 0, 0, 0, - 0, 487, 487, 487, 166, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 487, 596, 487, 0, 0, - 0, 0, 0, 487, 0, 0, 0, 0, 487, 0, - 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, - 1442, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 487, 0, 0, - 487, 0, 0, 0, 596, 443, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1205, 443, 443, 443, 443, - 443, 0, 0, 0, 0, 0, 0, 0, 1750, 0, - 0, 0, 443, 0, 0, 443, 443, 0, 0, 443, - 1760, 1300, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 487, 166, - 0, 0, 1132, 537, 34, 0, 0, 0, 0, 0, + 979, 972, 2282, 0, 982, 0, 0, 0, 0, 0, + 2284, 0, 0, 1932, 0, 0, 2144, 0, 0, 0, + 0, 971, 970, 980, 981, 973, 974, 975, 976, 977, + 978, 979, 972, 0, 1947, 982, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 167, 168, 169, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 487, 0, 0, - 0, 0, 0, 0, 0, 487, 487, 0, 34, 0, - 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, - 759, 1822, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1205, 0, 1204, 0, 0, 0, 1210, 1210, 0, - 1210, 1300, 1210, 1210, 0, 1219, 1210, 1210, 1210, 1210, - 1210, 0, 0, 573, 0, 0, 0, 0, 1204, 1204, - 759, 0, 1050, 0, 0, 0, 443, 443, 443, 443, - 443, 0, 1664, 0, 0, 0, 1665, 0, 0, 0, - 0, 0, 443, 443, 0, 0, 0, 1672, 1673, 1120, - 0, 1279, 0, 1679, 0, 0, 1682, 1683, 0, 0, - 0, 0, 0, 0, 1689, 0, 1690, 0, 0, 1693, - 1694, 1695, 1696, 1697, 442, 0, 0, 596, 0, 0, - 0, 0, 0, 0, 489, 1707, 0, 0, 0, 0, - 0, 0, 569, 1133, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 610, - 610, 610, 0, 0, 0, 0, 0, 0, 763, 0, - 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, - 0, 0, 1751, 1752, 0, 0, 0, 0, 1205, 0, - 0, 0, 0, 0, 1146, 1149, 1150, 1151, 1152, 1153, - 1154, 0, 1155, 1156, 1157, 1158, 1159, 1134, 1135, 1136, - 1137, 1118, 1119, 1147, 443, 1121, 0, 1122, 1123, 1124, - 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1138, 1139, 1140, - 1141, 1142, 1143, 1144, 1145, 0, 0, 0, 0, 0, - 0, 0, 0, 443, 0, 0, 0, 1394, 0, 610, - 0, 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, 443, 0, 0, - 0, 1426, 1427, 0, 0, 0, 0, 0, 1205, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, - 0, 0, 1148, 0, 0, 0, 1461, 0, 0, 443, - 0, 0, 0, 0, 0, 0, 1075, 0, 161, 610, - 0, 0, 0, 443, 0, 0, 443, 0, 0, 1823, - 0, 0, 0, 0, 0, 0, 0, 610, 0, 0, - 610, 0, 0, 103, 0, 125, 0, 0, 0, 0, - 0, 759, 0, 0, 0, 0, 145, 1881, 1882, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, - 0, 0, 124, 0, 0, 0, 1205, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 766, 0, 0, 0, - 142, 0, 143, 0, 0, 0, 0, 1185, 1186, 134, - 133, 160, 0, 1933, 0, 0, 0, 0, 0, 0, - 759, 0, 0, 0, 0, 0, 766, 0, 0, 0, - 0, 0, 443, 0, 1948, 443, 443, 443, 0, 0, - 0, 0, 0, 0, 926, 926, 926, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 129, 1187, 136, 34, 1184, 0, 130, 131, 0, - 759, 0, 146, 0, 0, 0, 0, 991, 993, 0, - 0, 0, 151, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1442, 0, 0, 0, - 0, 0, 870, 0, 875, 0, 0, 877, 1006, 0, - 0, 0, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, - 0, 1021, 1023, 1026, 1026, 1026, 1023, 1026, 1026, 1023, - 1026, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 0, 0, - 0, 0, 0, 1051, 0, 0, 0, 34, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2021, 0, 0, 0, 2023, 0, - 0, 1647, 0, 0, 1088, 0, 0, 0, 0, 2032, - 2033, 161, 0, 0, 0, 0, 0, 0, 138, 0, - 0, 0, 1181, 0, 0, 2047, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 103, 0, 125, 0, - 0, 443, 2056, 2057, 0, 0, 2061, 0, 0, 145, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1205, 0, 0, - 0, 0, 0, 0, 132, 0, 0, 0, 0, 0, - 135, 0, 0, 0, 0, 124, 126, 0, 0, 127, - 0, 1081, 0, 0, 1092, 0, 0, 0, 0, 0, - 0, 0, 0, 142, 0, 143, 0, 2094, 0, 0, - 1185, 1186, 134, 133, 160, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 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, 2122, 0, 0, 0, 0, - 0, 0, 0, 0, 129, 1187, 136, 0, 1184, 0, - 130, 131, 0, 0, 0, 146, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 151, 0, 0, 0, 0, - 139, 144, 141, 147, 148, 149, 150, 152, 153, 154, - 155, 0, 0, 0, 0, 0, 156, 157, 158, 159, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1813, 2163, 2164, 2165, 2166, 0, 2170, 0, - 2171, 2172, 2174, 0, 0, 0, 2175, 2176, 0, 0, - 1825, 0, 0, 0, 1204, 0, 1832, 0, 0, 1110, - 0, 0, 0, 0, 610, 0, 1838, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, - 36, 37, 72, 39, 40, 0, 0, 0, 2202, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 76, - 0, 138, 0, 0, 41, 67, 68, 0, 65, 69, - 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 926, 926, 926, 0, 1241, 0, 0, 0, 0, - 0, 610, 0, 0, 0, 0, 54, 0, 0, 0, - 0, 0, 0, 0, 2264, 2265, 71, 132, 0, 0, - 0, 0, 0, 0, 1281, 0, 0, 0, 0, 126, - 0, 0, 127, 0, 0, 0, 0, 1210, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1310, 0, 0, 610, 0, - 0, 1204, 1314, 0, 1934, 1210, 0, 0, 0, 0, - 0, 0, 0, 1325, 1326, 1327, 1328, 1329, 1330, 1331, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 44, 47, 50, 49, 52, 0, 64, 0, 0, 70, - 0, 0, 0, 0, 0, 0, 0, 1092, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 53, 75, 74, 0, 0, 62, 63, 51, - 0, 0, 0, 139, 144, 141, 147, 148, 149, 150, - 152, 153, 154, 155, 0, 0, 0, 0, 0, 156, - 157, 158, 159, 0, 0, 0, 0, 0, 759, 0, - 0, 1204, 1493, 0, 0, 0, 1825, 0, 55, 56, - 0, 57, 58, 59, 60, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1468, 0, 0, 0, 0, 0, - 0, 1472, 0, 1475, 0, 0, 0, 0, 0, 0, - 0, 0, 1494, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1204, - 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1825, 2091, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2106, 2107, 2108, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2123, 2123, 2123, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2138, 0, 2140, 0, 0, 0, 0, 0, 1825, 0, - 0, 0, 0, 1825, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1825, 0, 0, 610, 0, 0, 0, 0, - 0, 0, 0, 1092, 0, 0, 0, 0, 0, 0, - 1622, 0, 0, 0, 0, 1631, 1632, 0, 0, 1636, - 0, 0, 0, 0, 0, 0, 0, 1639, 0, 0, - 0, 0, 0, 1668, 1642, 0, 573, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1825, 0, 0, 0, 0, 0, 0, - 0, 1646, 0, 0, 0, 2206, 0, 0, 0, 0, - 0, 0, 0, 1705, 0, 0, 0, 0, 0, 0, - 1204, 0, 2220, 0, 0, 0, 0, 0, 0, 0, - 610, 610, 0, 0, 0, 0, 0, 0, 0, 0, - 1088, 0, 0, 0, 0, 0, 0, 1732, 1733, 0, - 0, 1088, 1088, 1088, 1088, 1088, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1493, 0, 0, - 1088, 0, 0, 0, 1088, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1757, 0, 0, 0, 0, 0, 0, 0, 0, 1839, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1816, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1856, 1857, 1858, 1859, 1860, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1092, 1866, 0, 0, - 0, 0, 0, 0, 1931, 0, 34, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1088, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1919, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1930, 0, 971, 970, 980, 981, 973, 974, + 975, 976, 977, 978, 979, 972, 1877, 2194, 982, 0, + 0, 0, 34, 0, 487, 487, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 166, 971, 970, 980, 981, + 973, 974, 975, 976, 977, 978, 979, 972, 462, 487, + 982, 0, 0, 0, 0, 0, 166, 461, 0, 487, + 34, 0, 0, 166, 0, 166, 0, 0, 459, 0, + 0, 0, 161, 166, 166, 0, 0, 0, 0, 0, + 487, 0, 0, 487, 0, 0, 0, 2042, 0, 0, + 0, 0, 0, 0, 487, 502, 0, 103, 0, 0, + 0, 0, 0, 0, 2020, 0, 0, 456, 2022, 0, + 145, 2036, 0, 0, 0, 0, 468, 0, 0, 2031, + 2032, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2046, 971, 970, 980, 981, + 973, 974, 975, 976, 977, 978, 979, 972, 0, 487, + 982, 1768, 2055, 2056, 0, 0, 2060, 0, 0, 0, + 0, 0, 0, 474, 142, 0, 143, 0, 0, 0, + 0, 0, 0, 487, 0, 160, 0, 0, 0, 487, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 446, 0, 448, 463, 0, 476, 0, 475, 452, + 0, 450, 454, 464, 455, 0, 449, 0, 460, 0, + 0, 451, 465, 466, 480, 479, 467, 2093, 473, 458, + 477, 0, 0, 487, 971, 970, 980, 981, 973, 974, + 975, 976, 977, 978, 979, 972, 146, 0, 982, 0, + 0, 0, 0, 0, 0, 0, 151, 0, 0, 2041, + 0, 2035, 0, 0, 0, 0, 0, 0, 0, 443, + 0, 443, 0, 0, 443, 2121, 166, 0, 0, 0, + 0, 0, 0, 166, 0, 0, 0, 0, 166, 166, + 0, 0, 166, 0, 166, 0, 0, 0, 0, 0, + 166, 0, 161, 0, 0, 0, 0, 166, 971, 970, + 980, 981, 973, 974, 975, 976, 977, 978, 979, 972, + 0, 0, 982, 0, 0, 2034, 0, 103, 0, 0, + 0, 0, 0, 0, 166, 487, 0, 0, 0, 0, + 145, 0, 0, 2162, 2163, 2164, 2165, 0, 2169, 0, + 2170, 2171, 2173, 0, 478, 0, 2174, 2175, 0, 534, + 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 471, 0, 971, 970, 980, 981, 973, 974, + 975, 976, 977, 978, 979, 972, 2033, 472, 982, 0, + 0, 0, 0, 0, 142, 0, 143, 443, 2201, 0, + 0, 0, 0, 0, 0, 160, 0, 0, 0, 0, + 0, 0, 0, 596, 0, 0, 0, 0, 0, 485, + 0, 0, 0, 0, 0, 0, 0, 0, 443, 166, + 443, 1094, 0, 0, 0, 0, 0, 166, 971, 970, + 980, 981, 973, 974, 975, 976, 977, 978, 979, 972, + 0, 610, 982, 0, 759, 0, 766, 0, 0, 0, + 166, 0, 0, 0, 2263, 2264, 146, 0, 0, 0, + 0, 166, 166, 166, 166, 166, 151, 0, 0, 0, + 0, 0, 0, 166, 0, 0, 0, 166, 0, 0, + 166, 166, 0, 0, 166, 166, 166, 1662, 0, 971, + 970, 980, 981, 973, 974, 975, 976, 977, 978, 979, + 972, 0, 0, 982, 0, 0, 0, 971, 970, 980, + 981, 973, 974, 975, 976, 977, 978, 979, 972, 0, + 0, 982, 0, 0, 139, 144, 141, 147, 148, 149, + 150, 152, 153, 154, 155, 0, 0, 0, 0, 0, + 156, 157, 158, 159, 487, 0, 0, 0, 0, 166, + 0, 0, 0, 0, 0, 0, 166, 0, 0, 0, + 0, 0, 487, 0, 0, 0, 0, 0, 487, 0, + 0, 0, 138, 0, 0, 0, 443, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1964, 0, 0, + 0, 0, 1050, 0, 0, 0, 0, 0, 0, 0, + 0, 166, 166, 166, 166, 166, 996, 997, 998, 999, + 1000, 1001, 1002, 1003, 1004, 1005, 0, 166, 166, 0, + 0, 1205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 442, 0, 1205, 1205, 0, 0, + 0, 0, 443, 487, 489, 0, 0, 0, 0, 0, + 0, 0, 569, 0, 0, 0, 0, 0, 1256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2038, 0, - 0, 1985, 0, 0, 0, 2044, 2045, 2046, 0, 0, + 0, 443, 0, 0, 0, 0, 0, 0, 763, 487, + 0, 0, 0, 0, 0, 0, 1301, 0, 0, 0, + 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 487, 0, 443, 0, 0, 0, 487, 487, 0, 443, + 0, 0, 0, 0, 0, 0, 0, 0, 1324, 1325, + 443, 443, 443, 443, 443, 443, 443, 0, 0, 166, + 0, 0, 0, 0, 139, 144, 141, 147, 148, 149, + 150, 152, 153, 154, 155, 0, 0, 0, 0, 0, + 156, 157, 158, 159, 443, 0, 0, 0, 166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1998, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2001, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2012, 0, 0, - 2015, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 166, 0, 0, 0, 0, 0, 0, 0, + 487, 0, 0, 0, 0, 0, 0, 0, 487, 0, + 610, 610, 610, 0, 166, 0, 596, 1301, 0, 0, + 0, 596, 596, 0, 166, 596, 596, 596, 933, 935, + 0, 1205, 0, 0, 0, 0, 0, 0, 166, 0, + 0, 166, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 596, 596, 596, 596, 596, 0, 0, 0, 0, + 1256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 443, 0, 0, 0, 0, 0, 1301, 443, 0, + 443, 0, 0, 0, 0, 0, 0, 0, 443, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1075, 0, 0, 0, 0, + 0, 0, 0, 610, 0, 0, 0, 0, 0, 1105, + 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, + 166, 166, 166, 487, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 487, 487, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1931, - 0, 34, 0, 1931, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2086, 0, 0, 2087, - 2088, 2089, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 487, 487, + 487, 166, 870, 0, 875, 0, 0, 877, 0, 0, + 0, 0, 487, 0, 487, 0, 0, 0, 0, 0, + 487, 0, 0, 0, 0, 487, 0, 0, 0, 0, + 1364, 0, 0, 1373, 1374, 1375, 1376, 1377, 1378, 1379, + 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 0, 0, + 0, 0, 0, 0, 487, 0, 0, 487, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 443, 0, 0, 0, 0, 0, 0, 443, 0, + 0, 0, 0, 443, 443, 0, 0, 443, 0, 1637, + 0, 0, 1426, 0, 0, 443, 0, 0, 0, 0, + 0, 0, 443, 0, 0, 0, 0, 0, 759, 0, + 0, 0, 0, 0, 0, 487, 166, 0, 0, 0, + 0, 1204, 0, 0, 0, 1210, 1210, 487, 1210, 443, + 1210, 1210, 0, 1219, 1210, 1210, 1210, 1210, 1210, 0, + 0, 0, 0, 0, 487, 0, 1204, 1204, 759, 0, + 0, 0, 487, 487, 0, 0, 0, 0, 0, 0, + 0, 1081, 0, 0, 1092, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1280, + 0, 0, 0, 0, 0, 0, 0, 596, 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 596, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, + 0, 0, 1256, 0, 0, 0, 0, 610, 610, 610, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1931, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2195, 0, 0, 0, 0, - 34, 0, 0, 0, 0, 0, 0, 0, 737, 723, - 0, 0, 672, 740, 642, 660, 750, 663, 666, 706, - 621, 685, 314, 657, 0, 646, 617, 653, 618, 644, - 674, 223, 678, 641, 725, 688, 739, 272, 34, 623, - 647, 328, 662, 176, 708, 366, 209, 281, 279, 394, - 233, 226, 222, 208, 256, 287, 326, 384, 320, 746, - 276, 695, 0, 375, 299, 0, 0, 0, 676, 729, - 683, 719, 671, 707, 631, 694, 741, 658, 703, 742, - 262, 207, 175, 311, 376, 237, 0, 0, 0, 167, - 168, 169, 0, 2240, 2241, 2201, 0, 0, 0, 0, - 198, 0, 205, 700, 736, 655, 702, 219, 260, 225, - 218, 391, 747, 728, 705, 753, 616, 697, 0, 619, - 622, 749, 732, 650, 651, 0, 0, 0, 0, 0, - 0, 0, 675, 684, 716, 669, 0, 0, 0, 0, - 0, 0, 0, 0, 648, 0, 693, 0, 0, 0, - 627, 620, 0, 0, 0, 0, 673, 0, 0, 0, - 630, 0, 649, 717, 0, 614, 245, 624, 300, 0, - 721, 731, 670, 423, 735, 668, 667, 738, 712, 628, - 727, 661, 271, 626, 268, 171, 187, 0, 659, 310, - 349, 355, 726, 645, 654, 210, 652, 353, 324, 408, - 194, 235, 346, 329, 351, 692, 710, 352, 277, 396, - 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, - 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, - 371, 243, 174, 275, 432, 186, 361, 202, 179, 383, - 404, 199, 364, 0, 0, 0, 181, 402, 380, 294, - 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, - 400, 211, 437, 190, 419, 183, 928, 418, 306, 395, - 403, 295, 286, 182, 401, 293, 285, 270, 231, 251, - 339, 280, 340, 252, 302, 301, 303, 0, 177, 0, - 377, 412, 438, 195, 196, 197, 640, 230, 234, 240, - 242, 0, 248, 255, 273, 317, 338, 336, 342, 722, - 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, - 305, 191, 254, 373, 269, 278, 714, 752, 323, 354, - 200, 410, 374, 635, 639, 633, 634, 686, 687, 636, - 743, 744, 745, 718, 629, 0, 637, 638, 0, 724, - 733, 734, 691, 170, 184, 274, 748, 343, 238, 436, - 417, 413, 615, 632, 216, 643, 0, 0, 656, 664, - 665, 677, 679, 680, 681, 682, 690, 698, 699, 701, - 709, 711, 713, 715, 720, 730, 751, 172, 173, 185, - 193, 203, 215, 228, 236, 246, 250, 253, 257, 258, - 261, 266, 283, 288, 289, 290, 291, 307, 308, 309, - 312, 315, 316, 319, 321, 322, 325, 331, 332, 333, - 334, 335, 337, 344, 348, 356, 357, 358, 359, 360, - 362, 363, 367, 368, 369, 370, 378, 382, 397, 398, - 409, 421, 426, 247, 405, 427, 0, 282, 689, 696, - 284, 232, 249, 259, 704, 416, 379, 189, 350, 239, - 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, - 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, - 389, 296, 220, 737, 723, 0, 0, 672, 740, 642, + 0, 0, 0, 0, 596, 443, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1205, 443, 443, 443, 443, + 443, 0, 0, 0, 0, 0, 0, 0, 1749, 0, + 0, 0, 443, 0, 0, 443, 443, 0, 0, 443, + 1759, 1301, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1110, + 0, 0, 0, 0, 0, 1395, 0, 610, 0, 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, 443, 0, 0, 0, 0, 1427, + 1428, 1821, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1205, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1301, 0, 0, 1460, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1075, 1241, 0, 610, 0, 0, + 0, 0, 0, 0, 0, 0, 443, 443, 443, 443, + 443, 0, 0, 0, 0, 610, 0, 0, 610, 0, + 0, 0, 443, 443, 1282, 0, 0, 0, 0, 759, + 0, 0, 0, 0, 0, 0, 1657, 1658, 1659, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1311, 0, 596, 0, 0, + 0, 0, 1315, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1326, 1327, 1328, 1329, 1330, 1331, 1332, + 0, 0, 0, 0, 766, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 443, 0, 1092, 759, 0, + 161, 0, 0, 0, 766, 0, 0, 0, 1205, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 103, 0, 125, 0, 0, + 0, 0, 0, 0, 443, 0, 0, 0, 145, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 759, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 443, 0, 0, 0, 0, 0, 135, + 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 142, 0, 143, 0, 0, 443, 0, 112, + 113, 134, 133, 160, 0, 0, 0, 0, 1205, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, + 0, 0, 0, 0, 1467, 0, 0, 0, 0, 443, + 0, 1471, 0, 1474, 0, 0, 0, 0, 0, 0, + 0, 0, 1493, 443, 0, 0, 443, 0, 0, 0, + 1646, 0, 0, 129, 110, 136, 117, 109, 0, 130, + 131, 0, 0, 0, 146, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 151, 118, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, + 119, 114, 115, 116, 120, 0, 0, 0, 0, 111, + 0, 0, 0, 0, 0, 0, 0, 0, 122, 0, + 0, 0, 0, 0, 0, 0, 1205, 1878, 1879, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1899, 1900, 0, 1901, 1902, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1908, 1909, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 443, 0, 0, 443, 443, 443, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 138, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1256, 0, 0, 0, + 1958, 0, 0, 0, 1092, 0, 132, 0, 0, 0, + 0, 1621, 0, 0, 0, 0, 1630, 1631, 126, 0, + 1635, 127, 0, 0, 0, 0, 0, 0, 1638, 0, + 0, 0, 0, 0, 0, 1641, 0, 0, 0, 1812, + 35, 36, 37, 72, 39, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1824, 0, 0, + 76, 1204, 1645, 1831, 0, 41, 67, 68, 0, 65, + 69, 610, 0, 1837, 0, 0, 0, 0, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2019, 0, 0, 0, 54, 0, 0, + 0, 443, 0, 0, 0, 0, 0, 71, 0, 0, + 0, 0, 139, 144, 141, 147, 148, 149, 150, 152, + 153, 154, 155, 0, 0, 0, 0, 1205, 156, 157, + 158, 159, 0, 0, 0, 0, 0, 161, 610, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1822, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 103, 0, 125, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1210, 145, 0, 0, 0, 0, + 2071, 44, 47, 50, 49, 52, 0, 64, 0, 0, + 70, 0, 0, 0, 0, 610, 0, 0, 1204, 0, + 0, 1933, 1210, 0, 0, 0, 135, 0, 0, 1756, + 0, 124, 0, 53, 75, 74, 0, 0, 62, 63, + 51, 0, 0, 0, 0, 0, 0, 0, 0, 142, + 0, 143, 0, 0, 0, 0, 1185, 1186, 134, 133, + 160, 0, 0, 0, 0, 0, 0, 0, 0, 2111, + 2112, 2113, 2114, 2115, 0, 0, 0, 2118, 2119, 55, + 56, 0, 57, 58, 59, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1815, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 129, 1187, 136, 0, 1184, 759, 130, 131, 1204, 0, + 0, 146, 0, 1824, 0, 0, 0, 0, 0, 0, + 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1855, + 1856, 1857, 1858, 1859, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1092, 1865, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1204, 0, 0, 0, + 2232, 0, 0, 0, 0, 0, 0, 138, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1918, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1824, 2090, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 132, 0, 0, 0, 0, 2105, 2106, + 2107, 0, 0, 0, 0, 126, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 1963, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2122, 2122, 2122, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2137, 0, 2139, + 1984, 0, 0, 0, 0, 1824, 0, 0, 0, 0, + 1824, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1997, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2000, 0, 0, 0, 0, 0, 0, 1824, + 0, 0, 610, 0, 0, 0, 2011, 0, 0, 2014, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, + 144, 141, 147, 148, 149, 150, 152, 153, 154, 155, + 0, 0, 0, 0, 0, 156, 157, 158, 159, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1824, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2205, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1204, 0, 2219, + 0, 0, 0, 0, 0, 0, 0, 610, 610, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2085, 0, 0, 2086, 2087, + 2088, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 737, 723, 0, 0, 672, 740, 642, 660, 750, 663, 666, 706, 621, 685, 314, 657, 0, 646, 617, 653, 618, 644, 674, 223, 678, 641, 725, 688, 739, 272, 0, 623, 647, 328, 662, 176, 708, @@ -1709,15 +1611,15 @@ var yyAct = [...]int{ 287, 326, 384, 320, 746, 276, 695, 0, 375, 299, 0, 0, 0, 676, 729, 683, 719, 671, 707, 631, 694, 741, 658, 703, 742, 262, 207, 175, 311, 376, - 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, + 237, 0, 0, 0, 167, 168, 169, 0, 2239, 2240, 0, 0, 0, 0, 0, 198, 0, 205, 700, 736, 655, 702, 219, 260, 225, 218, 391, 747, 728, 705, 753, 616, 697, 0, 619, 622, 749, 732, 650, 651, 0, 0, 0, 0, 0, 0, 0, 675, 684, 716, - 669, 0, 0, 0, 0, 0, 0, 1923, 0, 648, + 669, 0, 0, 0, 0, 0, 0, 0, 0, 648, 0, 693, 0, 0, 0, 627, 620, 0, 0, 0, 0, 673, 0, 0, 0, 630, 0, 649, 717, 0, - 614, 245, 624, 300, 0, 721, 731, 670, 423, 735, + 614, 245, 624, 300, 2200, 721, 731, 670, 423, 735, 668, 667, 738, 712, 628, 727, 661, 271, 626, 268, 171, 187, 0, 659, 310, 349, 355, 726, 645, 654, 210, 652, 353, 324, 408, 194, 235, 346, 329, 351, @@ -1762,7 +1664,7 @@ var yyAct = [...]int{ 218, 391, 747, 728, 705, 753, 616, 697, 0, 619, 622, 749, 732, 650, 651, 0, 0, 0, 0, 0, 0, 0, 675, 684, 716, 669, 0, 0, 0, 0, - 0, 0, 1761, 0, 648, 0, 693, 0, 0, 0, + 0, 0, 1922, 0, 648, 0, 693, 0, 0, 0, 627, 620, 0, 0, 0, 0, 673, 0, 0, 0, 630, 0, 649, 717, 0, 614, 245, 624, 300, 0, 721, 731, 670, 423, 735, 668, 667, 738, 712, 628, @@ -1809,7 +1711,7 @@ var yyAct = [...]int{ 655, 702, 219, 260, 225, 218, 391, 747, 728, 705, 753, 616, 697, 0, 619, 622, 749, 732, 650, 651, 0, 0, 0, 0, 0, 0, 0, 675, 684, 716, - 669, 0, 0, 0, 0, 0, 0, 1470, 0, 648, + 669, 0, 0, 0, 0, 0, 0, 1760, 0, 648, 0, 693, 0, 0, 0, 627, 620, 0, 0, 0, 0, 673, 0, 0, 0, 630, 0, 649, 717, 0, 614, 245, 624, 300, 0, 721, 731, 670, 423, 735, @@ -1851,13 +1753,13 @@ var yyAct = [...]int{ 233, 226, 222, 208, 256, 287, 326, 384, 320, 746, 276, 695, 0, 375, 299, 0, 0, 0, 676, 729, 683, 719, 671, 707, 631, 694, 741, 658, 703, 742, - 262, 207, 175, 311, 376, 237, 71, 0, 0, 167, + 262, 207, 175, 311, 376, 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, 700, 736, 655, 702, 219, 260, 225, 218, 391, 747, 728, 705, 753, 616, 697, 0, 619, 622, 749, 732, 650, 651, 0, 0, 0, 0, 0, 0, 0, 675, 684, 716, 669, 0, 0, 0, 0, - 0, 0, 0, 0, 648, 0, 693, 0, 0, 0, + 0, 0, 1469, 0, 648, 0, 693, 0, 0, 0, 627, 620, 0, 0, 0, 0, 673, 0, 0, 0, 630, 0, 649, 717, 0, 614, 245, 624, 300, 0, 721, 731, 670, 423, 735, 668, 667, 738, 712, 628, @@ -1899,7 +1801,7 @@ var yyAct = [...]int{ 287, 326, 384, 320, 746, 276, 695, 0, 375, 299, 0, 0, 0, 676, 729, 683, 719, 671, 707, 631, 694, 741, 658, 703, 742, 262, 207, 175, 311, 376, - 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, + 237, 71, 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, 700, 736, 655, 702, 219, 260, 225, 218, 391, 747, 728, 705, 753, 616, 697, 0, 619, 622, 749, 732, 650, 651, @@ -1964,13 +1866,13 @@ var yyAct = [...]int{ 371, 243, 174, 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, - 400, 211, 437, 190, 419, 183, 625, 418, 306, 395, + 400, 211, 437, 190, 419, 183, 928, 418, 306, 395, 403, 295, 286, 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, 195, 196, 197, 640, 230, 234, 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, 722, 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, - 613, 754, 607, 606, 269, 278, 714, 752, 323, 354, + 305, 191, 254, 373, 269, 278, 714, 752, 323, 354, 200, 410, 374, 635, 639, 633, 634, 686, 687, 636, 743, 744, 745, 718, 629, 0, 637, 638, 0, 724, 733, 734, 691, 170, 184, 274, 748, 343, 238, 436, @@ -2009,7 +1911,7 @@ var yyAct = [...]int{ 692, 710, 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, - 186, 361, 202, 179, 383, 1096, 199, 364, 0, 0, + 186, 361, 202, 179, 383, 404, 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, 190, 419, 183, 625, 418, 306, 395, 403, 295, 286, 182, 401, @@ -2057,7 +1959,7 @@ var yyAct = [...]int{ 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, 186, 361, 202, 179, 383, - 604, 199, 364, 0, 0, 0, 181, 402, 380, 294, + 1096, 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, 190, 419, 183, 625, 418, 306, 395, 403, 295, 286, 182, 401, 293, 285, 270, 231, 251, @@ -2081,203 +1983,344 @@ var yyAct = [...]int{ 284, 232, 249, 259, 704, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, - 389, 296, 220, 314, 0, 0, 1396, 0, 504, 0, - 0, 0, 223, 0, 503, 0, 0, 0, 272, 0, - 0, 1397, 328, 0, 176, 0, 366, 209, 281, 279, - 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, - 547, 276, 0, 0, 375, 299, 0, 0, 0, 0, - 0, 538, 539, 0, 0, 0, 0, 0, 0, 0, - 0, 262, 207, 175, 311, 376, 237, 71, 0, 0, - 167, 168, 169, 525, 524, 527, 528, 529, 530, 0, - 0, 198, 526, 205, 531, 532, 533, 0, 219, 260, - 225, 218, 391, 0, 0, 0, 0, 0, 501, 518, - 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, + 389, 296, 220, 737, 723, 0, 0, 672, 740, 642, + 660, 750, 663, 666, 706, 621, 685, 314, 657, 0, + 646, 617, 653, 618, 644, 674, 223, 678, 641, 725, + 688, 739, 272, 0, 623, 647, 328, 662, 176, 708, + 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, + 287, 326, 384, 320, 746, 276, 695, 0, 375, 299, + 0, 0, 0, 676, 729, 683, 719, 671, 707, 631, + 694, 741, 658, 703, 742, 262, 207, 175, 311, 376, + 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, + 0, 0, 0, 0, 0, 198, 0, 205, 700, 736, + 655, 702, 219, 260, 225, 218, 391, 747, 728, 705, + 753, 616, 697, 0, 619, 622, 749, 732, 650, 651, + 0, 0, 0, 0, 0, 0, 0, 675, 684, 716, + 669, 0, 0, 0, 0, 0, 0, 0, 0, 648, + 0, 693, 0, 0, 0, 627, 620, 0, 0, 0, + 0, 673, 0, 0, 0, 630, 0, 649, 717, 0, + 614, 245, 624, 300, 0, 721, 731, 670, 423, 735, + 668, 667, 738, 712, 628, 727, 661, 271, 626, 268, + 171, 187, 0, 659, 310, 349, 355, 726, 645, 654, + 210, 652, 353, 324, 408, 194, 235, 346, 329, 351, + 692, 710, 352, 277, 396, 341, 406, 424, 425, 217, + 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, + 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, + 186, 361, 202, 179, 383, 604, 199, 364, 0, 0, + 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, + 221, 241, 212, 313, 399, 400, 211, 437, 190, 419, + 183, 625, 418, 306, 395, 403, 295, 286, 182, 401, + 293, 285, 270, 231, 251, 339, 280, 340, 252, 302, + 301, 303, 0, 177, 0, 377, 412, 438, 195, 196, + 197, 640, 230, 234, 240, 242, 0, 248, 255, 273, + 317, 338, 336, 342, 722, 390, 407, 415, 422, 428, + 429, 433, 430, 431, 434, 613, 754, 607, 606, 269, + 278, 714, 752, 323, 354, 200, 410, 374, 635, 639, + 633, 634, 686, 687, 636, 743, 744, 745, 718, 629, + 0, 637, 638, 0, 724, 733, 734, 691, 170, 184, + 274, 748, 343, 238, 436, 417, 413, 615, 632, 216, + 643, 0, 0, 656, 664, 665, 677, 679, 680, 681, + 682, 690, 698, 699, 701, 709, 711, 713, 715, 720, + 730, 751, 172, 173, 185, 193, 203, 215, 228, 236, + 246, 250, 253, 257, 258, 261, 266, 283, 288, 289, + 290, 291, 307, 308, 309, 312, 315, 316, 319, 321, + 322, 325, 331, 332, 333, 334, 335, 337, 344, 348, + 356, 357, 358, 359, 360, 362, 363, 367, 368, 369, + 370, 378, 382, 397, 398, 409, 421, 426, 247, 405, + 427, 0, 282, 689, 696, 284, 232, 249, 259, 704, + 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, + 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, + 201, 365, 385, 386, 387, 389, 296, 220, 314, 0, + 0, 1397, 0, 504, 0, 0, 0, 223, 0, 503, + 0, 0, 0, 272, 0, 0, 1398, 328, 0, 176, + 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, + 256, 287, 326, 384, 320, 547, 276, 0, 0, 375, + 299, 0, 0, 0, 0, 0, 538, 539, 0, 0, + 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, + 376, 237, 71, 0, 0, 167, 168, 169, 525, 524, + 527, 528, 529, 530, 0, 0, 198, 526, 205, 531, + 532, 533, 0, 219, 260, 225, 218, 391, 0, 0, + 0, 0, 0, 501, 518, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 515, 516, 594, 0, 0, 0, 562, 0, 517, - 0, 0, 510, 511, 513, 512, 514, 519, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, - 0, 561, 0, 0, 423, 0, 0, 559, 0, 0, - 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, - 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, - 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, - 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, - 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, - 267, 371, 243, 174, 275, 432, 186, 361, 202, 179, - 383, 404, 199, 364, 0, 0, 0, 181, 402, 380, - 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, - 399, 400, 211, 437, 190, 419, 183, 0, 418, 306, - 395, 403, 295, 286, 182, 401, 293, 285, 270, 231, - 251, 339, 280, 340, 252, 302, 301, 303, 0, 177, - 0, 377, 412, 438, 195, 196, 197, 0, 230, 234, - 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, - 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, - 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, - 354, 200, 410, 374, 549, 560, 555, 556, 553, 554, - 548, 552, 551, 550, 563, 540, 541, 542, 543, 545, - 0, 557, 558, 544, 170, 184, 274, 0, 343, 238, - 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 515, 516, 594, 0, + 0, 0, 562, 0, 517, 0, 0, 510, 511, 513, + 512, 514, 519, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 245, 0, 300, 0, 561, 0, 0, 423, + 0, 0, 559, 0, 0, 0, 0, 0, 271, 0, + 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, + 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, + 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, + 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, + 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, + 432, 186, 361, 202, 179, 383, 404, 199, 364, 0, + 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, + 345, 221, 241, 212, 313, 399, 400, 211, 437, 190, + 419, 183, 0, 418, 306, 395, 403, 295, 286, 182, + 401, 293, 285, 270, 231, 251, 339, 280, 340, 252, + 302, 301, 303, 0, 177, 0, 377, 412, 438, 195, + 196, 197, 0, 230, 234, 240, 242, 0, 248, 255, + 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, + 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, + 269, 278, 0, 0, 323, 354, 200, 410, 374, 549, + 560, 555, 556, 553, 554, 548, 552, 551, 550, 563, + 540, 541, 542, 543, 545, 0, 557, 558, 544, 170, + 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, + 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, - 185, 193, 203, 215, 228, 236, 246, 250, 253, 257, - 258, 261, 266, 283, 288, 289, 290, 291, 307, 308, - 309, 312, 315, 316, 319, 321, 322, 325, 331, 332, - 333, 334, 335, 337, 344, 348, 356, 357, 358, 359, - 360, 362, 363, 367, 368, 369, 370, 378, 382, 397, - 398, 409, 421, 426, 247, 405, 427, 0, 282, 0, - 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, - 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, - 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, - 387, 389, 296, 220, 314, 0, 0, 0, 0, 504, - 0, 0, 0, 223, 0, 503, 0, 0, 0, 272, - 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, - 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, - 320, 547, 276, 0, 0, 375, 299, 0, 0, 0, - 0, 0, 538, 539, 0, 0, 0, 0, 0, 0, - 1509, 0, 262, 207, 175, 311, 376, 237, 71, 0, - 0, 167, 168, 169, 525, 524, 527, 528, 529, 530, - 0, 0, 198, 526, 205, 531, 532, 533, 1510, 219, - 260, 225, 218, 391, 0, 0, 0, 0, 0, 501, - 518, 0, 546, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 515, 516, 0, 0, 0, 0, 562, 0, - 517, 0, 0, 510, 511, 513, 512, 514, 519, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, - 300, 0, 561, 0, 0, 423, 0, 0, 559, 0, - 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, - 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, - 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, - 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, - 420, 435, 188, 214, 318, 381, 411, 372, 297, 392, - 393, 267, 371, 243, 174, 275, 432, 186, 361, 202, - 179, 383, 404, 199, 364, 0, 0, 0, 181, 402, - 380, 294, 264, 265, 180, 0, 345, 221, 241, 212, - 313, 399, 400, 211, 437, 190, 419, 183, 0, 418, - 306, 395, 403, 295, 286, 182, 401, 293, 285, 270, - 231, 251, 339, 280, 340, 252, 302, 301, 303, 0, - 177, 0, 377, 412, 438, 195, 196, 197, 0, 230, - 234, 240, 242, 0, 248, 255, 273, 317, 338, 336, - 342, 0, 390, 407, 415, 422, 428, 429, 433, 430, - 431, 434, 305, 191, 254, 373, 269, 278, 0, 0, - 323, 354, 200, 410, 374, 549, 560, 555, 556, 553, - 554, 548, 552, 551, 550, 563, 540, 541, 542, 543, - 545, 0, 557, 558, 544, 170, 184, 274, 0, 343, - 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, + 0, 0, 0, 172, 173, 185, 193, 203, 215, 228, + 236, 246, 250, 253, 257, 258, 261, 266, 283, 288, + 289, 290, 291, 307, 308, 309, 312, 315, 316, 319, + 321, 322, 325, 331, 332, 333, 334, 335, 337, 344, + 348, 356, 357, 358, 359, 360, 362, 363, 367, 368, + 369, 370, 378, 382, 397, 398, 409, 421, 426, 247, + 405, 427, 0, 282, 0, 0, 284, 232, 249, 259, + 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, + 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, + 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, + 0, 0, 0, 0, 504, 0, 0, 0, 223, 0, + 503, 0, 0, 0, 272, 0, 0, 0, 328, 0, + 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, + 208, 256, 287, 326, 384, 320, 547, 276, 0, 0, + 375, 299, 0, 0, 0, 0, 0, 538, 539, 0, + 0, 0, 0, 0, 0, 1508, 0, 262, 207, 175, + 311, 376, 237, 71, 0, 0, 167, 168, 169, 525, + 524, 527, 528, 529, 530, 0, 0, 198, 526, 205, + 531, 532, 533, 1509, 219, 260, 225, 218, 391, 0, + 0, 0, 0, 0, 501, 518, 0, 546, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 515, 516, 0, + 0, 0, 0, 562, 0, 517, 0, 0, 510, 511, + 513, 512, 514, 519, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 245, 0, 300, 0, 561, 0, 0, + 423, 0, 0, 559, 0, 0, 0, 0, 0, 271, + 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, + 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, + 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, + 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, + 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, + 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, + 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, + 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, + 190, 419, 183, 0, 418, 306, 395, 403, 295, 286, + 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, + 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, + 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, + 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, + 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, + 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, + 549, 560, 555, 556, 553, 554, 548, 552, 551, 550, + 563, 540, 541, 542, 543, 545, 0, 557, 558, 544, + 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, + 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, - 173, 185, 193, 203, 215, 228, 236, 246, 250, 253, - 257, 258, 261, 266, 283, 288, 289, 290, 291, 307, - 308, 309, 312, 315, 316, 319, 321, 322, 325, 331, - 332, 333, 334, 335, 337, 344, 348, 356, 357, 358, - 359, 360, 362, 363, 367, 368, 369, 370, 378, 382, - 397, 398, 409, 421, 426, 247, 405, 427, 0, 282, - 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, - 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, - 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, - 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, - 504, 0, 0, 0, 223, 0, 503, 0, 0, 0, - 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, - 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, - 384, 320, 547, 276, 0, 0, 375, 299, 0, 0, - 0, 0, 0, 538, 539, 0, 0, 0, 0, 0, - 0, 0, 0, 262, 207, 175, 311, 376, 237, 71, - 0, 581, 167, 168, 169, 525, 524, 527, 528, 529, - 530, 0, 0, 198, 526, 205, 531, 532, 533, 0, - 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, - 501, 518, 0, 546, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, + 228, 236, 246, 250, 253, 257, 258, 261, 266, 283, + 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, + 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, + 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, + 368, 369, 370, 378, 382, 397, 398, 409, 421, 426, + 247, 405, 427, 0, 282, 0, 0, 284, 232, 249, + 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, + 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, + 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, + 314, 0, 0, 0, 0, 504, 0, 0, 0, 223, + 0, 503, 0, 0, 0, 272, 0, 0, 0, 328, + 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, + 222, 208, 256, 287, 326, 384, 320, 547, 276, 0, + 0, 375, 299, 0, 0, 0, 0, 0, 538, 539, + 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, + 175, 311, 376, 237, 71, 0, 581, 167, 168, 169, + 525, 524, 527, 528, 529, 530, 0, 0, 198, 526, + 205, 531, 532, 533, 0, 219, 260, 225, 218, 391, + 0, 0, 0, 0, 0, 501, 518, 0, 546, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 515, 516, + 0, 0, 0, 0, 562, 0, 517, 0, 0, 510, + 511, 513, 512, 514, 519, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 0, 300, 0, 561, 0, + 0, 423, 0, 0, 559, 0, 0, 0, 0, 0, + 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, + 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, + 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, + 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, + 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, + 174, 275, 432, 186, 361, 202, 179, 383, 404, 199, + 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, + 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, + 437, 190, 419, 183, 0, 418, 306, 395, 403, 295, + 286, 182, 401, 293, 285, 270, 231, 251, 339, 280, + 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, + 438, 195, 196, 197, 0, 230, 234, 240, 242, 0, + 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, + 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, + 254, 373, 269, 278, 0, 0, 323, 354, 200, 410, + 374, 549, 560, 555, 556, 553, 554, 548, 552, 551, + 550, 563, 540, 541, 542, 543, 545, 0, 557, 558, + 544, 170, 184, 274, 0, 343, 238, 436, 417, 413, + 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 515, 516, 0, 0, 0, 0, 562, - 0, 517, 0, 0, 510, 511, 513, 512, 514, 519, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, - 0, 300, 0, 561, 0, 0, 423, 0, 0, 559, - 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, - 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, - 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, - 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, - 388, 420, 435, 188, 214, 318, 381, 411, 372, 297, - 392, 393, 267, 371, 243, 174, 275, 432, 186, 361, - 202, 179, 383, 404, 199, 364, 0, 0, 0, 181, - 402, 380, 294, 264, 265, 180, 0, 345, 221, 241, - 212, 313, 399, 400, 211, 437, 190, 419, 183, 0, - 418, 306, 395, 403, 295, 286, 182, 401, 293, 285, - 270, 231, 251, 339, 280, 340, 252, 302, 301, 303, - 0, 177, 0, 377, 412, 438, 195, 196, 197, 0, - 230, 234, 240, 242, 0, 248, 255, 273, 317, 338, - 336, 342, 0, 390, 407, 415, 422, 428, 429, 433, - 430, 431, 434, 305, 191, 254, 373, 269, 278, 0, - 0, 323, 354, 200, 410, 374, 549, 560, 555, 556, - 553, 554, 548, 552, 551, 550, 563, 540, 541, 542, - 543, 545, 0, 557, 558, 544, 170, 184, 274, 0, - 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 185, 193, 203, + 215, 228, 236, 246, 250, 253, 257, 258, 261, 266, + 283, 288, 289, 290, 291, 307, 308, 309, 312, 315, + 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, + 337, 344, 348, 356, 357, 358, 359, 360, 362, 363, + 367, 368, 369, 370, 378, 382, 397, 398, 409, 421, + 426, 247, 405, 427, 0, 282, 0, 0, 284, 232, + 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, + 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, + 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, + 220, 314, 0, 0, 0, 0, 504, 0, 0, 0, + 223, 0, 503, 0, 0, 0, 272, 0, 0, 0, + 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, + 226, 222, 208, 256, 287, 326, 384, 320, 547, 276, + 0, 0, 375, 299, 0, 0, 0, 0, 0, 538, + 539, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 207, 175, 311, 376, 237, 71, 0, 0, 167, 168, + 169, 525, 524, 527, 528, 529, 530, 0, 0, 198, + 526, 205, 531, 532, 533, 0, 219, 260, 225, 218, + 391, 0, 0, 0, 0, 0, 501, 518, 0, 546, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 515, + 516, 594, 0, 0, 0, 562, 0, 517, 0, 0, + 510, 511, 513, 512, 514, 519, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 245, 0, 300, 0, 561, + 0, 0, 423, 0, 0, 559, 0, 0, 0, 0, + 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, + 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, + 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, + 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, + 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, + 243, 174, 275, 432, 186, 361, 202, 179, 383, 404, + 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, + 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, + 211, 437, 190, 419, 183, 0, 418, 306, 395, 403, + 295, 286, 182, 401, 293, 285, 270, 231, 251, 339, + 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, + 412, 438, 195, 196, 197, 0, 230, 234, 240, 242, + 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, + 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, + 191, 254, 373, 269, 278, 0, 0, 323, 354, 200, + 410, 374, 549, 560, 555, 556, 553, 554, 548, 552, + 551, 550, 563, 540, 541, 542, 543, 545, 0, 557, + 558, 544, 170, 184, 274, 0, 343, 238, 436, 417, + 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 185, 193, + 203, 215, 228, 236, 246, 250, 253, 257, 258, 261, + 266, 283, 288, 289, 290, 291, 307, 308, 309, 312, + 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, + 335, 337, 344, 348, 356, 357, 358, 359, 360, 362, + 363, 367, 368, 369, 370, 378, 382, 397, 398, 409, + 421, 426, 247, 405, 427, 0, 282, 0, 0, 284, + 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, + 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, + 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, + 296, 220, 314, 0, 0, 0, 0, 504, 0, 0, + 0, 223, 0, 503, 0, 0, 0, 272, 0, 0, + 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, + 233, 226, 222, 208, 256, 287, 326, 384, 320, 547, + 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, + 538, 539, 0, 0, 0, 0, 0, 0, 0, 0, + 262, 207, 175, 311, 376, 237, 71, 0, 0, 167, + 168, 169, 525, 1415, 527, 528, 529, 530, 0, 0, + 198, 526, 205, 531, 532, 533, 0, 219, 260, 225, + 218, 391, 0, 0, 0, 0, 0, 501, 518, 0, + 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 172, 173, 185, 193, 203, 215, 228, 236, 246, 250, - 253, 257, 258, 261, 266, 283, 288, 289, 290, 291, - 307, 308, 309, 312, 315, 316, 319, 321, 322, 325, - 331, 332, 333, 334, 335, 337, 344, 348, 356, 357, - 358, 359, 360, 362, 363, 367, 368, 369, 370, 378, - 382, 397, 398, 409, 421, 426, 247, 405, 427, 0, - 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, - 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, - 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, - 385, 386, 387, 389, 296, 220, 314, 0, 0, 0, - 0, 504, 0, 0, 0, 223, 0, 503, 0, 0, - 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, - 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, - 326, 384, 320, 547, 276, 0, 0, 375, 299, 0, - 0, 0, 0, 0, 538, 539, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, - 71, 0, 0, 167, 168, 169, 525, 524, 527, 528, - 529, 530, 0, 0, 198, 526, 205, 531, 532, 533, - 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, - 0, 501, 518, 0, 546, 0, 0, 0, 0, 0, + 515, 516, 594, 0, 0, 0, 562, 0, 517, 0, + 0, 510, 511, 513, 512, 514, 519, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, + 561, 0, 0, 423, 0, 0, 559, 0, 0, 0, + 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, + 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, + 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, + 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, + 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, + 371, 243, 174, 275, 432, 186, 361, 202, 179, 383, + 404, 199, 364, 0, 0, 0, 181, 402, 380, 294, + 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, + 400, 211, 437, 190, 419, 183, 0, 418, 306, 395, + 403, 295, 286, 182, 401, 293, 285, 270, 231, 251, + 339, 280, 340, 252, 302, 301, 303, 0, 177, 0, + 377, 412, 438, 195, 196, 197, 0, 230, 234, 240, + 242, 0, 248, 255, 273, 317, 338, 336, 342, 0, + 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, + 305, 191, 254, 373, 269, 278, 0, 0, 323, 354, + 200, 410, 374, 549, 560, 555, 556, 553, 554, 548, + 552, 551, 550, 563, 540, 541, 542, 543, 545, 0, + 557, 558, 544, 170, 184, 274, 0, 343, 238, 436, + 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 515, 516, 594, 0, 0, 0, - 562, 0, 517, 0, 0, 510, 511, 513, 512, 514, - 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 245, 0, 300, 0, 561, 0, 0, 423, 0, 0, - 559, 0, 0, 0, 0, 0, 271, 0, 268, 171, - 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, - 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, - 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, - 414, 388, 420, 435, 188, 214, 318, 381, 411, 372, - 297, 392, 393, 267, 371, 243, 174, 275, 432, 186, - 361, 202, 179, 383, 404, 199, 364, 0, 0, 0, - 181, 402, 380, 294, 264, 265, 180, 0, 345, 221, - 241, 212, 313, 399, 400, 211, 437, 190, 419, 183, - 0, 418, 306, 395, 403, 295, 286, 182, 401, 293, - 285, 270, 231, 251, 339, 280, 340, 252, 302, 301, - 303, 0, 177, 0, 377, 412, 438, 195, 196, 197, - 0, 230, 234, 240, 242, 0, 248, 255, 273, 317, - 338, 336, 342, 0, 390, 407, 415, 422, 428, 429, - 433, 430, 431, 434, 305, 191, 254, 373, 269, 278, - 0, 0, 323, 354, 200, 410, 374, 549, 560, 555, - 556, 553, 554, 548, 552, 551, 550, 563, 540, 541, - 542, 543, 545, 0, 557, 558, 544, 170, 184, 274, - 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, + 0, 0, 0, 0, 0, 0, 0, 172, 173, 185, + 193, 203, 215, 228, 236, 246, 250, 253, 257, 258, + 261, 266, 283, 288, 289, 290, 291, 307, 308, 309, + 312, 315, 316, 319, 321, 322, 325, 331, 332, 333, + 334, 335, 337, 344, 348, 356, 357, 358, 359, 360, + 362, 363, 367, 368, 369, 370, 378, 382, 397, 398, + 409, 421, 426, 247, 405, 427, 0, 282, 0, 0, + 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, + 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, + 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, + 389, 296, 220, 314, 0, 0, 0, 0, 504, 0, + 0, 0, 223, 0, 503, 0, 0, 0, 272, 0, + 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, + 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, + 547, 276, 0, 0, 375, 299, 0, 0, 0, 0, + 0, 538, 539, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 207, 175, 311, 376, 237, 71, 0, 0, + 167, 168, 169, 525, 1412, 527, 528, 529, 530, 0, + 0, 198, 526, 205, 531, 532, 533, 0, 219, 260, + 225, 218, 391, 0, 0, 0, 0, 0, 501, 518, + 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 515, 516, 594, 0, 0, 0, 562, 0, 517, + 0, 0, 510, 511, 513, 512, 514, 519, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, + 0, 561, 0, 0, 423, 0, 0, 559, 0, 0, + 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, + 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, + 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, + 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, + 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, + 267, 371, 243, 174, 275, 432, 186, 361, 202, 179, + 383, 404, 199, 364, 0, 0, 0, 181, 402, 380, + 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, + 399, 400, 211, 437, 190, 419, 183, 0, 418, 306, + 395, 403, 295, 286, 182, 401, 293, 285, 270, 231, + 251, 339, 280, 340, 252, 302, 301, 303, 0, 177, + 0, 377, 412, 438, 195, 196, 197, 0, 230, 234, + 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, + 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, + 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, + 354, 200, 410, 374, 549, 560, 555, 556, 553, 554, + 548, 552, 551, 550, 563, 540, 541, 542, 543, 545, + 0, 557, 558, 544, 170, 184, 274, 0, 343, 238, + 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 172, 173, 185, 193, 203, 215, 228, 236, 246, - 250, 253, 257, 258, 261, 266, 283, 288, 289, 290, - 291, 307, 308, 309, 312, 315, 316, 319, 321, 322, - 325, 331, 332, 333, 334, 335, 337, 344, 348, 356, - 357, 358, 359, 360, 362, 363, 367, 368, 369, 370, - 378, 382, 397, 398, 409, 421, 426, 247, 405, 427, - 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, - 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, - 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, - 365, 385, 386, 387, 389, 296, 220, 314, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 185, 193, 203, 215, 228, 236, 246, 250, 253, 257, + 258, 261, 266, 283, 288, 289, 290, 291, 307, 308, + 309, 312, 315, 316, 319, 321, 322, 325, 331, 332, + 333, 334, 335, 337, 344, 348, 356, 357, 358, 359, + 360, 362, 363, 367, 368, 369, 370, 378, 382, 397, + 398, 409, 421, 426, 247, 405, 427, 0, 282, 0, + 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, + 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, + 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, + 387, 389, 296, 220, 574, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 504, 0, 0, 0, 223, 0, 503, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 547, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 538, 539, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, - 237, 71, 0, 0, 167, 168, 169, 525, 1414, 527, + 237, 71, 0, 0, 167, 168, 169, 525, 524, 527, 528, 529, 530, 0, 0, 198, 526, 205, 531, 532, 533, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 501, 518, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 515, 516, 594, 0, 0, + 0, 0, 0, 0, 0, 515, 516, 0, 0, 0, 0, 562, 0, 517, 0, 0, 510, 511, 513, 512, 514, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, 561, 0, 0, 423, 0, @@ -2318,12 +2361,12 @@ var yyAct = [...]int{ 256, 287, 326, 384, 320, 547, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 538, 539, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, - 376, 237, 71, 0, 0, 167, 168, 169, 525, 1411, + 376, 237, 71, 0, 0, 167, 168, 169, 525, 524, 527, 528, 529, 530, 0, 0, 198, 526, 205, 531, 532, 533, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 501, 518, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 515, 516, 594, 0, + 0, 0, 0, 0, 0, 0, 515, 516, 0, 0, 0, 0, 562, 0, 517, 0, 0, 510, 511, 513, 512, 514, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, 561, 0, 0, 423, @@ -2357,24 +2400,161 @@ var yyAct = [...]int{ 405, 427, 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, - 347, 201, 365, 385, 386, 387, 389, 296, 220, 574, + 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, + 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, + 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, + 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, + 208, 256, 287, 326, 384, 320, 547, 276, 0, 0, + 375, 299, 0, 0, 0, 0, 0, 538, 539, 0, + 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, + 311, 376, 237, 71, 0, 0, 167, 168, 169, 525, + 524, 527, 528, 529, 530, 0, 0, 198, 526, 205, + 531, 532, 533, 0, 219, 260, 225, 218, 391, 0, + 0, 0, 0, 0, 0, 518, 0, 546, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 515, 516, 0, + 0, 0, 0, 562, 0, 517, 0, 0, 510, 511, + 513, 512, 514, 519, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 245, 0, 300, 0, 561, 0, 0, + 423, 0, 0, 559, 0, 0, 0, 0, 0, 271, + 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, + 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, + 329, 351, 2233, 0, 352, 277, 396, 341, 406, 424, + 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, + 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, + 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, + 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, + 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, + 190, 419, 183, 0, 418, 306, 395, 403, 295, 286, + 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, + 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, + 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, + 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, + 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, + 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, + 549, 560, 555, 556, 553, 554, 548, 552, 551, 550, + 563, 540, 541, 542, 543, 545, 0, 557, 558, 544, + 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, + 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 314, 0, 0, 0, 0, 504, 0, 0, - 0, 223, 0, 503, 0, 0, 0, 272, 0, 0, + 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, + 228, 236, 246, 250, 253, 257, 258, 261, 266, 283, + 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, + 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, + 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, + 368, 369, 370, 378, 382, 397, 398, 409, 421, 426, + 247, 405, 427, 0, 282, 0, 0, 284, 232, 249, + 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, + 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, + 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, + 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, + 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, + 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, + 222, 208, 256, 287, 326, 384, 320, 547, 276, 0, + 0, 375, 299, 0, 0, 0, 0, 0, 538, 539, + 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, + 175, 311, 376, 237, 71, 0, 581, 167, 168, 169, + 525, 524, 527, 528, 529, 530, 0, 0, 198, 526, + 205, 531, 532, 533, 0, 219, 260, 225, 218, 391, + 0, 0, 0, 0, 0, 0, 518, 0, 546, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 515, 516, + 0, 0, 0, 0, 562, 0, 517, 0, 0, 510, + 511, 513, 512, 514, 519, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 0, 300, 0, 561, 0, + 0, 423, 0, 0, 559, 0, 0, 0, 0, 0, + 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, + 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, + 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, + 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, + 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, + 174, 275, 432, 186, 361, 202, 179, 383, 404, 199, + 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, + 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, + 437, 190, 419, 183, 0, 418, 306, 395, 403, 295, + 286, 182, 401, 293, 285, 270, 231, 251, 339, 280, + 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, + 438, 195, 196, 197, 0, 230, 234, 240, 242, 0, + 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, + 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, + 254, 373, 269, 278, 0, 0, 323, 354, 200, 410, + 374, 549, 560, 555, 556, 553, 554, 548, 552, 551, + 550, 563, 540, 541, 542, 543, 545, 0, 557, 558, + 544, 170, 184, 274, 0, 343, 238, 436, 417, 413, + 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 185, 193, 203, + 215, 228, 236, 246, 250, 253, 257, 258, 261, 266, + 283, 288, 289, 290, 291, 307, 308, 309, 312, 315, + 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, + 337, 344, 348, 356, 357, 358, 359, 360, 362, 363, + 367, 368, 369, 370, 378, 382, 397, 398, 409, 421, + 426, 247, 405, 427, 0, 282, 0, 0, 284, 232, + 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, + 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, + 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, + 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, + 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, + 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, + 226, 222, 208, 256, 287, 326, 384, 320, 547, 276, + 0, 0, 375, 299, 0, 0, 0, 0, 0, 538, + 539, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 207, 175, 311, 376, 237, 71, 0, 0, 167, 168, + 169, 525, 524, 527, 528, 529, 530, 0, 0, 198, + 526, 205, 531, 532, 533, 0, 219, 260, 225, 218, + 391, 0, 0, 0, 0, 0, 0, 518, 0, 546, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 515, + 516, 0, 0, 0, 0, 562, 0, 517, 0, 0, + 510, 511, 513, 512, 514, 519, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 245, 0, 300, 0, 561, + 0, 0, 423, 0, 0, 559, 0, 0, 0, 0, + 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, + 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, + 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, + 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, + 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, + 243, 174, 275, 432, 186, 361, 202, 179, 383, 404, + 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, + 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, + 211, 437, 190, 419, 183, 0, 418, 306, 395, 403, + 295, 286, 182, 401, 293, 285, 270, 231, 251, 339, + 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, + 412, 438, 195, 196, 197, 0, 230, 234, 240, 242, + 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, + 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, + 191, 254, 373, 269, 278, 0, 0, 323, 354, 200, + 410, 374, 549, 560, 555, 556, 553, 554, 548, 552, + 551, 550, 563, 540, 541, 542, 543, 545, 0, 557, + 558, 544, 170, 184, 274, 0, 343, 238, 436, 417, + 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 185, 193, + 203, 215, 228, 236, 246, 250, 253, 257, 258, 261, + 266, 283, 288, 289, 290, 291, 307, 308, 309, 312, + 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, + 335, 337, 344, 348, 356, 357, 358, 359, 360, 362, + 363, 367, 368, 369, 370, 378, 382, 397, 398, 409, + 421, 426, 247, 405, 427, 0, 282, 0, 0, 284, + 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, + 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, + 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, + 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, + 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, - 233, 226, 222, 208, 256, 287, 326, 384, 320, 547, + 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, - 538, 539, 0, 0, 0, 0, 0, 0, 0, 0, - 262, 207, 175, 311, 376, 237, 71, 0, 0, 167, - 168, 169, 525, 524, 527, 528, 529, 530, 0, 0, - 198, 526, 205, 531, 532, 533, 0, 219, 260, 225, - 218, 391, 0, 0, 0, 0, 0, 501, 518, 0, - 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 515, 516, 0, 0, 0, 0, 562, 0, 517, 0, - 0, 510, 511, 513, 512, 514, 519, 0, 0, 0, + 262, 207, 175, 311, 376, 237, 0, 0, 0, 167, + 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, + 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 971, 970, 980, 981, + 973, 974, 975, 976, 977, 978, 979, 972, 0, 0, + 982, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, - 561, 0, 0, 423, 0, 0, 559, 0, 0, 0, + 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, @@ -2390,9 +2570,9 @@ var yyAct = [...]int{ 242, 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, 354, - 200, 410, 374, 549, 560, 555, 556, 553, 554, 548, - 552, 551, 550, 563, 540, 541, 542, 543, 545, 0, - 557, 558, 544, 170, 184, 274, 0, 343, 238, 436, + 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, 185, @@ -2405,23 +2585,23 @@ var yyAct = [...]int{ 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, - 389, 296, 220, 314, 0, 0, 0, 0, 504, 0, - 0, 0, 223, 0, 503, 0, 0, 0, 272, 0, + 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, + 0, 0, 223, 800, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, - 547, 276, 0, 0, 375, 299, 0, 0, 0, 0, - 0, 538, 539, 0, 0, 0, 0, 0, 0, 0, - 0, 262, 207, 175, 311, 376, 237, 71, 0, 0, - 167, 168, 169, 525, 524, 527, 528, 529, 530, 0, - 0, 198, 526, 205, 531, 532, 533, 0, 219, 260, - 225, 218, 391, 0, 0, 0, 0, 0, 501, 518, - 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 207, 175, 311, 376, 237, 0, 0, 0, + 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, + 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 515, 516, 0, 0, 0, 0, 562, 0, 517, - 0, 0, 510, 511, 513, 512, 514, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, - 0, 561, 0, 0, 423, 0, 0, 559, 0, 0, - 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, + 0, 0, 0, 799, 423, 0, 0, 0, 0, 0, + 0, 796, 797, 271, 762, 268, 171, 187, 790, 794, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, @@ -2434,11 +2614,11 @@ var yyAct = [...]int{ 251, 339, 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, - 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, - 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, - 354, 200, 410, 374, 549, 560, 555, 556, 553, 554, - 548, 552, 551, 550, 563, 540, 541, 542, 543, 545, - 0, 557, 558, 544, 170, 184, 274, 0, 343, 238, + 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, + 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, + 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, @@ -2451,25 +2631,25 @@ var yyAct = [...]int{ 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, - 387, 389, 296, 220, 314, 0, 0, 0, 0, 0, + 387, 389, 296, 220, 314, 0, 0, 0, 1074, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, - 320, 547, 276, 0, 0, 375, 299, 0, 0, 0, - 0, 0, 538, 539, 0, 0, 0, 0, 0, 0, - 0, 0, 262, 207, 175, 311, 376, 237, 71, 0, - 0, 167, 168, 169, 525, 524, 527, 528, 529, 530, - 0, 0, 198, 526, 205, 531, 532, 533, 0, 219, - 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, - 518, 0, 546, 0, 0, 0, 0, 0, 0, 0, + 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 262, 207, 175, 311, 376, 237, 0, 0, + 0, 167, 168, 169, 0, 1076, 0, 0, 0, 0, + 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, + 260, 225, 218, 391, 0, 0, 960, 961, 959, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 962, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 515, 516, 0, 0, 0, 0, 562, 0, - 517, 0, 0, 510, 511, 513, 512, 514, 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, - 300, 0, 561, 0, 0, 423, 0, 0, 559, 0, + 300, 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, - 324, 408, 194, 235, 346, 329, 351, 2234, 0, 352, + 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, 186, 361, 202, @@ -2482,9 +2662,9 @@ var yyAct = [...]int{ 234, 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, 269, 278, 0, 0, - 323, 354, 200, 410, 374, 549, 560, 555, 556, 553, - 554, 548, 552, 551, 550, 563, 540, 541, 542, 543, - 545, 0, 557, 558, 544, 170, 184, 274, 0, 343, + 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, @@ -2497,69 +2677,256 @@ var yyAct = [...]int{ 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, - 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, - 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, - 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, - 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, - 384, 320, 547, 276, 0, 0, 375, 299, 0, 0, - 0, 0, 0, 538, 539, 0, 0, 0, 0, 0, - 0, 0, 0, 262, 207, 175, 311, 376, 237, 71, - 0, 581, 167, 168, 169, 525, 524, 527, 528, 529, - 530, 0, 0, 198, 526, 205, 531, 532, 533, 0, - 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, - 0, 518, 0, 546, 0, 0, 0, 0, 0, 0, + 386, 387, 389, 296, 220, 35, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 314, 0, + 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, + 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, + 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, + 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, + 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, + 376, 237, 71, 0, 581, 167, 168, 169, 0, 0, + 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, + 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 515, 516, 0, 0, 0, 0, 562, - 0, 517, 0, 0, 510, 511, 513, 512, 514, 519, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, - 0, 300, 0, 561, 0, 0, 423, 0, 0, 559, - 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, - 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, - 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, - 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, - 388, 420, 435, 188, 214, 318, 381, 411, 372, 297, - 392, 393, 267, 371, 243, 174, 275, 432, 186, 361, - 202, 179, 383, 404, 199, 364, 0, 0, 0, 181, - 402, 380, 294, 264, 265, 180, 0, 345, 221, 241, - 212, 313, 399, 400, 211, 437, 190, 419, 183, 0, - 418, 306, 395, 403, 295, 286, 182, 401, 293, 285, - 270, 231, 251, 339, 280, 340, 252, 302, 301, 303, - 0, 177, 0, 377, 412, 438, 195, 196, 197, 0, - 230, 234, 240, 242, 0, 248, 255, 273, 317, 338, - 336, 342, 0, 390, 407, 415, 422, 428, 429, 433, - 430, 431, 434, 305, 191, 254, 373, 269, 278, 0, - 0, 323, 354, 200, 410, 374, 549, 560, 555, 556, - 553, 554, 548, 552, 551, 550, 563, 540, 541, 542, - 543, 545, 0, 557, 558, 544, 170, 184, 274, 0, - 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 172, 173, 185, 193, 203, 215, 228, 236, 246, 250, - 253, 257, 258, 261, 266, 283, 288, 289, 290, 291, - 307, 308, 309, 312, 315, 316, 319, 321, 322, 325, - 331, 332, 333, 334, 335, 337, 344, 348, 356, 357, - 358, 359, 360, 362, 363, 367, 368, 369, 370, 378, - 382, 397, 398, 409, 421, 426, 247, 405, 427, 0, - 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, - 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, - 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, - 385, 386, 387, 389, 296, 220, 314, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, + 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, + 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, + 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, + 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, + 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, + 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, + 432, 186, 361, 202, 179, 383, 404, 199, 364, 0, + 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, + 345, 221, 241, 212, 313, 399, 400, 211, 437, 190, + 419, 183, 0, 418, 306, 395, 403, 295, 286, 182, + 401, 293, 285, 270, 231, 251, 339, 280, 340, 252, + 302, 301, 303, 0, 177, 0, 377, 412, 438, 195, + 196, 197, 0, 230, 234, 240, 242, 0, 248, 255, + 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, + 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, + 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, + 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, + 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 172, 173, 185, 193, 203, 215, 228, + 236, 246, 250, 253, 257, 258, 261, 266, 283, 288, + 289, 290, 291, 307, 308, 309, 312, 315, 316, 319, + 321, 322, 325, 331, 332, 333, 334, 335, 337, 344, + 348, 356, 357, 358, 359, 360, 362, 363, 367, 368, + 369, 370, 378, 382, 397, 398, 409, 421, 426, 247, + 405, 427, 0, 282, 0, 0, 284, 232, 249, 259, + 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, + 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, + 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, + 0, 0, 0, 1442, 0, 0, 0, 0, 223, 0, + 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, + 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, + 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, + 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, + 311, 376, 237, 0, 0, 0, 167, 168, 169, 0, + 1257, 0, 0, 0, 0, 0, 0, 198, 0, 205, + 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 245, 0, 300, 0, 0, 0, 0, + 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, + 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, + 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, + 329, 351, 0, 1440, 352, 277, 396, 341, 406, 424, + 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, + 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, + 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, + 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, + 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, + 190, 419, 183, 0, 418, 306, 395, 403, 295, 286, + 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, + 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, + 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, + 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, + 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, + 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, + 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, + 228, 236, 246, 250, 253, 257, 258, 261, 266, 283, + 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, + 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, + 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, + 368, 369, 370, 378, 382, 397, 398, 409, 421, 426, + 247, 405, 427, 0, 282, 0, 0, 284, 232, 249, + 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, + 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, + 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, + 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, + 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, + 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, + 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, + 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, + 175, 311, 376, 237, 0, 0, 0, 167, 168, 169, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, + 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 756, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 0, 300, 0, 0, 0, + 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, + 271, 762, 268, 171, 187, 760, 0, 310, 349, 355, + 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, + 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, + 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, + 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, + 174, 275, 432, 186, 361, 202, 179, 383, 404, 199, + 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, + 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, + 437, 190, 419, 183, 0, 418, 306, 395, 403, 295, + 286, 182, 401, 293, 285, 270, 231, 251, 339, 280, + 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, + 438, 195, 196, 197, 0, 230, 234, 240, 242, 0, + 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, + 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, + 254, 373, 269, 278, 0, 0, 323, 354, 200, 410, + 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, + 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 185, 193, 203, + 215, 228, 236, 246, 250, 253, 257, 258, 261, 266, + 283, 288, 289, 290, 291, 307, 308, 309, 312, 315, + 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, + 337, 344, 348, 356, 357, 358, 359, 360, 362, 363, + 367, 368, 369, 370, 378, 382, 397, 398, 409, 421, + 426, 247, 405, 427, 0, 282, 0, 0, 284, 232, + 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, + 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, + 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, + 220, 314, 0, 0, 0, 1442, 0, 0, 0, 0, + 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, + 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, + 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, + 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 207, 175, 311, 376, 237, 0, 0, 0, 167, 168, + 169, 0, 1257, 0, 0, 0, 0, 0, 0, 198, + 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, + 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 245, 0, 300, 0, 0, + 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, + 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, + 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, + 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, + 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, + 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, + 243, 174, 275, 432, 186, 361, 202, 179, 383, 404, + 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, + 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, + 211, 437, 190, 419, 183, 0, 418, 306, 395, 403, + 295, 286, 182, 401, 293, 285, 270, 231, 251, 339, + 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, + 412, 438, 195, 196, 197, 0, 230, 234, 240, 242, + 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, + 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, + 191, 254, 373, 269, 278, 0, 0, 323, 354, 200, + 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, + 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 185, 193, + 203, 215, 228, 236, 246, 250, 253, 257, 258, 261, + 266, 283, 288, 289, 290, 291, 307, 308, 309, 312, + 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, + 335, 337, 344, 348, 356, 357, 358, 359, 360, 362, + 363, 367, 368, 369, 370, 378, 382, 397, 398, 409, + 421, 426, 247, 405, 427, 0, 282, 0, 0, 284, + 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, + 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, + 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, + 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, + 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, + 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, + 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, + 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 262, 207, 175, 311, 376, 237, 0, 0, 581, 167, + 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, + 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, + 0, 0, 0, 423, 0, 0, 0, 0, 2123, 0, + 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, + 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, + 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, + 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, + 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, + 371, 243, 174, 275, 432, 186, 361, 202, 179, 383, + 404, 199, 364, 0, 0, 0, 181, 402, 380, 294, + 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, + 400, 211, 437, 190, 419, 183, 0, 418, 306, 395, + 403, 295, 286, 182, 401, 293, 285, 270, 231, 251, + 339, 280, 340, 252, 302, 301, 303, 0, 177, 0, + 377, 412, 438, 195, 196, 197, 0, 230, 234, 240, + 242, 0, 248, 255, 273, 317, 338, 336, 342, 0, + 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, + 305, 191, 254, 373, 269, 278, 0, 0, 323, 354, + 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 170, 184, 274, 0, 343, 238, 436, + 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 172, 173, 185, + 193, 203, 215, 228, 236, 246, 250, 253, 257, 258, + 261, 266, 283, 288, 289, 290, 291, 307, 308, 309, + 312, 315, 316, 319, 321, 322, 325, 331, 332, 333, + 334, 335, 337, 344, 348, 356, 357, 358, 359, 360, + 362, 363, 367, 368, 369, 370, 378, 382, 397, 398, + 409, 421, 426, 247, 405, 427, 0, 282, 0, 0, + 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, + 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, + 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, + 389, 296, 220, 35, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, - 326, 384, 320, 547, 276, 0, 0, 375, 299, 0, - 0, 0, 0, 0, 538, 539, 0, 0, 0, 0, + 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, - 71, 0, 0, 167, 168, 169, 525, 524, 527, 528, - 529, 530, 0, 0, 198, 526, 205, 531, 532, 533, + 71, 0, 0, 167, 168, 169, 0, 0, 0, 0, + 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, - 0, 0, 518, 0, 546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 515, 516, 0, 0, 0, 0, - 562, 0, 517, 0, 0, 510, 511, 513, 512, 514, - 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 245, 0, 300, 0, 561, 0, 0, 423, 0, 0, - 559, 0, 0, 0, 0, 0, 271, 0, 268, 171, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, + 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, @@ -2574,9 +2941,9 @@ var yyAct = [...]int{ 0, 230, 234, 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, 269, 278, - 0, 0, 323, 354, 200, 410, 374, 549, 560, 555, - 556, 553, 554, 548, 552, 551, 550, 563, 540, 541, - 542, 543, 545, 0, 557, 558, 544, 170, 184, 274, + 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2596,13 +2963,13 @@ var yyAct = [...]int{ 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, - 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, + 237, 0, 0, 0, 167, 168, 169, 0, 0, 1461, + 0, 0, 1462, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 971, 970, 980, 981, 973, 974, 975, 976, 977, - 978, 979, 972, 0, 0, 982, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, @@ -2636,13 +3003,13 @@ var yyAct = [...]int{ 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, 0, - 0, 0, 0, 0, 0, 0, 0, 223, 800, 0, + 0, 0, 0, 0, 0, 0, 0, 223, 0, 1107, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, - 376, 237, 0, 0, 0, 167, 168, 169, 0, 0, + 376, 237, 0, 0, 0, 167, 168, 169, 0, 1106, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2650,9 +3017,9 @@ 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, 245, 0, 300, 0, 0, 0, 799, 423, - 0, 0, 0, 0, 0, 0, 796, 797, 271, 762, - 268, 171, 187, 790, 794, 310, 349, 355, 0, 0, + 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, + 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, + 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, @@ -2682,286 +3049,99 @@ var yyAct = [...]int{ 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, - 0, 0, 0, 1074, 0, 0, 0, 0, 223, 0, - 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, - 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, - 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, - 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, - 311, 376, 237, 0, 0, 0, 167, 168, 169, 0, - 1076, 0, 0, 0, 0, 0, 0, 198, 0, 205, - 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, - 0, 960, 961, 959, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 962, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 245, 0, 300, 0, 0, 0, 0, - 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, - 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, - 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, - 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, - 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, - 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, - 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, - 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, - 190, 419, 183, 0, 418, 306, 395, 403, 295, 286, - 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, - 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, - 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, - 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, - 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, - 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, - 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, - 228, 236, 246, 250, 253, 257, 258, 261, 266, 283, - 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, - 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, - 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, - 368, 369, 370, 378, 382, 397, 398, 409, 421, 426, - 247, 405, 427, 0, 282, 0, 0, 284, 232, 249, - 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, - 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, - 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, - 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 314, 0, 0, 0, 0, 0, 0, - 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, - 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, - 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, - 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 262, 207, 175, 311, 376, 237, 71, 0, 581, - 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, - 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, - 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, - 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, - 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, - 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, - 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, - 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, - 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, - 267, 371, 243, 174, 275, 432, 186, 361, 202, 179, - 383, 404, 199, 364, 0, 0, 0, 181, 402, 380, - 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, - 399, 400, 211, 437, 190, 419, 183, 0, 418, 306, - 395, 403, 295, 286, 182, 401, 293, 285, 270, 231, - 251, 339, 280, 340, 252, 302, 301, 303, 0, 177, - 0, 377, 412, 438, 195, 196, 197, 0, 230, 234, - 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, - 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, - 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, - 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 170, 184, 274, 0, 343, 238, - 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, - 185, 193, 203, 215, 228, 236, 246, 250, 253, 257, - 258, 261, 266, 283, 288, 289, 290, 291, 307, 308, - 309, 312, 315, 316, 319, 321, 322, 325, 331, 332, - 333, 334, 335, 337, 344, 348, 356, 357, 358, 359, - 360, 362, 363, 367, 368, 369, 370, 378, 382, 397, - 398, 409, 421, 426, 247, 405, 427, 0, 282, 0, - 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, - 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, - 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, - 387, 389, 296, 220, 314, 0, 0, 0, 1441, 0, - 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, - 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, - 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, - 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 262, 207, 175, 311, 376, 237, 0, 0, - 0, 167, 168, 169, 0, 1443, 0, 0, 0, 0, - 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, - 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, - 300, 0, 0, 0, 0, 423, 0, 0, 0, 0, - 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, - 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, - 324, 408, 194, 235, 346, 329, 351, 0, 1439, 352, - 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, - 420, 435, 188, 214, 318, 381, 411, 372, 297, 392, - 393, 267, 371, 243, 174, 275, 432, 186, 361, 202, - 179, 383, 404, 199, 364, 0, 0, 0, 181, 402, - 380, 294, 264, 265, 180, 0, 345, 221, 241, 212, - 313, 399, 400, 211, 437, 190, 419, 183, 0, 418, - 306, 395, 403, 295, 286, 182, 401, 293, 285, 270, - 231, 251, 339, 280, 340, 252, 302, 301, 303, 0, - 177, 0, 377, 412, 438, 195, 196, 197, 0, 230, - 234, 240, 242, 0, 248, 255, 273, 317, 338, 336, - 342, 0, 390, 407, 415, 422, 428, 429, 433, 430, - 431, 434, 305, 191, 254, 373, 269, 278, 0, 0, - 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 170, 184, 274, 0, 343, - 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, - 173, 185, 193, 203, 215, 228, 236, 246, 250, 253, - 257, 258, 261, 266, 283, 288, 289, 290, 291, 307, - 308, 309, 312, 315, 316, 319, 321, 322, 325, 331, - 332, 333, 334, 335, 337, 344, 348, 356, 357, 358, - 359, 360, 362, 363, 367, 368, 369, 370, 378, 382, - 397, 398, 409, 421, 426, 247, 405, 427, 0, 282, - 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, - 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, - 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, - 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, - 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, - 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, - 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, - 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 262, 207, 175, 311, 376, 237, 0, - 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, - 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, - 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 756, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, - 0, 300, 0, 0, 0, 0, 423, 0, 0, 0, - 0, 0, 0, 0, 0, 271, 762, 268, 171, 187, - 760, 0, 310, 349, 355, 0, 0, 0, 210, 0, - 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, - 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, - 388, 420, 435, 188, 214, 318, 381, 411, 372, 297, - 392, 393, 267, 371, 243, 174, 275, 432, 186, 361, - 202, 179, 383, 404, 199, 364, 0, 0, 0, 181, - 402, 380, 294, 264, 265, 180, 0, 345, 221, 241, - 212, 313, 399, 400, 211, 437, 190, 419, 183, 0, - 418, 306, 395, 403, 295, 286, 182, 401, 293, 285, - 270, 231, 251, 339, 280, 340, 252, 302, 301, 303, - 0, 177, 0, 377, 412, 438, 195, 196, 197, 0, - 230, 234, 240, 242, 0, 248, 255, 273, 317, 338, - 336, 342, 0, 390, 407, 415, 422, 428, 429, 433, - 430, 431, 434, 305, 191, 254, 373, 269, 278, 0, - 0, 323, 354, 200, 410, 374, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 170, 184, 274, 0, - 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 172, 173, 185, 193, 203, 215, 228, 236, 246, 250, - 253, 257, 258, 261, 266, 283, 288, 289, 290, 291, - 307, 308, 309, 312, 315, 316, 319, 321, 322, 325, - 331, 332, 333, 334, 335, 337, 344, 348, 356, 357, - 358, 359, 360, 362, 363, 367, 368, 369, 370, 378, - 382, 397, 398, 409, 421, 426, 247, 405, 427, 0, - 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, - 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, - 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, - 385, 386, 387, 389, 296, 220, 314, 0, 0, 0, - 1441, 0, 0, 0, 0, 223, 0, 0, 0, 0, - 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, - 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, - 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, - 0, 0, 0, 167, 168, 169, 0, 1443, 0, 0, - 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, - 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, - 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, - 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, - 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, - 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, - 414, 388, 420, 435, 188, 214, 318, 381, 411, 372, - 297, 392, 393, 267, 371, 243, 174, 275, 432, 186, - 361, 202, 179, 383, 404, 199, 364, 0, 0, 0, - 181, 402, 380, 294, 264, 265, 180, 0, 345, 221, - 241, 212, 313, 399, 400, 211, 437, 190, 419, 183, - 0, 418, 306, 395, 403, 295, 286, 182, 401, 293, - 285, 270, 231, 251, 339, 280, 340, 252, 302, 301, - 303, 0, 177, 0, 377, 412, 438, 195, 196, 197, - 0, 230, 234, 240, 242, 0, 248, 255, 273, 317, - 338, 336, 342, 0, 390, 407, 415, 422, 428, 429, - 433, 430, 431, 434, 305, 191, 254, 373, 269, 278, - 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 170, 184, 274, - 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 172, 173, 185, 193, 203, 215, 228, 236, 246, - 250, 253, 257, 258, 261, 266, 283, 288, 289, 290, - 291, 307, 308, 309, 312, 315, 316, 319, 321, 322, - 325, 331, 332, 333, 334, 335, 337, 344, 348, 356, - 357, 358, 359, 360, 362, 363, 367, 368, 369, 370, - 378, 382, 397, 398, 409, 421, 426, 247, 405, 427, - 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, - 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, - 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, - 365, 385, 386, 387, 389, 296, 220, 314, 0, 0, - 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, - 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, - 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, - 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, + 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, + 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, + 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, + 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, + 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, + 311, 376, 237, 0, 0, 0, 167, 168, 169, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, + 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, - 237, 0, 0, 581, 167, 168, 169, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, - 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 245, 0, 300, 0, 0, 0, 0, + 423, 0, 0, 0, 0, 2206, 0, 0, 0, 271, + 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, + 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, + 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, + 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, + 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, + 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, + 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, + 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, + 190, 419, 183, 0, 418, 306, 395, 403, 295, 286, + 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, + 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, + 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, + 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, + 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, + 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, - 0, 0, 0, 2124, 0, 0, 0, 271, 0, 268, - 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, - 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, - 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, - 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, - 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, - 186, 361, 202, 179, 383, 404, 199, 364, 0, 0, - 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, - 221, 241, 212, 313, 399, 400, 211, 437, 190, 419, - 183, 0, 418, 306, 395, 403, 295, 286, 182, 401, - 293, 285, 270, 231, 251, 339, 280, 340, 252, 302, - 301, 303, 0, 177, 0, 377, 412, 438, 195, 196, - 197, 0, 230, 234, 240, 242, 0, 248, 255, 273, - 317, 338, 336, 342, 0, 390, 407, 415, 422, 428, - 429, 433, 430, 431, 434, 305, 191, 254, 373, 269, - 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 170, 184, - 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, + 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, + 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, + 228, 236, 246, 250, 253, 257, 258, 261, 266, 283, + 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, + 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, + 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, + 368, 369, 370, 378, 382, 397, 398, 409, 421, 426, + 247, 405, 427, 0, 282, 0, 0, 284, 232, 249, + 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, + 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, + 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, + 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, + 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, + 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, + 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, + 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, + 175, 311, 376, 237, 0, 0, 0, 167, 168, 169, + 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, + 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 173, 185, 193, 203, 215, 228, 236, - 246, 250, 253, 257, 258, 261, 266, 283, 288, 289, - 290, 291, 307, 308, 309, 312, 315, 316, 319, 321, - 322, 325, 331, 332, 333, 334, 335, 337, 344, 348, - 356, 357, 358, 359, 360, 362, 363, 367, 368, 369, - 370, 378, 382, 397, 398, 409, 421, 426, 247, 405, - 427, 0, 282, 0, 0, 284, 232, 249, 259, 0, - 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, - 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, - 201, 365, 385, 386, 387, 389, 296, 220, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 245, 0, 300, 0, 0, 0, + 0, 423, 0, 0, 0, 0, 2123, 0, 0, 0, + 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, + 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, + 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, + 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, + 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, + 174, 275, 432, 186, 361, 202, 179, 383, 404, 199, + 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, + 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, + 437, 190, 419, 183, 0, 418, 306, 395, 403, 295, + 286, 182, 401, 293, 285, 270, 231, 251, 339, 280, + 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, + 438, 195, 196, 197, 0, 230, 234, 240, 242, 0, + 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, + 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, + 254, 373, 269, 278, 0, 0, 323, 354, 200, 410, + 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, + 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 185, 193, 203, + 215, 228, 236, 246, 250, 253, 257, 258, 261, 266, + 283, 288, 289, 290, 291, 307, 308, 309, 312, 315, + 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, + 337, 344, 348, 356, 357, 358, 359, 360, 362, 363, + 367, 368, 369, 370, 378, 382, 397, 398, 409, 421, + 426, 247, 405, 427, 0, 282, 0, 0, 284, 232, + 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, + 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, + 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, + 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, @@ -3014,7 +3194,7 @@ var yyAct = [...]int{ 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, 0, 0, 0, 167, - 168, 169, 0, 0, 1462, 0, 0, 1463, 0, 0, + 168, 169, 0, 1257, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3054,13 +3234,13 @@ var yyAct = [...]int{ 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, - 0, 0, 223, 0, 1107, 0, 0, 0, 272, 0, + 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, 0, 0, 0, - 167, 168, 169, 0, 1106, 0, 0, 0, 0, 0, + 167, 168, 169, 0, 1076, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3115,7 +3295,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, 0, 0, - 2207, 0, 0, 0, 271, 0, 268, 171, 187, 0, + 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, 388, @@ -3132,7 +3312,7 @@ var yyAct = [...]int{ 431, 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 170, 184, 274, 0, 343, + 0, 0, 0, 0, 0, 170, 184, 274, 1347, 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, @@ -3145,7 +3325,7 @@ var yyAct = [...]int{ 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, - 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, + 386, 387, 389, 296, 220, 314, 0, 1229, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, @@ -3161,7 +3341,7 @@ var yyAct = [...]int{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, 0, - 0, 2124, 0, 0, 0, 271, 0, 268, 171, 187, + 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, 414, @@ -3191,14 +3371,14 @@ var yyAct = [...]int{ 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, - 385, 386, 387, 389, 296, 220, 314, 0, 0, 0, + 385, 386, 387, 389, 296, 220, 314, 0, 1227, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, - 71, 0, 0, 167, 168, 169, 0, 0, 0, 0, + 0, 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3237,14 +3417,14 @@ var yyAct = [...]int{ 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, - 365, 385, 386, 387, 389, 296, 220, 314, 0, 0, + 365, 385, 386, 387, 389, 296, 220, 314, 0, 1225, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, - 237, 0, 0, 0, 167, 168, 169, 0, 1443, 0, + 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3284,13 +3464,13 @@ var yyAct = [...]int{ 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, 0, - 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, + 1223, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, - 376, 237, 0, 0, 0, 167, 168, 169, 0, 1076, + 376, 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3330,7 +3510,7 @@ var yyAct = [...]int{ 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, - 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, + 0, 1221, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, @@ -3363,7 +3543,7 @@ var yyAct = [...]int{ 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 170, 184, 274, 1346, 343, 238, 436, 417, 413, 0, + 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, @@ -3376,7 +3556,7 @@ var yyAct = [...]int{ 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, - 314, 0, 1229, 0, 0, 0, 0, 0, 0, 223, + 314, 0, 1217, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, @@ -3422,7 +3602,146 @@ var yyAct = [...]int{ 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, - 220, 314, 0, 1227, 0, 0, 0, 0, 0, 0, + 220, 314, 0, 1215, 0, 0, 0, 0, 0, 0, + 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, + 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, + 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, + 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, + 207, 175, 311, 376, 237, 0, 0, 0, 167, 168, + 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, + 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, + 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 245, 0, 300, 0, 0, + 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, + 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, + 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, + 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, + 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, + 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, + 243, 174, 275, 432, 186, 361, 202, 179, 383, 404, + 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, + 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, + 211, 437, 190, 419, 183, 0, 418, 306, 395, 403, + 295, 286, 182, 401, 293, 285, 270, 231, 251, 339, + 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, + 412, 438, 195, 196, 197, 0, 230, 234, 240, 242, + 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, + 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, + 191, 254, 373, 269, 278, 0, 0, 323, 354, 200, + 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, + 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 185, 193, + 203, 215, 228, 236, 246, 250, 253, 257, 258, 261, + 266, 283, 288, 289, 290, 291, 307, 308, 309, 312, + 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, + 335, 337, 344, 348, 356, 357, 358, 359, 360, 362, + 363, 367, 368, 369, 370, 378, 382, 397, 398, 409, + 421, 426, 247, 405, 427, 0, 282, 0, 0, 284, + 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, + 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, + 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, + 296, 220, 314, 0, 1213, 0, 0, 0, 0, 0, + 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, + 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, + 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, + 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 262, 207, 175, 311, 376, 237, 0, 0, 0, 167, + 168, 169, 0, 0, 0, 0, 0, 0, 0, 0, + 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, + 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 245, 0, 300, 0, + 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, + 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, + 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, + 194, 235, 346, 329, 351, 0, 0, 352, 277, 396, + 341, 406, 424, 425, 217, 304, 414, 388, 420, 435, + 188, 214, 318, 381, 411, 372, 297, 392, 393, 267, + 371, 243, 174, 275, 432, 186, 361, 202, 179, 383, + 404, 199, 364, 0, 0, 0, 181, 402, 380, 294, + 264, 265, 180, 0, 345, 221, 241, 212, 313, 399, + 400, 211, 437, 190, 419, 183, 0, 418, 306, 395, + 403, 295, 286, 182, 401, 293, 285, 270, 231, 251, + 339, 280, 340, 252, 302, 301, 303, 0, 177, 0, + 377, 412, 438, 195, 196, 197, 0, 230, 234, 240, + 242, 0, 248, 255, 273, 317, 338, 336, 342, 0, + 390, 407, 415, 422, 428, 429, 433, 430, 431, 434, + 305, 191, 254, 373, 269, 278, 0, 0, 323, 354, + 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 170, 184, 274, 0, 343, 238, 436, + 417, 413, 0, 0, 216, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 172, 173, 185, + 193, 203, 215, 228, 236, 246, 250, 253, 257, 258, + 261, 266, 283, 288, 289, 290, 291, 307, 308, 309, + 312, 315, 316, 319, 321, 322, 325, 331, 332, 333, + 334, 335, 337, 344, 348, 356, 357, 358, 359, 360, + 362, 363, 367, 368, 369, 370, 378, 382, 397, 398, + 409, 421, 426, 247, 405, 427, 0, 282, 0, 0, + 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, + 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, + 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, + 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, + 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, + 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, + 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, + 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 262, 207, 175, 311, 376, 237, 1188, 0, 0, + 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, + 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, + 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 245, 0, 300, + 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, + 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, + 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, + 408, 194, 235, 346, 329, 351, 0, 0, 352, 277, + 396, 341, 406, 424, 425, 217, 304, 414, 388, 420, + 435, 188, 214, 318, 381, 411, 372, 297, 392, 393, + 267, 371, 243, 174, 275, 432, 186, 361, 202, 179, + 383, 404, 199, 364, 0, 0, 0, 181, 402, 380, + 294, 264, 265, 180, 0, 345, 221, 241, 212, 313, + 399, 400, 211, 437, 190, 419, 183, 0, 418, 306, + 395, 403, 295, 286, 182, 401, 293, 285, 270, 231, + 251, 339, 280, 340, 252, 302, 301, 303, 0, 177, + 0, 377, 412, 438, 195, 196, 197, 0, 230, 234, + 240, 242, 0, 248, 255, 273, 317, 338, 336, 342, + 0, 390, 407, 415, 422, 428, 429, 433, 430, 431, + 434, 305, 191, 254, 373, 269, 278, 0, 0, 323, + 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 170, 184, 274, 0, 343, 238, + 436, 417, 413, 0, 0, 216, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 185, 193, 203, 215, 228, 236, 246, 250, 253, 257, + 258, 261, 266, 283, 288, 289, 290, 291, 307, 308, + 309, 312, 315, 316, 319, 321, 322, 325, 331, 332, + 333, 334, 335, 337, 344, 348, 356, 357, 358, 359, + 360, 362, 363, 367, 368, 369, 370, 378, 382, 397, + 398, 409, 421, 426, 247, 405, 427, 0, 282, 0, + 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, + 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, + 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, + 387, 389, 296, 220, 1089, 0, 0, 0, 0, 0, + 0, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, @@ -3468,8 +3787,8 @@ var yyAct = [...]int{ 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, - 296, 220, 314, 0, 1225, 0, 0, 0, 0, 0, - 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, + 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, + 1080, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, @@ -3514,14 +3833,14 @@ var yyAct = [...]int{ 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, 387, - 389, 296, 220, 314, 0, 1223, 0, 0, 0, 0, + 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, 0, 0, 0, - 167, 168, 169, 0, 0, 0, 0, 0, 0, 0, + 167, 168, 169, 0, 936, 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3560,7 +3879,7 @@ var yyAct = [...]int{ 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, 386, - 387, 389, 296, 220, 314, 0, 1221, 0, 0, 0, + 387, 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, 384, @@ -3574,7 +3893,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, 0, 0, 0, 245, 0, + 0, 0, 0, 0, 0, 0, 492, 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, @@ -3602,11 +3921,11 @@ var yyAct = [...]int{ 308, 309, 312, 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, 368, 369, 370, 378, 382, - 397, 398, 409, 421, 426, 247, 405, 427, 0, 282, + 397, 398, 409, 421, 426, 491, 405, 427, 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, 385, - 386, 387, 389, 296, 220, 314, 0, 1217, 0, 0, + 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, 326, @@ -3621,7 +3940,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, 245, - 0, 300, 0, 0, 0, 0, 423, 0, 0, 0, + 0, 300, 0, 0, 441, 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, 0, @@ -3652,146 +3971,7 @@ var yyAct = [...]int{ 282, 0, 0, 284, 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, 365, - 385, 386, 387, 389, 296, 220, 314, 0, 1215, 0, - 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, - 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, - 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, - 326, 384, 320, 0, 276, 0, 0, 375, 299, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 262, 207, 175, 311, 376, 237, - 0, 0, 0, 167, 168, 169, 0, 0, 0, 0, - 0, 0, 0, 0, 198, 0, 205, 0, 0, 0, - 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 245, 0, 300, 0, 0, 0, 0, 423, 0, 0, - 0, 0, 0, 0, 0, 0, 271, 0, 268, 171, - 187, 0, 0, 310, 349, 355, 0, 0, 0, 210, - 0, 353, 324, 408, 194, 235, 346, 329, 351, 0, - 0, 352, 277, 396, 341, 406, 424, 425, 217, 304, - 414, 388, 420, 435, 188, 214, 318, 381, 411, 372, - 297, 392, 393, 267, 371, 243, 174, 275, 432, 186, - 361, 202, 179, 383, 404, 199, 364, 0, 0, 0, - 181, 402, 380, 294, 264, 265, 180, 0, 345, 221, - 241, 212, 313, 399, 400, 211, 437, 190, 419, 183, - 0, 418, 306, 395, 403, 295, 286, 182, 401, 293, - 285, 270, 231, 251, 339, 280, 340, 252, 302, 301, - 303, 0, 177, 0, 377, 412, 438, 195, 196, 197, - 0, 230, 234, 240, 242, 0, 248, 255, 273, 317, - 338, 336, 342, 0, 390, 407, 415, 422, 428, 429, - 433, 430, 431, 434, 305, 191, 254, 373, 269, 278, - 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 170, 184, 274, - 0, 343, 238, 436, 417, 413, 0, 0, 216, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 172, 173, 185, 193, 203, 215, 228, 236, 246, - 250, 253, 257, 258, 261, 266, 283, 288, 289, 290, - 291, 307, 308, 309, 312, 315, 316, 319, 321, 322, - 325, 331, 332, 333, 334, 335, 337, 344, 348, 356, - 357, 358, 359, 360, 362, 363, 367, 368, 369, 370, - 378, 382, 397, 398, 409, 421, 426, 247, 405, 427, - 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, - 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, - 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, - 365, 385, 386, 387, 389, 296, 220, 314, 0, 1213, - 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, - 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, - 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, - 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, - 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, - 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, - 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, - 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, - 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, - 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, - 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, - 186, 361, 202, 179, 383, 404, 199, 364, 0, 0, - 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, - 221, 241, 212, 313, 399, 400, 211, 437, 190, 419, - 183, 0, 418, 306, 395, 403, 295, 286, 182, 401, - 293, 285, 270, 231, 251, 339, 280, 340, 252, 302, - 301, 303, 0, 177, 0, 377, 412, 438, 195, 196, - 197, 0, 230, 234, 240, 242, 0, 248, 255, 273, - 317, 338, 336, 342, 0, 390, 407, 415, 422, 428, - 429, 433, 430, 431, 434, 305, 191, 254, 373, 269, - 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 170, 184, - 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 173, 185, 193, 203, 215, 228, 236, - 246, 250, 253, 257, 258, 261, 266, 283, 288, 289, - 290, 291, 307, 308, 309, 312, 315, 316, 319, 321, - 322, 325, 331, 332, 333, 334, 335, 337, 344, 348, - 356, 357, 358, 359, 360, 362, 363, 367, 368, 369, - 370, 378, 382, 397, 398, 409, 421, 426, 247, 405, - 427, 0, 282, 0, 0, 284, 232, 249, 259, 0, - 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, - 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, - 201, 365, 385, 386, 387, 389, 296, 220, 314, 0, - 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, - 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, - 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, - 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, - 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, - 376, 237, 1188, 0, 0, 167, 168, 169, 0, 0, - 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, - 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, - 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, - 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, - 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, - 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, - 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, - 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, - 432, 186, 361, 202, 179, 383, 404, 199, 364, 0, - 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, - 345, 221, 241, 212, 313, 399, 400, 211, 437, 190, - 419, 183, 0, 418, 306, 395, 403, 295, 286, 182, - 401, 293, 285, 270, 231, 251, 339, 280, 340, 252, - 302, 301, 303, 0, 177, 0, 377, 412, 438, 195, - 196, 197, 0, 230, 234, 240, 242, 0, 248, 255, - 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, - 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, - 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, - 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, - 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 172, 173, 185, 193, 203, 215, 228, - 236, 246, 250, 253, 257, 258, 261, 266, 283, 288, - 289, 290, 291, 307, 308, 309, 312, 315, 316, 319, - 321, 322, 325, 331, 332, 333, 334, 335, 337, 344, - 348, 356, 357, 358, 359, 360, 362, 363, 367, 368, - 369, 370, 378, 382, 397, 398, 409, 421, 426, 247, - 405, 427, 0, 282, 0, 0, 284, 232, 249, 259, - 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, - 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, - 347, 201, 365, 385, 386, 387, 389, 296, 220, 1089, - 0, 0, 0, 0, 0, 0, 314, 0, 0, 0, + 385, 386, 387, 389, 296, 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, 287, @@ -3832,263 +4012,80 @@ var yyAct = [...]int{ 250, 253, 257, 258, 261, 266, 283, 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, 344, 348, 356, - 357, 358, 359, 360, 362, 363, 367, 368, 369, 370, - 378, 382, 397, 398, 409, 421, 426, 247, 405, 427, - 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, - 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, - 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, - 365, 385, 386, 387, 389, 296, 220, 314, 0, 0, - 0, 0, 0, 0, 0, 1080, 223, 0, 0, 0, - 0, 0, 272, 0, 0, 0, 328, 0, 176, 0, - 366, 209, 281, 279, 394, 233, 226, 222, 208, 256, - 287, 326, 384, 320, 0, 276, 0, 0, 375, 299, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 262, 207, 175, 311, 376, - 237, 0, 0, 0, 167, 168, 169, 0, 0, 0, - 0, 0, 0, 0, 0, 198, 0, 205, 0, 0, - 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 245, 0, 300, 0, 0, 0, 0, 423, 0, - 0, 0, 0, 0, 0, 0, 0, 271, 0, 268, - 171, 187, 0, 0, 310, 349, 355, 0, 0, 0, - 210, 0, 353, 324, 408, 194, 235, 346, 329, 351, - 0, 0, 352, 277, 396, 341, 406, 424, 425, 217, - 304, 414, 388, 420, 435, 188, 214, 318, 381, 411, - 372, 297, 392, 393, 267, 371, 243, 174, 275, 432, - 186, 361, 202, 179, 383, 404, 199, 364, 0, 0, - 0, 181, 402, 380, 294, 264, 265, 180, 0, 345, - 221, 241, 212, 313, 399, 400, 211, 437, 190, 419, - 183, 0, 418, 306, 395, 403, 295, 286, 182, 401, - 293, 285, 270, 231, 251, 339, 280, 340, 252, 302, - 301, 303, 0, 177, 0, 377, 412, 438, 195, 196, - 197, 0, 230, 234, 240, 242, 0, 248, 255, 273, - 317, 338, 336, 342, 0, 390, 407, 415, 422, 428, - 429, 433, 430, 431, 434, 305, 191, 254, 373, 269, - 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 170, 184, - 274, 0, 343, 238, 436, 417, 413, 0, 0, 216, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 172, 173, 185, 193, 203, 215, 228, 236, - 246, 250, 253, 257, 258, 261, 266, 283, 288, 289, - 290, 291, 307, 308, 309, 312, 315, 316, 319, 321, - 322, 325, 331, 332, 333, 334, 335, 337, 344, 348, - 356, 357, 358, 359, 360, 362, 363, 367, 368, 369, - 370, 378, 382, 397, 398, 409, 421, 426, 247, 405, - 427, 0, 282, 0, 0, 284, 232, 249, 259, 0, - 416, 379, 189, 350, 239, 178, 206, 192, 213, 227, - 229, 263, 292, 298, 327, 330, 244, 224, 204, 347, - 201, 365, 385, 386, 387, 389, 296, 220, 314, 0, - 0, 0, 0, 0, 0, 0, 0, 223, 0, 0, - 0, 0, 0, 272, 0, 0, 0, 328, 0, 176, - 0, 366, 209, 281, 279, 394, 233, 226, 222, 208, - 256, 287, 326, 384, 320, 0, 276, 0, 0, 375, - 299, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 262, 207, 175, 311, - 376, 237, 0, 0, 0, 167, 168, 169, 0, 936, - 0, 0, 0, 0, 0, 0, 198, 0, 205, 0, - 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 245, 0, 300, 0, 0, 0, 0, 423, - 0, 0, 0, 0, 0, 0, 0, 0, 271, 0, - 268, 171, 187, 0, 0, 310, 349, 355, 0, 0, - 0, 210, 0, 353, 324, 408, 194, 235, 346, 329, - 351, 0, 0, 352, 277, 396, 341, 406, 424, 425, - 217, 304, 414, 388, 420, 435, 188, 214, 318, 381, - 411, 372, 297, 392, 393, 267, 371, 243, 174, 275, - 432, 186, 361, 202, 179, 383, 404, 199, 364, 0, - 0, 0, 181, 402, 380, 294, 264, 265, 180, 0, - 345, 221, 241, 212, 313, 399, 400, 211, 437, 190, - 419, 183, 0, 418, 306, 395, 403, 295, 286, 182, - 401, 293, 285, 270, 231, 251, 339, 280, 340, 252, - 302, 301, 303, 0, 177, 0, 377, 412, 438, 195, - 196, 197, 0, 230, 234, 240, 242, 0, 248, 255, - 273, 317, 338, 336, 342, 0, 390, 407, 415, 422, - 428, 429, 433, 430, 431, 434, 305, 191, 254, 373, - 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, - 184, 274, 0, 343, 238, 436, 417, 413, 0, 0, - 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 172, 173, 185, 193, 203, 215, 228, - 236, 246, 250, 253, 257, 258, 261, 266, 283, 288, - 289, 290, 291, 307, 308, 309, 312, 315, 316, 319, - 321, 322, 325, 331, 332, 333, 334, 335, 337, 344, - 348, 356, 357, 358, 359, 360, 362, 363, 367, 368, - 369, 370, 378, 382, 397, 398, 409, 421, 426, 247, - 405, 427, 0, 282, 0, 0, 284, 232, 249, 259, - 0, 416, 379, 189, 350, 239, 178, 206, 192, 213, - 227, 229, 263, 292, 298, 327, 330, 244, 224, 204, - 347, 201, 365, 385, 386, 387, 389, 296, 220, 314, - 0, 0, 0, 0, 0, 0, 0, 0, 223, 0, - 0, 0, 0, 0, 272, 0, 0, 0, 328, 0, - 176, 0, 366, 209, 281, 279, 394, 233, 226, 222, - 208, 256, 287, 326, 384, 320, 0, 276, 0, 0, - 375, 299, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 262, 207, 175, - 311, 376, 237, 0, 0, 0, 167, 168, 169, 0, - 0, 0, 0, 0, 0, 0, 0, 198, 0, 205, - 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, + 357, 358, 359, 360, 362, 363, 367, 368, 369, 370, + 378, 382, 397, 398, 409, 421, 426, 247, 405, 427, + 0, 282, 0, 0, 284, 232, 249, 259, 0, 416, + 379, 189, 350, 239, 178, 206, 192, 213, 227, 229, + 263, 292, 298, 327, 330, 244, 224, 204, 347, 201, + 365, 385, 386, 387, 389, 296, 220, 161, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1181, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 103, 0, 125, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, + 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 142, + 0, 143, 0, 0, 0, 0, 1185, 1186, 134, 133, + 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 492, 0, 245, 0, 300, 0, 0, 0, 0, - 423, 0, 0, 0, 0, 0, 0, 0, 0, 271, - 0, 268, 171, 187, 0, 0, 310, 349, 355, 0, - 0, 0, 210, 0, 353, 324, 408, 194, 235, 346, - 329, 351, 0, 0, 352, 277, 396, 341, 406, 424, - 425, 217, 304, 414, 388, 420, 435, 188, 214, 318, - 381, 411, 372, 297, 392, 393, 267, 371, 243, 174, - 275, 432, 186, 361, 202, 179, 383, 404, 199, 364, - 0, 0, 0, 181, 402, 380, 294, 264, 265, 180, - 0, 345, 221, 241, 212, 313, 399, 400, 211, 437, - 190, 419, 183, 0, 418, 306, 395, 403, 295, 286, - 182, 401, 293, 285, 270, 231, 251, 339, 280, 340, - 252, 302, 301, 303, 0, 177, 0, 377, 412, 438, - 195, 196, 197, 0, 230, 234, 240, 242, 0, 248, - 255, 273, 317, 338, 336, 342, 0, 390, 407, 415, - 422, 428, 429, 433, 430, 431, 434, 305, 191, 254, - 373, 269, 278, 0, 0, 323, 354, 200, 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 170, 184, 274, 0, 343, 238, 436, 417, 413, 0, - 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, + 129, 1187, 136, 0, 1184, 0, 130, 131, 0, 0, + 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 172, 173, 185, 193, 203, 215, - 228, 236, 246, 250, 253, 257, 258, 261, 266, 283, - 288, 289, 290, 291, 307, 308, 309, 312, 315, 316, - 319, 321, 322, 325, 331, 332, 333, 334, 335, 337, - 344, 348, 356, 357, 358, 359, 360, 362, 363, 367, - 368, 369, 370, 378, 382, 397, 398, 409, 421, 426, - 491, 405, 427, 0, 282, 0, 0, 284, 232, 249, - 259, 0, 416, 379, 189, 350, 239, 178, 206, 192, - 213, 227, 229, 263, 292, 298, 327, 330, 244, 224, - 204, 347, 201, 365, 385, 386, 387, 389, 296, 220, - 314, 0, 0, 0, 0, 0, 0, 0, 0, 223, - 0, 0, 0, 0, 0, 272, 0, 0, 0, 328, - 0, 176, 0, 366, 209, 281, 279, 394, 233, 226, - 222, 208, 256, 287, 326, 384, 320, 0, 276, 0, - 0, 375, 299, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 262, 207, - 175, 311, 376, 237, 0, 0, 0, 167, 168, 169, - 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, - 205, 0, 0, 0, 0, 219, 260, 225, 218, 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 245, 0, 300, 0, 0, 441, - 0, 423, 0, 0, 0, 0, 0, 0, 0, 0, - 271, 0, 268, 171, 187, 0, 0, 310, 349, 355, - 0, 0, 0, 210, 0, 353, 324, 408, 194, 235, - 346, 329, 351, 0, 0, 352, 277, 396, 341, 406, - 424, 425, 217, 304, 414, 388, 420, 435, 188, 214, - 318, 381, 411, 372, 297, 392, 393, 267, 371, 243, - 174, 275, 432, 186, 361, 202, 179, 383, 404, 199, - 364, 0, 0, 0, 181, 402, 380, 294, 264, 265, - 180, 0, 345, 221, 241, 212, 313, 399, 400, 211, - 437, 190, 419, 183, 0, 418, 306, 395, 403, 295, - 286, 182, 401, 293, 285, 270, 231, 251, 339, 280, - 340, 252, 302, 301, 303, 0, 177, 0, 377, 412, - 438, 195, 196, 197, 0, 230, 234, 240, 242, 0, - 248, 255, 273, 317, 338, 336, 342, 0, 390, 407, - 415, 422, 428, 429, 433, 430, 431, 434, 305, 191, - 254, 373, 269, 278, 0, 0, 323, 354, 200, 410, - 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 170, 184, 274, 0, 343, 238, 436, 417, 413, - 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 172, 173, 185, 193, 203, - 215, 228, 236, 246, 250, 253, 257, 258, 261, 266, - 283, 288, 289, 290, 291, 307, 308, 309, 312, 315, - 316, 319, 321, 322, 325, 331, 332, 333, 334, 335, - 337, 344, 348, 356, 357, 358, 359, 360, 362, 363, - 367, 368, 369, 370, 378, 382, 397, 398, 409, 421, - 426, 247, 405, 427, 0, 282, 0, 0, 284, 232, - 249, 259, 0, 416, 379, 189, 350, 239, 178, 206, - 192, 213, 227, 229, 263, 292, 298, 327, 330, 244, - 224, 204, 347, 201, 365, 385, 386, 387, 389, 296, - 220, 314, 0, 0, 0, 0, 0, 0, 0, 0, - 223, 0, 0, 0, 0, 0, 272, 0, 0, 0, - 328, 0, 176, 0, 366, 209, 281, 279, 394, 233, - 226, 222, 208, 256, 287, 326, 384, 320, 0, 276, - 0, 0, 375, 299, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 262, - 207, 175, 311, 376, 237, 0, 0, 0, 167, 168, - 169, 0, 0, 0, 0, 0, 0, 0, 0, 198, - 0, 205, 0, 0, 0, 0, 219, 260, 225, 218, - 391, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 245, 0, 300, 0, 0, - 0, 0, 423, 0, 0, 0, 0, 0, 0, 0, - 0, 271, 0, 268, 171, 187, 0, 0, 310, 349, - 355, 0, 0, 0, 210, 0, 353, 324, 408, 194, - 235, 346, 329, 351, 0, 0, 352, 277, 396, 341, - 406, 424, 425, 217, 304, 414, 388, 420, 435, 188, - 214, 318, 381, 411, 372, 297, 392, 393, 267, 371, - 243, 174, 275, 432, 186, 361, 202, 179, 383, 404, - 199, 364, 0, 0, 0, 181, 402, 380, 294, 264, - 265, 180, 0, 345, 221, 241, 212, 313, 399, 400, - 211, 437, 190, 419, 183, 0, 418, 306, 395, 403, - 295, 286, 182, 401, 293, 285, 270, 231, 251, 339, - 280, 340, 252, 302, 301, 303, 0, 177, 0, 377, - 412, 438, 195, 196, 197, 0, 230, 234, 240, 242, - 0, 248, 255, 273, 317, 338, 336, 342, 0, 390, - 407, 415, 422, 428, 429, 433, 430, 431, 434, 305, - 191, 254, 373, 269, 278, 0, 0, 323, 354, 200, - 410, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 170, 184, 274, 0, 343, 238, 436, 417, - 413, 0, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 172, 173, 185, 193, - 203, 215, 228, 236, 246, 250, 253, 257, 258, 261, - 266, 283, 288, 289, 290, 291, 307, 308, 309, 312, - 315, 316, 319, 321, 322, 325, 331, 332, 333, 334, - 335, 337, 344, 348, 356, 357, 358, 359, 360, 362, - 363, 367, 368, 369, 370, 378, 382, 397, 398, 409, - 421, 426, 247, 405, 427, 0, 282, 0, 0, 284, - 232, 249, 259, 0, 416, 379, 189, 350, 239, 178, - 206, 192, 213, 227, 229, 263, 292, 298, 327, 330, - 244, 224, 204, 347, 201, 365, 385, 386, 387, 389, - 296, 220, + 0, 0, 0, 132, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 126, 0, 0, 127, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, + 144, 141, 147, 148, 149, 150, 152, 153, 154, 155, + 0, 0, 0, 0, 0, 156, 157, 158, 159, } var yyPact = [...]int{ - 4113, -1000, -340, 1608, -1000, -1000, -1000, -1000, -1000, -1000, + 4224, -1000, -346, 1644, -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, 1600, 1234, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 641, 1277, -1000, 1501, 3855, -1000, 28577, 410, + -1000, 28116, 407, 2220, 28577, -1000, 101, -1000, 90, 28577, + 100, 27655, -1000, -1000, -286, 12409, 1439, -13, -15, 28577, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1275, + 1576, 1585, 1598, 1098, 1517, -1000, 10552, 10552, 372, 372, + 372, 8708, -1000, -1000, 16571, 28577, 28577, 143, -1000, 1501, + -1000, -1000, 215, -1000, 287, 1228, -1000, 1227, -1000, 465, + 583, 284, 354, 352, 283, 282, 281, 280, 276, 273, + 267, 265, 291, -1000, 577, 577, -173, -176, 2607, 358, + 358, 358, 382, 1474, 1473, -1000, 533, -1000, 577, 577, + 183, 577, 577, 577, 577, 206, 204, 577, 577, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 208, 1501, 167, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 1572, 1232, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 560, 1253, -1000, 1479, 253, -1000, 29082, 394, - -1000, 28621, 391, 2045, 29082, -1000, 125, -1000, 111, 29082, - 115, 28160, -1000, -1000, -287, 12914, 1429, -13, -30, 29082, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1245, - 1518, 1526, 1570, 1075, 1490, -1000, 11057, 11057, 329, 329, - 329, 9213, -1000, -1000, 17076, 29082, 29082, 171, -1000, 1479, - -1000, -1000, 140, -1000, 245, 1185, -1000, 1181, -1000, 556, - 465, 241, 318, 317, 240, 236, 235, 234, 231, 228, - 227, 224, 254, -1000, 535, 535, -179, -183, 2370, 298, - 298, 298, 364, 1450, 1449, -1000, 487, -1000, 535, 535, - 137, 535, 535, 535, 535, 190, 188, 535, 535, 535, - 535, 535, 535, 535, 535, 535, 535, 535, 535, 535, - 535, 535, 176, 1479, 177, -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, @@ -4114,27 +4111,27 @@ var yyPact = [...]int{ -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 28577, + 113, 28577, -1000, 463, 28577, 639, 639, 26, 639, 639, + 639, 639, 91, 484, -17, -1000, 89, 176, 82, 170, + 635, 166, 76, -1000, -1000, 156, 635, 79, -1000, 639, + 6808, 6808, 6808, -1000, 1488, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 381, -1000, -1000, -1000, -1000, 28577, 27194, + 275, 640, -1000, -1000, -1000, 2, -1000, -1000, 1143, 672, + -1000, 12409, 1290, 1125, 1125, -1000, -1000, 436, -1000, -1000, + 13792, 13792, 13792, 13792, 13792, 13792, 13792, 13792, 13792, 13792, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 29082, - 65, 29082, -1000, 441, 29082, 626, 626, 34, 626, 626, - 626, 626, 101, 419, -41, -1000, 83, 173, 109, 175, - 635, 213, 59, -1000, -1000, 169, 635, 49, -1000, 626, - 7313, 7313, 7313, -1000, 1464, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, 346, -1000, -1000, -1000, -1000, 29082, 27699, - 289, 577, -1000, -1000, -1000, 29, -1000, -1000, 1156, 846, - -1000, 12914, 2742, 1189, 1189, -1000, -1000, 418, -1000, -1000, - 14297, 14297, 14297, 14297, 14297, 14297, 14297, 14297, 14297, 14297, + -1000, -1000, -1000, -1000, 1125, 462, -1000, 11948, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 12409, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, 1125, + 1125, 1125, 1125, 1125, -1000, -1000, -1000, 28577, -1000, 1125, + 128, 1600, -1000, 1234, -1000, -1000, -1000, 1498, 12409, 12409, + 1600, -1000, 1386, 10552, -1000, -1000, 1424, -1000, -1000, -1000, + -1000, -1000, 783, 1625, -1000, 15175, 455, 1624, 26733, -1000, + 20272, 26272, 1225, 8233, -54, -1000, -1000, -1000, 611, 18889, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 1189, 439, -1000, 12453, 1189, 1189, - 1189, 1189, 1189, 1189, 1189, 1189, 12914, 1189, 1189, 1189, - 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, 1189, - 1189, 1189, 1189, 1189, -1000, -1000, -1000, 29082, -1000, 1189, - 136, 1572, -1000, 1232, -1000, -1000, -1000, 1468, 12914, 12914, - 1572, -1000, 1387, 11057, -1000, -1000, 1402, -1000, -1000, -1000, - -1000, -1000, 669, 1594, -1000, 15680, 436, 1592, 27238, -1000, - 20777, 26777, 1180, 8738, -33, -1000, -1000, -1000, 575, 19394, + -1000, -1000, -1000, -1000, -1000, 1488, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1464, -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, @@ -4146,197 +4143,196 @@ 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, 1151, 28577, -1000, -1000, 152, + 1006, -1000, 1274, -1000, 1145, -1000, 1238, 1291, 406, 1006, + 402, 401, 400, -1000, -121, -1000, -1000, -1000, -1000, -1000, + 577, 577, 266, 3855, 29052, -1000, -1000, -1000, 25804, 1272, + 1006, -1000, 1269, -1000, 1515, 356, 532, 532, 1006, -1000, + -1000, 28577, 1006, 1513, 1511, 28577, 28577, -1000, 25343, -1000, + 24882, 24421, 902, 28577, 23960, 23499, 23038, 22577, 22116, -1000, + 1361, -1000, 1247, -1000, -1000, -1000, 28577, 28577, 28577, 45, + -1000, -1000, 28577, 1006, -1000, -1000, 899, 885, 577, 577, + 884, 996, 994, 992, 577, 577, 882, 990, 20733, 252, + 878, 874, 867, 908, 988, 112, 904, 876, 864, 28577, + 1255, 28577, -1000, 160, 504, 274, 601, 1501, 1433, 1209, + 380, 405, 1006, 362, 362, -1000, 7283, -1000, -1000, 981, + 12409, -1000, 658, 635, 635, -1000, -1000, -1000, -1000, -1000, + -1000, 639, 28577, 658, -1000, -1000, -1000, 635, 639, 28577, + 639, 639, 639, 639, 635, 635, 635, 639, 28577, 28577, + 28577, 28577, 28577, 28577, 28577, 28577, 28577, 6808, 6808, 6808, + 537, 639, -1000, 1327, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 99, -1000, -1000, -1000, -1000, -1000, 1644, -1000, + -1000, -1000, -117, 1208, 21655, -1000, -291, -292, -293, -294, + -1000, -1000, -1000, -298, -301, -1000, -1000, -1000, 12409, 12409, + 12409, 12409, 887, 568, 13792, 842, 544, 13792, 13792, 13792, + 13792, 13792, 13792, 13792, 13792, 13792, 13792, 13792, 13792, 13792, + 13792, 13792, 861, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 1006, -1000, 1642, 1124, 1124, 486, 486, 486, 486, + 486, 486, 486, 486, 486, 14253, 9169, 7283, 1098, 1141, + 1600, 10552, 10552, 12409, 12409, 11474, 11013, 10552, 1487, 686, + 672, 28577, -1000, 1002, -1000, -1000, 13331, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 28577, + 28577, 10552, 10552, 10552, 10552, 10552, -1000, 1204, -1000, -172, + 16110, 12409, 980, 1585, 1098, 1424, 1535, 1633, 516, 669, + 1203, -1000, 945, 1585, 18428, 1226, -1000, 1424, -1000, -1000, + -1000, 28577, -1000, -1000, 21194, -1000, -1000, 6333, 28577, 264, + 28577, -1000, 1206, 1384, -1000, -1000, -1000, 1570, 17967, 28577, + 1232, 1158, -1000, -1000, 454, 7758, -54, -1000, 7758, 1166, + -1000, -34, -49, 9630, 481, -1000, -1000, -1000, 2607, 14714, + 1059, 1455, 27, -1000, -1000, -1000, 1238, -1000, 1238, 1238, + 1238, 1238, 45, 45, 45, 45, -1000, -1000, -1000, -1000, + -1000, 1254, 1253, -1000, 1238, 1238, 1238, 1238, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1132, 29082, -1000, -1000, 3221, - 924, -1000, 1252, -1000, 1129, -1000, 1207, 1259, 390, 924, - 381, 380, 379, -1000, -116, -1000, -1000, -1000, -1000, -1000, - 535, 535, 229, 253, 3856, -1000, -1000, -1000, 26309, 1250, - 924, -1000, 1249, -1000, 1495, 330, 512, 512, 924, -1000, - -1000, 29082, 924, 1493, 1489, 29082, 29082, -1000, 25848, -1000, - 25387, 24926, 862, 29082, 24465, 24004, 23543, 23082, 22621, -1000, - 1339, -1000, 1241, -1000, -1000, -1000, 29082, 29082, 29082, 28, - -1000, -1000, 29082, 924, -1000, -1000, 857, 852, 535, 535, - 833, 972, 970, 965, 535, 535, 832, 959, 1007, 180, - 816, 805, 804, 853, 953, 112, 811, 753, 795, 29082, - 1248, 29082, -1000, 168, 504, 261, 557, 1479, 1428, 1179, - 344, 388, 924, 312, 312, -1000, 7788, -1000, -1000, 952, - 12914, -1000, 650, 635, 635, -1000, -1000, -1000, -1000, -1000, - -1000, 626, 29082, 650, -1000, -1000, -1000, 635, 626, 29082, - 626, 626, 626, 626, 635, 635, 635, 626, 29082, 29082, - 29082, 29082, 29082, 29082, 29082, 29082, 29082, 7313, 7313, 7313, - 500, 626, -1000, 1346, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 114, -1000, -1000, -1000, -1000, -1000, 1608, -1000, - -1000, -1000, -113, 1177, 22160, -1000, -291, -292, -293, -294, - -1000, -1000, -1000, -297, -299, -1000, -1000, -1000, 12914, 12914, - 12914, 12914, 894, 513, 14297, 705, 506, 14297, 14297, 14297, - 14297, 14297, 14297, 14297, 14297, 14297, 14297, 14297, 14297, 14297, - 14297, 14297, 676, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 924, -1000, 1606, 1061, 1061, 461, 461, 461, 461, - 461, 461, 461, 461, 461, 14758, 9674, 7788, 1075, 1126, - 1572, 11057, 11057, 12914, 12914, 11979, 11518, 11057, 1455, 605, - 846, 29082, -1000, 893, -1000, -1000, 13836, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 29082, - 29082, 11057, 11057, 11057, 11057, 11057, -1000, 1176, -1000, -172, - 16615, 12914, 946, 1526, 1075, 1402, 1498, 1600, 480, 855, - 1174, -1000, 935, 1526, 18933, 1218, -1000, 1402, -1000, -1000, - -1000, 29082, -1000, -1000, 21699, -1000, -1000, 6838, 29082, 221, - 29082, -1000, 1198, 1308, -1000, -1000, -1000, 1515, 18472, 29082, - 1203, 1186, -1000, -1000, 435, 8263, -33, -1000, 8263, 1161, - -1000, -66, -45, 10135, 451, -1000, -1000, -1000, 2370, 15219, - 1049, 1435, 47, -1000, -1000, -1000, 1207, -1000, 1207, 1207, - 1207, 1207, 28, 28, 28, 28, -1000, -1000, -1000, -1000, - -1000, 1247, 1246, -1000, 1207, 1207, 1207, 1207, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1252, 1252, 1252, 1239, 1239, + 347, -1000, 12409, 116, 28577, 1550, 855, 160, 363, 1297, + 1006, 1006, 1006, 363, -1000, 1035, 960, -1000, 1202, -1000, + -1000, 1597, -1000, -1000, 853, 742, 739, 603, 28577, 137, + 256, -1000, 315, -1000, 28577, 1006, 1508, 532, 1006, -1000, + 1006, -1000, -1000, -1000, -1000, 453, -1000, -1000, 1006, 1200, + -1000, 1177, 767, 723, 724, 697, 1200, -1000, -1000, -147, + 1200, -1000, 1200, -1000, 1200, -1000, 1200, -1000, 1200, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 559, 28577, 137, + 861, -1000, 379, -1000, -1000, 861, 861, -1000, -1000, -1000, + -1000, 978, 977, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, 1244, 1244, 1244, 1220, 1220, - 290, -1000, 12914, 107, 29082, 1504, 790, 168, 315, 1279, - 924, 924, 924, 315, -1000, 983, 971, -1000, 1172, -1000, - -1000, 1569, -1000, -1000, 617, 629, 627, 484, 29082, 141, - 220, -1000, 284, -1000, 29082, 924, 1487, 512, 924, -1000, - 924, -1000, -1000, -1000, -1000, 433, -1000, -1000, 924, 1171, - -1000, 1065, 729, 622, 688, 616, 1171, -1000, -1000, -159, - 1171, -1000, 1171, -1000, 1171, -1000, 1171, -1000, 1171, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 532, 29082, 141, - 676, -1000, 343, -1000, -1000, 676, 676, -1000, -1000, -1000, - -1000, 930, 929, -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, -338, - 29082, -1000, 156, 545, 196, 226, 206, 29082, 131, 1521, - 154, 186, 29082, 29082, 312, 1307, 29082, 1509, 29082, -1000, - -1000, -1000, -1000, 846, 29082, -1000, -1000, 626, 626, -1000, - -1000, 29082, 626, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 626, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 928, -1000, 29082, 29082, - -1000, -1000, -1000, -1000, -1000, 78, -78, 166, -1000, -1000, - -1000, -1000, 1523, -1000, 846, 513, 719, 647, -1000, -1000, - 899, -1000, -1000, 2150, -1000, -1000, -1000, -1000, 705, 14297, - 14297, 14297, 611, 2150, 2910, 728, 1266, 461, 562, 562, - 476, 476, 476, 476, 476, 533, 533, -1000, -1000, -1000, - -1000, 893, -1000, -1000, -1000, 893, 11057, 11057, 1169, 1189, - 423, -1000, 1245, -1000, -1000, 1526, 1095, 1095, 714, 876, - 566, 1591, 1095, 552, 1589, 1095, 1095, 11057, -1000, -1000, - 690, -1000, 12914, 893, -1000, 888, 1166, 1164, 1095, 893, - 893, 1095, 1095, 29082, -1000, -284, -1000, -96, 473, 1189, - -1000, 21238, -1000, -1000, 893, 1156, -1000, 1468, -1000, -1000, - 1414, -1000, 1381, 12914, 12914, 12914, -1000, -1000, -1000, 1468, - 1571, -1000, 1397, 1396, 1583, 11057, 20777, 1402, -1000, -1000, - -1000, 422, 1583, 1201, 1189, -1000, 29082, 20777, 20777, 20777, - 20777, 20777, -1000, 1364, 1363, -1000, 1361, 1357, 1368, 29082, - -1000, 1109, 1075, 18472, 221, 1149, 20777, 29082, -1000, -1000, - 20777, 29082, 6363, -1000, 1161, -33, -69, -1000, -1000, -1000, - -1000, 846, -1000, 966, -1000, 2227, -1000, 281, -1000, -1000, - -1000, -1000, 457, 1514, 1433, -15, -1000, -1000, -1000, 28, - 28, -1000, -1000, 451, 687, 451, 451, 451, 926, 926, - -1000, -1000, -1000, -1000, -1000, 788, -1000, -1000, -1000, 766, - -1000, -1000, 869, 1332, 107, -1000, -1000, 535, 925, 1438, - 29082, -1000, -1000, 1041, 156, 29082, 564, 1303, -1000, 1279, - 1279, 1279, 29082, -1000, -1000, -1000, -1000, 3583, 29082, 1106, - -1000, 139, 29082, 1019, 29082, -1000, 1103, 1234, 924, 924, - -1000, -1000, 7788, -1000, 29082, 1189, -1000, -1000, -1000, -1000, - 384, 1474, 1469, 141, 139, 451, 924, -1000, -1000, -1000, - -1000, -1000, -341, 1101, 369, 144, 147, 29082, 29082, 29082, - 29082, 29082, 410, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 181, 340, -1000, 29082, 29082, 378, -1000, -1000, -1000, 635, - -1000, -1000, 635, -1000, -1000, -1000, -1000, -1000, -1000, 1459, - -87, -313, -1000, -310, -1000, -1000, -1000, -1000, 611, 2150, - 2852, -1000, 14297, 14297, -1000, -1000, 1095, 1095, 11057, 7788, - 1572, 1468, -1000, -1000, 361, 676, 361, 14297, 14297, -1000, - 14297, 14297, -1000, -151, 1052, 534, -1000, 12914, 709, -1000, - -1000, 14297, 14297, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, 376, 374, 373, 29082, -1000, -1000, -1000, 879, - 917, 1377, 846, 846, -1000, -1000, 29082, -1000, -1000, -1000, - -1000, 1580, 12914, -1000, 1160, -1000, 5888, 1526, 1293, 29082, - 1189, 1608, 16154, 29082, 1211, -1000, 543, 1308, 1278, 1290, - 1276, -1000, -1000, -1000, -1000, 1360, -1000, 1318, -1000, -1000, - -1000, -1000, -1000, 1075, 1583, 20777, 1151, -1000, 1151, -1000, - 421, -1000, -1000, -1000, -92, -64, -1000, -1000, -1000, 2370, - -1000, -1000, -1000, -1000, 643, 14297, 1599, -1000, 913, -1000, - -1000, 1486, 1484, -1000, 29082, 1224, -1000, -1000, -1000, 451, - 451, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1090, -1000, - 1084, 1159, 1082, 51, -1000, 1258, 1457, 535, 535, -1000, - 751, -1000, 924, -1000, -1000, 367, -1000, 1508, 29082, 1288, - 1287, 1285, -1000, 1557, 1158, -1000, 29082, -1000, -1000, 29082, - -1000, -1000, 1395, 107, 29082, -1000, -1000, -1000, -1000, 220, - 29082, -1000, 1061, 139, -1000, -1000, -1000, -1000, -1000, -1000, - 29082, 152, -1000, 1223, 691, -1000, 1270, -1000, -1000, -1000, - -1000, 113, 195, -1000, 29082, 372, 1332, 29082, -1000, -1000, - -1000, 626, 626, -1000, 1453, -1000, 924, -1000, 14297, 2150, - 2150, -1000, -1000, 893, -1000, 1526, -1000, 893, 1207, 1207, - -1000, 1207, 1220, -1000, 1207, 99, 1207, 68, 893, 893, - 2805, 2757, 2647, 2357, 1189, -141, -1000, 846, 12914, 2294, - 1798, 1189, 1189, 1189, 1058, 912, 28, -1000, -1000, -1000, - 1578, 1547, 846, -1000, -1000, -1000, 1491, 1025, 1144, -1000, - -1000, 10596, 1078, 1390, 416, 1058, 1572, 29082, 12914, -1000, - -1000, 12914, 1202, -1000, 12914, -1000, -1000, -1000, 1572, 1572, - 1151, -1000, -1000, 479, -1000, -1000, -1000, -1000, -1000, 2150, - -86, -1000, -1000, -1000, 1200, 14297, -1000, -1000, 28, 900, - 28, 732, -1000, 701, -1000, -1000, -226, -1000, -1000, 1238, - 1294, -1000, -1000, 29082, -1000, -1000, 29082, 29082, 29082, 29082, - 29082, -1000, -1000, 187, -1000, 1055, 1048, -1000, -177, -1000, - -1000, 1195, -1000, -1000, -1000, 1013, -1000, -160, 924, 29082, - 29082, 29082, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 2150, -1000, 1468, -1000, -1000, 233, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, 14297, 14297, 14297, 14297, 14297, 1526, - 895, 846, 14297, 14297, 17998, 20316, 20316, 17537, 28, 45, - -1000, 12914, 12914, 1481, -1000, 1189, -1000, 1221, 29082, 1189, - 29082, -1000, 1526, -1000, 846, 846, 29082, 846, 1526, -1000, - -1000, 29082, 978, 451, -1000, 451, 1000, 991, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, 1195, -1000, -1000, -1000, - 1158, -1000, 200, 249, -1000, 220, -1000, -184, -190, 1513, - 29082, -1000, -1000, 7788, -1000, -1000, 1190, 1274, -1000, -1000, - -1000, -1000, 888, 888, 888, 888, 170, 893, -1000, 888, - 888, 1046, -1000, -1000, -1000, 1046, 1046, 473, -277, -1000, - 1425, 1403, 846, 1156, 1598, -1000, 1189, 1608, 411, 1144, - -1000, -1000, 1044, -1000, 1039, -1000, -1000, -1000, -1000, -1000, - 1511, 1189, -1000, -1000, -1000, -1000, 1232, 1018, 1153, -1000, - 511, 29082, 29082, -1000, -1000, -1000, -1000, 893, 124, -162, - -1000, -1000, -1000, 19855, -1000, -1000, -1000, -1000, 45, 268, - -1000, 1408, 1403, -1000, 1545, 1413, 1538, -1000, 29082, 1144, - 29082, -1000, 1284, 671, 1232, 13375, 183, -1000, 7788, 5413, - 998, -1000, -1000, 1376, -157, -174, -1000, -1000, 1407, 1405, - 1405, 1408, -1000, 1532, 1531, -1000, 887, 1529, 886, 1060, - -1000, 1283, -1000, 1588, -1000, -1000, -1000, 638, 884, -1000, - -1000, -1000, 183, 888, 893, -1000, -59, -1000, -1000, -1000, - -1000, -1000, 1270, -1000, 1371, -1000, 1404, 784, -1000, -1000, - -1000, -1000, 882, 881, -1000, 689, -1000, -1000, 1590, 428, - 428, -1000, -1000, -1000, -1000, -1000, 288, -1000, -1000, -160, - -171, -1000, 775, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 285, 754, -1000, 161, -1000, -167, -1000, -1000, -1000, - -1000, -1000, -1000, -175, -1000, + -338, 28577, -1000, 150, 600, 234, 268, 225, 28577, 109, + 1579, 164, 177, 28577, 28577, 362, 1323, 28577, 1558, 28577, + -1000, -1000, -1000, -1000, 672, 28577, -1000, -1000, 639, 639, + -1000, -1000, 28577, 639, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, 639, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 969, -1000, 28577, + 28577, -1000, -1000, -1000, -1000, -1000, 64, -44, 179, -1000, + -1000, -1000, -1000, 1581, -1000, 672, 568, 684, 558, -1000, + -1000, 802, -1000, -1000, 2117, -1000, -1000, -1000, -1000, 842, + 13792, 13792, 13792, 573, 2117, 2694, 1207, 701, 486, 714, + 714, 476, 476, 476, 476, 476, 683, 683, -1000, -1000, + -1000, -1000, 1002, -1000, -1000, -1000, 1002, 10552, 10552, 1181, + 1125, 452, -1000, 1275, -1000, -1000, 1585, 1096, 1096, 1007, + 913, 618, 1623, 1096, 599, 1620, 1096, 1096, 10552, -1000, + -1000, 657, -1000, 12409, 1002, -1000, 2148, 1178, 1171, 1096, + 1002, 1002, 1096, 1096, 28577, -1000, -274, -1000, -100, 464, + 1125, -1000, 20733, 1002, 1143, -1000, 1498, -1000, -1000, 1457, + -1000, 1394, 12409, 12409, 12409, -1000, -1000, -1000, 1498, 1587, + -1000, 1409, 1408, 1612, 10552, 20272, 1424, -1000, -1000, -1000, + 451, 1612, 1176, 1125, -1000, 28577, 20272, 20272, 20272, 20272, + 20272, -1000, 1346, 1344, -1000, 1377, 1340, 1395, 28577, -1000, + 1118, 1098, 17967, 264, 1147, 20272, 28577, -1000, -1000, 20272, + 28577, 5858, -1000, 1166, -54, -25, -1000, -1000, -1000, -1000, + 672, -1000, 933, -1000, 2387, -1000, 341, -1000, -1000, -1000, + -1000, 589, 1569, 1452, 10, -1000, -1000, -1000, 45, 45, + -1000, -1000, 481, 866, 481, 481, 481, 959, 959, -1000, + -1000, -1000, -1000, -1000, 852, -1000, -1000, -1000, 850, -1000, + -1000, 778, 1329, 116, -1000, -1000, 577, 944, 1467, 28577, + -1000, -1000, 1057, 150, 28577, 688, 1322, -1000, 1297, 1297, + 1297, 28577, -1000, -1000, -1000, -1000, 4332, 28577, 1109, -1000, + 132, 28577, 1039, 28577, -1000, 1106, 1251, 1006, 1006, -1000, + -1000, 7283, -1000, 28577, 1125, -1000, -1000, -1000, -1000, 404, + 1497, 1496, 137, 132, 481, 1006, -1000, -1000, -1000, -1000, + -1000, -341, 1101, 390, 139, 184, 28577, 28577, 28577, 28577, + 28577, 427, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 190, + 377, -1000, 28577, 28577, 456, -1000, -1000, -1000, 635, -1000, + -1000, 635, -1000, -1000, -1000, -1000, -1000, -1000, 1489, -46, + -313, -1000, -310, -1000, -1000, -1000, -1000, 573, 2117, 2223, + -1000, 13792, 13792, -1000, -1000, 1096, 1096, 10552, 7283, 1600, + 1498, -1000, -1000, 289, 861, 289, 13792, 13792, -1000, 13792, + 13792, -1000, -133, 1182, 584, -1000, 12409, 681, -1000, -1000, + 13792, 13792, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + -1000, 398, 396, 395, 28577, -1000, -1000, -1000, 889, 942, + 1379, 672, 672, -1000, -1000, 28577, -1000, -1000, -1000, -1000, + 1610, 12409, -1000, 1164, -1000, 5383, 1585, 1320, 28577, 1125, + 1644, 15649, 28577, 1174, -1000, 597, 1384, 1313, 1319, 1311, + -1000, -1000, -1000, -1000, 1342, -1000, 1265, -1000, -1000, -1000, + -1000, -1000, 1098, 1612, 20272, 1135, -1000, 1135, -1000, 446, + -1000, -1000, -1000, -71, -72, -1000, -1000, -1000, 2607, -1000, + -1000, -1000, -1000, 770, 13792, 1631, -1000, 938, -1000, -1000, + 1504, 1503, -1000, 28577, 1249, -1000, -1000, -1000, 481, 481, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1094, -1000, 1090, + 1161, 1084, 66, -1000, 1286, 1480, 577, 577, -1000, 808, + -1000, 1006, -1000, -1000, 388, -1000, 1540, 28577, 1318, 1317, + 1315, -1000, 1596, 1159, -1000, 28577, -1000, -1000, 28577, -1000, + -1000, 1402, 116, 28577, -1000, -1000, -1000, -1000, 256, 28577, + -1000, 1124, 132, -1000, -1000, -1000, -1000, -1000, -1000, 28577, + 151, -1000, 1248, 911, -1000, 1293, -1000, -1000, -1000, -1000, + 98, 232, -1000, 28577, 438, 1329, 28577, -1000, -1000, -1000, + 639, 639, -1000, 1478, -1000, 1006, -1000, 13792, 2117, 2117, + -1000, -1000, 1002, -1000, 1585, -1000, 1002, 1238, 1238, -1000, + 1238, 1239, -1000, 1238, 74, 1238, 71, 1002, 1002, 2676, + 2615, 2551, 2411, 1125, -128, -1000, 672, 12409, 2485, 2323, + 1125, 1125, 1125, 1079, 937, 45, -1000, -1000, -1000, 1589, + 1595, 672, -1000, -1000, -1000, 1525, 1051, 1062, -1000, -1000, + 10091, 1082, 1401, 440, 1079, 1600, 28577, 12409, -1000, -1000, + 12409, 1237, -1000, 12409, -1000, -1000, -1000, 1600, 1600, 1135, + -1000, -1000, 498, -1000, -1000, -1000, -1000, -1000, 2117, -137, + -1000, -1000, -1000, 1236, 13792, -1000, -1000, 45, 923, 45, + 805, -1000, 801, -1000, -1000, -214, -1000, -1000, 1244, 1285, + -1000, -1000, 28577, -1000, -1000, 28577, 28577, 28577, 28577, 28577, + -1000, -1000, 253, -1000, 1075, 1070, -1000, -171, -1000, -1000, + 1235, -1000, -1000, -1000, 1028, -1000, -148, 1006, 28577, 28577, + 28577, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 2117, + -1000, 1498, -1000, -1000, 241, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, 13792, 13792, 13792, 13792, 13792, 1585, 921, + 672, 13792, 13792, 17493, 19811, 19811, 17032, 45, 19, -1000, + 12409, 12409, 1499, -1000, 1125, -1000, 1150, 28577, 1125, 28577, + -1000, 1585, -1000, 672, 672, 28577, 672, 1585, -1000, -1000, + 28577, 2191, 481, -1000, 481, 1012, 1010, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, 1235, -1000, -1000, -1000, 1159, + -1000, 242, 305, -1000, 256, -1000, -178, -179, 1563, 28577, + -1000, -1000, 7283, -1000, -1000, 1231, 1295, -1000, -1000, -1000, + -1000, 2148, 2148, 2148, 2148, 213, 1002, -1000, 2148, 2148, + 1056, -1000, -1000, -1000, 1056, 1056, 464, -266, -1000, 1427, + 1428, 672, 1143, 1629, -1000, 1125, 1644, 434, 1062, -1000, + -1000, 1053, -1000, 1032, -1000, -1000, -1000, -1000, -1000, 1562, + 1125, -1000, -1000, -1000, -1000, 1234, 1027, 1116, -1000, 540, + 28577, 28577, -1000, -1000, -1000, -1000, 1002, 142, -151, -1000, + -1000, -1000, 19350, -1000, -1000, -1000, -1000, 19, 263, -1000, + 1445, 1428, -1000, 1594, 1423, 1593, -1000, 28577, 1062, 28577, + -1000, 1309, 830, 1234, 12870, 189, -1000, 7283, 4908, 1017, + -1000, -1000, 1375, -144, -166, -1000, -1000, 1417, 1419, 1419, + 1445, -1000, 1592, 1591, -1000, 920, 1588, 918, 919, -1000, + 1300, -1000, 1619, -1000, -1000, -1000, 766, 917, -1000, -1000, + -1000, 189, 2148, 1002, -1000, -50, -1000, -1000, -1000, -1000, + -1000, 1293, -1000, 1358, -1000, 1414, 794, -1000, -1000, -1000, + -1000, 910, 906, -1000, 888, -1000, -1000, 1621, 468, 468, + -1000, -1000, -1000, -1000, -1000, 318, -1000, -1000, -148, -149, + -1000, 792, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, + 314, 868, -1000, 153, -1000, -164, -1000, -1000, -1000, -1000, + -1000, -1000, -167, -1000, } var yyPgo = [...]int{ - 0, 1863, 1862, 12, 90, 93, 1861, 1859, 1857, 1856, - 136, 134, 133, 1855, 1854, 1853, 1849, 1848, 1846, 1845, - 1844, 1842, 1840, 1838, 1837, 66, 121, 40, 44, 124, - 1836, 1834, 39, 1833, 1832, 1830, 125, 123, 567, 1829, - 129, 1828, 1826, 1825, 1823, 1818, 1817, 1814, 1812, 1811, - 1810, 1809, 1808, 1805, 1804, 230, 1803, 1797, 4, 1796, - 41, 1795, 1794, 1784, 1782, 1781, 94, 1778, 1776, 1775, - 118, 1773, 1772, 46, 402, 63, 84, 1771, 1770, 77, - 126, 1768, 64, 107, 1767, 1766, 787, 1764, 50, 82, - 102, 1763, 51, 1762, 1761, 68, 1760, 1759, 1757, 81, - 1755, 1754, 3342, 1753, 78, 86, 19, 34, 1750, 1745, - 1742, 1741, 38, 416, 1740, 1739, 32, 1738, 1737, 141, - 1735, 91, 22, 1731, 18, 43, 25, 1730, 100, 1729, - 28, 56, 35, 1726, 87, 1725, 1724, 1723, 1721, 80, - 1720, 85, 108, 24, 1719, 1718, 1714, 8, 16, 1713, - 1712, 1711, 1710, 1709, 1708, 15, 1707, 6, 1704, 27, - 1703, 17, 23, 30, 76, 73, 33, 14, 1701, 135, - 1698, 29, 130, 72, 115, 1695, 1694, 1693, 847, 149, - 1692, 1691, 48, 1689, 104, 106, 1686, 166, 1684, 1683, - 69, 1086, 2511, 9, 117, 1681, 1680, 1728, 59, 79, - 26, 1678, 57, 1677, 1675, 1674, 127, 119, 67, 769, - 45, 1673, 1672, 1671, 1669, 1667, 1666, 1665, 83, 185, - 31, 109, 37, 1664, 1663, 1661, 65, 47, 1659, 113, - 112, 74, 128, 1658, 120, 103, 53, 1657, 58, 1656, - 1655, 1653, 1651, 61, 1650, 1649, 1648, 1641, 111, 105, - 71, 42, 1639, 36, 75, 99, 98, 1638, 20, 122, - 7, 1636, 1, 0, 1633, 3, 131, 162, 110, 1632, - 1631, 2, 1630, 5, 1628, 1627, 89, 1625, 1624, 1623, - 11, 21, 10, 1617, 1615, 3253, 1960, 116, 1614, 132, + 0, 1879, 1878, 11, 91, 99, 1877, 1871, 1870, 1869, + 136, 133, 131, 1868, 1866, 1863, 1862, 1861, 1860, 1859, + 1857, 1856, 1855, 1854, 1853, 67, 121, 43, 47, 140, + 1848, 1847, 30, 1846, 1845, 1844, 148, 147, 587, 1843, + 129, 1842, 1841, 1839, 1838, 1837, 1836, 1835, 1833, 1832, + 1831, 1830, 1829, 1828, 1827, 220, 1825, 1824, 5, 1821, + 37, 1820, 1819, 1816, 1814, 1813, 101, 1810, 1808, 1806, + 122, 1805, 1804, 56, 116, 71, 78, 1803, 1801, 82, + 126, 1799, 64, 104, 1798, 1797, 93, 1796, 45, 75, + 80, 1795, 46, 1792, 1791, 57, 1790, 1789, 1788, 85, + 1785, 1783, 2912, 1782, 73, 87, 16, 53, 1779, 1778, + 1772, 1771, 40, 2415, 1770, 1769, 36, 1768, 1767, 141, + 1766, 89, 24, 1765, 13, 15, 23, 1764, 98, 1763, + 44, 59, 38, 1762, 94, 1760, 1759, 1758, 1756, 66, + 1754, 81, 105, 34, 1753, 1752, 1748, 21, 6, 1747, + 1743, 1742, 1741, 1740, 1738, 10, 1737, 14, 1735, 26, + 1734, 17, 18, 35, 77, 69, 29, 22, 1731, 161, + 1730, 25, 115, 72, 113, 1729, 1728, 1724, 972, 145, + 1723, 1722, 58, 1720, 107, 102, 1719, 173, 1717, 1715, + 65, 1304, 2669, 31, 117, 1713, 1712, 2139, 61, 86, + 20, 1711, 79, 1710, 1709, 1708, 127, 125, 50, 926, + 51, 1707, 1706, 1704, 1703, 1702, 1701, 1699, 132, 27, + 33, 106, 28, 1698, 1696, 1695, 63, 39, 1694, 111, + 110, 74, 135, 1693, 118, 103, 84, 1692, 83, 1691, + 1689, 1688, 1687, 48, 1685, 1684, 1683, 1681, 114, 108, + 68, 41, 1680, 42, 76, 109, 112, 1678, 19, 124, + 8, 1677, 1, 0, 1676, 4, 130, 172, 119, 1674, + 1671, 2, 1670, 7, 1668, 1661, 88, 1658, 1656, 1655, + 9, 32, 3, 1654, 1651, 186, 541, 120, 1650, 128, } -//line sql.y:5320 +//line sql.y:5316 type yySymType struct { union interface{} empty struct{} @@ -4816,73 +4812,73 @@ var yyR1 = [...]int{ 246, 246, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, - 243, 181, 181, 181, 270, 270, 270, 270, 270, 270, - 269, 269, 269, 242, 242, 242, 268, 268, 131, 131, - 132, 132, 30, 30, 30, 30, 30, 30, 29, 29, - 29, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 181, 181, 181, 270, 270, 270, 270, 270, 270, 269, + 269, 269, 242, 242, 242, 268, 268, 131, 131, 132, + 132, 30, 30, 30, 30, 30, 30, 29, 29, 29, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 31, 31, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 16, 16, 16, 16, 16, 16, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 31, 31, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 259, 259, 259, 259, 259, 259, 259, + 16, 16, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, 259, - 259, 259, 259, 259, 259, 225, 225, 225, 257, 257, - 258, 258, 17, 22, 22, 18, 18, 18, 18, 19, - 19, 41, 42, 42, 42, 42, 42, 42, 42, 42, + 259, 259, 259, 259, 225, 225, 225, 257, 257, 258, + 258, 17, 22, 22, 18, 18, 18, 18, 19, 19, + 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 274, 274, - 180, 180, 188, 188, 179, 179, 202, 202, 202, 182, - 182, 182, 183, 183, 278, 278, 278, 43, 43, 45, - 45, 46, 47, 47, 204, 204, 205, 205, 48, 49, - 61, 61, 61, 61, 61, 61, 63, 63, 63, 7, - 7, 7, 7, 57, 57, 57, 6, 6, 44, 44, - 51, 275, 275, 276, 277, 277, 277, 277, 52, 54, - 20, 20, 20, 20, 20, 20, 78, 78, 66, 66, - 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 72, 72, 72, 67, 67, 288, 55, 56, 56, 70, - 70, 70, 64, 64, 64, 69, 69, 69, 75, 75, - 77, 77, 77, 77, 77, 79, 79, 79, 79, 79, - 79, 79, 74, 74, 76, 76, 76, 76, 195, 195, - 195, 194, 194, 87, 87, 88, 88, 89, 89, 90, - 90, 90, 129, 105, 105, 162, 162, 161, 161, 163, - 163, 163, 163, 165, 165, 91, 91, 91, 91, 92, - 92, 93, 93, 94, 94, 203, 203, 200, 200, 200, - 199, 199, 98, 98, 98, 100, 99, 99, 99, 99, - 101, 101, 103, 103, 102, 102, 104, 106, 106, 106, - 106, 106, 107, 107, 86, 86, 86, 86, 86, 86, - 86, 86, 177, 177, 109, 109, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 120, 120, 120, 120, - 120, 120, 110, 110, 110, 110, 110, 110, 110, 73, - 73, 121, 121, 121, 128, 122, 122, 113, 113, 113, + 42, 42, 42, 42, 42, 42, 42, 274, 274, 180, + 180, 188, 188, 179, 179, 202, 202, 202, 182, 182, + 182, 183, 183, 278, 278, 278, 43, 43, 45, 45, + 46, 47, 47, 204, 204, 205, 205, 48, 49, 61, + 61, 61, 61, 61, 61, 63, 63, 63, 7, 7, + 7, 7, 57, 57, 57, 6, 6, 44, 44, 51, + 275, 275, 276, 277, 277, 277, 277, 52, 54, 20, + 20, 20, 20, 20, 20, 78, 78, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 72, + 72, 72, 67, 67, 288, 55, 56, 56, 70, 70, + 70, 64, 64, 64, 69, 69, 69, 75, 75, 77, + 77, 77, 77, 77, 79, 79, 79, 79, 79, 79, + 79, 74, 74, 76, 76, 76, 76, 195, 195, 195, + 194, 194, 87, 87, 88, 88, 89, 89, 90, 90, + 90, 129, 105, 105, 162, 162, 161, 161, 163, 163, + 163, 163, 165, 165, 91, 91, 91, 91, 92, 92, + 93, 93, 94, 94, 203, 203, 200, 200, 200, 199, + 199, 98, 98, 98, 100, 99, 99, 99, 99, 101, + 101, 103, 103, 102, 102, 104, 106, 106, 106, 106, + 106, 107, 107, 86, 86, 86, 86, 86, 86, 86, + 86, 177, 177, 109, 109, 108, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 120, 120, 120, 120, 120, + 120, 110, 110, 110, 110, 110, 110, 110, 73, 73, + 121, 121, 121, 128, 122, 122, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 117, 117, 117, 117, 115, 115, 115, 115, 115, - 115, 115, 115, 115, 115, 115, 115, 115, 115, 116, + 117, 117, 117, 117, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116, 289, 289, 119, 118, 118, - 118, 118, 118, 118, 118, 68, 68, 68, 68, 68, - 208, 208, 208, 210, 210, 210, 210, 210, 210, 210, - 210, 210, 210, 210, 210, 210, 135, 135, 65, 65, - 133, 133, 134, 136, 136, 130, 130, 130, 112, 112, - 112, 112, 112, 112, 112, 112, 114, 114, 114, 137, - 137, 138, 138, 139, 139, 140, 140, 141, 142, 142, - 142, 143, 143, 143, 143, 32, 32, 32, 32, 32, - 27, 27, 27, 27, 28, 28, 28, 80, 80, 80, - 80, 82, 82, 81, 81, 58, 58, 59, 59, 59, - 83, 83, 84, 84, 84, 84, 159, 159, 159, 144, - 144, 144, 144, 151, 151, 151, 147, 147, 149, 149, - 149, 150, 150, 150, 148, 156, 156, 158, 158, 157, - 157, 153, 153, 154, 154, 155, 155, 155, 152, 152, - 111, 111, 111, 111, 111, 160, 160, 160, 160, 166, - 166, 124, 124, 126, 126, 125, 127, 167, 167, 171, - 168, 168, 172, 172, 172, 172, 172, 169, 169, 170, - 170, 196, 196, 196, 176, 176, 187, 187, 184, 184, - 185, 185, 178, 178, 189, 189, 189, 53, 123, 123, - 254, 254, 251, 192, 192, 193, 193, 197, 197, 201, - 201, 198, 198, 190, 190, 190, 190, 190, 190, 190, + 116, 116, 116, 116, 289, 289, 119, 118, 118, 118, + 118, 118, 118, 118, 68, 68, 68, 68, 68, 208, + 208, 208, 210, 210, 210, 210, 210, 210, 210, 210, + 210, 210, 210, 210, 210, 135, 135, 65, 65, 133, + 133, 134, 136, 136, 130, 130, 130, 112, 112, 112, + 112, 112, 112, 112, 112, 114, 114, 114, 137, 137, + 138, 138, 139, 139, 140, 140, 141, 142, 142, 142, + 143, 143, 143, 143, 32, 32, 32, 32, 32, 27, + 27, 27, 27, 28, 28, 28, 80, 80, 80, 80, + 82, 82, 81, 81, 58, 58, 59, 59, 59, 83, + 83, 84, 84, 84, 84, 159, 159, 159, 144, 144, + 144, 144, 151, 151, 151, 147, 147, 149, 149, 149, + 150, 150, 150, 148, 156, 156, 158, 158, 157, 157, + 153, 153, 154, 154, 155, 155, 155, 152, 152, 111, + 111, 111, 111, 111, 160, 160, 160, 160, 166, 166, + 124, 124, 126, 126, 125, 127, 167, 167, 171, 168, + 168, 172, 172, 172, 172, 172, 169, 169, 170, 170, + 196, 196, 196, 176, 176, 187, 187, 184, 184, 185, + 185, 178, 178, 189, 189, 189, 53, 123, 123, 254, + 254, 251, 192, 192, 193, 193, 197, 197, 201, 201, + 198, 198, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, @@ -4896,7 +4892,7 @@ var yyR1 = [...]int{ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, 190, - 190, 190, 190, 191, 191, 191, 191, 191, 191, 191, + 190, 190, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, @@ -4923,7 +4919,7 @@ var yyR1 = [...]int{ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, - 191, 191, 285, 286, 206, 207, 207, 207, + 191, 285, 286, 206, 207, 207, 207, } var yyR2 = [...]int{ @@ -4958,73 +4954,73 @@ var yyR2 = [...]int{ 1, 1, 0, 1, 2, 0, 1, 1, 3, 2, 1, 2, 3, 3, 4, 4, 3, 3, 3, 3, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, - 5, 0, 2, 2, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, - 0, 2, 0, 1, 5, 1, 3, 7, 1, 3, - 3, 1, 2, 2, 2, 5, 5, 5, 6, 6, - 5, 5, 2, 2, 2, 2, 3, 3, 3, 4, - 1, 3, 5, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 4, 4, 2, 11, 3, - 6, 8, 6, 6, 6, 13, 8, 6, 10, 5, - 5, 5, 5, 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, 7, 7, 6, 5, 3, - 2, 3, 3, 3, 7, 3, 3, 3, 3, 4, - 7, 5, 2, 4, 4, 4, 4, 4, 5, 5, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, + 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, + 2, 0, 1, 5, 1, 3, 7, 1, 3, 3, + 1, 2, 2, 2, 5, 5, 5, 6, 6, 5, + 5, 2, 2, 2, 2, 3, 3, 3, 4, 1, + 3, 5, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 2, 2, 4, 4, 2, 11, 3, 6, + 8, 6, 6, 6, 13, 8, 6, 10, 5, 5, + 5, 5, 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, 7, 7, 6, 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, - 4, 2, 4, 2, 4, 5, 4, 4, 4, 4, - 3, 3, 5, 2, 3, 3, 3, 3, 1, 1, - 0, 1, 0, 1, 1, 1, 0, 2, 2, 0, - 2, 2, 0, 2, 0, 1, 1, 2, 1, 1, - 2, 1, 1, 5, 0, 1, 0, 1, 2, 3, - 0, 3, 3, 3, 3, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 3, 3, 2, 2, - 3, 1, 3, 2, 1, 2, 1, 2, 2, 4, - 3, 3, 6, 4, 7, 6, 1, 3, 2, 2, - 2, 2, 1, 1, 1, 3, 2, 1, 1, 1, - 0, 1, 1, 0, 3, 0, 2, 0, 2, 1, - 2, 2, 0, 1, 1, 0, 1, 1, 0, 1, - 0, 1, 2, 3, 4, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 2, 3, 5, 0, 1, - 2, 1, 1, 0, 2, 1, 3, 1, 1, 1, - 3, 3, 3, 3, 7, 0, 3, 1, 3, 1, - 1, 3, 3, 1, 3, 4, 4, 4, 3, 2, - 4, 0, 1, 0, 2, 0, 1, 0, 1, 2, - 1, 1, 1, 2, 2, 1, 2, 3, 2, 3, - 2, 2, 2, 1, 1, 3, 3, 0, 5, 4, - 5, 5, 0, 2, 1, 3, 3, 3, 2, 3, - 1, 2, 0, 3, 1, 1, 3, 3, 4, 4, - 5, 3, 4, 5, 6, 2, 1, 2, 1, 2, - 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, - 2, 1, 1, 1, 3, 1, 3, 1, 1, 1, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, - 1, 4, 5, 5, 6, 4, 4, 6, 6, 6, - 8, 8, 8, 8, 9, 8, 5, 4, 2, 2, + 2, 4, 2, 4, 5, 4, 4, 4, 4, 3, + 3, 5, 2, 3, 3, 3, 3, 1, 1, 0, + 1, 0, 1, 1, 1, 0, 2, 2, 0, 2, + 2, 0, 2, 0, 1, 1, 2, 1, 1, 2, + 1, 1, 5, 0, 1, 0, 1, 2, 3, 0, + 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 3, 3, 2, 2, 3, + 1, 3, 2, 1, 2, 1, 2, 2, 4, 3, + 3, 6, 4, 7, 6, 1, 3, 2, 2, 2, + 2, 1, 1, 1, 3, 2, 1, 1, 1, 0, + 1, 1, 0, 3, 0, 2, 0, 2, 1, 2, + 2, 0, 1, 1, 0, 1, 1, 0, 1, 0, + 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 1, 2, 3, 5, 0, 1, 2, + 1, 1, 0, 2, 1, 3, 1, 1, 1, 3, + 3, 3, 3, 7, 0, 3, 1, 3, 1, 1, + 3, 3, 1, 3, 4, 4, 4, 3, 2, 4, + 0, 1, 0, 2, 0, 1, 0, 1, 2, 1, + 1, 1, 2, 2, 1, 2, 3, 2, 3, 2, + 2, 2, 1, 1, 3, 3, 0, 5, 4, 5, + 5, 0, 2, 1, 3, 3, 3, 2, 3, 1, + 2, 0, 3, 1, 1, 3, 3, 4, 4, 5, + 3, 4, 5, 6, 2, 1, 2, 1, 2, 1, + 2, 1, 1, 1, 1, 1, 1, 1, 0, 2, + 1, 1, 1, 3, 1, 3, 1, 1, 1, 1, + 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, + 4, 5, 5, 6, 4, 4, 6, 6, 6, 8, + 8, 8, 8, 9, 8, 5, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 8, 8, 0, 2, 3, 4, 4, - 4, 4, 4, 4, 4, 0, 3, 4, 7, 3, - 1, 1, 1, 2, 3, 3, 1, 2, 2, 1, - 2, 1, 2, 2, 1, 2, 0, 1, 0, 2, - 1, 2, 4, 0, 2, 1, 3, 5, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 0, - 3, 0, 2, 0, 3, 1, 3, 2, 0, 1, - 1, 0, 2, 4, 4, 0, 2, 2, 1, 1, - 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, - 3, 0, 3, 1, 1, 0, 4, 0, 1, 1, - 0, 3, 1, 3, 2, 1, 0, 2, 4, 0, - 9, 3, 5, 0, 3, 3, 0, 1, 0, 2, - 2, 0, 2, 2, 2, 0, 2, 1, 2, 3, - 3, 0, 2, 1, 2, 3, 4, 3, 0, 1, - 2, 1, 5, 4, 4, 1, 3, 3, 5, 0, - 5, 1, 3, 1, 2, 3, 1, 1, 3, 3, - 1, 3, 3, 3, 3, 3, 2, 1, 2, 1, - 1, 1, 1, 1, 1, 1, 0, 1, 0, 2, - 0, 3, 0, 1, 0, 1, 1, 5, 0, 1, - 0, 1, 2, 1, 1, 1, 1, 1, 1, 0, + 2, 2, 8, 8, 0, 2, 3, 4, 4, 4, + 4, 4, 4, 4, 0, 3, 4, 7, 3, 1, + 1, 1, 2, 3, 3, 1, 2, 2, 1, 2, + 1, 2, 2, 1, 2, 0, 1, 0, 2, 1, + 2, 4, 0, 2, 1, 3, 5, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 0, 3, + 0, 2, 0, 3, 1, 3, 2, 0, 1, 1, + 0, 2, 4, 4, 0, 2, 2, 1, 1, 3, + 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, + 0, 3, 1, 1, 0, 4, 0, 1, 1, 0, + 3, 1, 3, 2, 1, 0, 2, 4, 0, 9, + 3, 5, 0, 3, 3, 0, 1, 0, 2, 2, + 0, 2, 2, 2, 0, 2, 1, 2, 3, 3, + 0, 2, 1, 2, 3, 4, 3, 0, 1, 2, + 1, 5, 4, 4, 1, 3, 3, 5, 0, 5, + 1, 3, 1, 2, 3, 1, 1, 3, 3, 1, + 3, 3, 3, 3, 3, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, + 3, 0, 1, 0, 1, 1, 5, 0, 1, 0, + 1, 2, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -5066,7 +5062,7 @@ var yyR2 = [...]int{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 1, 1, } var yyChk = [...]int{ @@ -5195,344 +5191,344 @@ var yyChk = [...]int{ -165, 21, -165, 21, -165, 21, -165, 21, -165, 21, 30, 77, 78, 30, 80, 81, 82, -130, -130, -227, -169, -102, -263, 91, 91, -238, -238, 91, 90, 90, - 90, -238, -238, 91, 90, -263, 90, -269, 186, 228, - 230, 91, 91, 91, 91, 30, 90, -270, 30, 469, - 468, 470, 471, 472, 91, 30, 91, 30, 91, -192, - 83, -102, -83, 218, 157, 159, 162, 75, 90, 232, - 122, 43, 84, 171, 168, -263, -184, 173, -184, -198, - -197, -190, 90, -86, -234, 12, 132, -202, -202, -182, - -102, -234, -202, -182, -102, -182, -182, -182, -182, -202, - -202, -202, -182, -197, -197, -102, -102, -102, -102, -102, - -102, -102, -207, -207, -207, -183, 130, -182, 75, -205, - 240, 274, 441, 442, 443, 84, 353, -95, 447, 447, - 447, 447, 447, 447, -86, -86, -86, -86, -120, 100, - 114, 101, 102, -113, -121, -125, -128, 95, 132, 130, - 131, 116, -113, -113, -113, -113, -113, -113, -113, -113, - -113, -113, -113, -113, -113, -113, -113, -208, -263, 90, - 148, -263, -112, -112, -192, -75, 22, 37, -74, -193, - -198, -190, -70, -286, -286, -139, -74, -74, -86, -86, - -130, 90, -74, -130, 90, -74, -74, -69, 22, 37, - -133, -134, 118, -130, -286, -113, -192, -192, -74, -75, - -75, -74, -74, 84, -277, 323, 324, 445, -200, 203, - -199, 23, -197, 90, -123, -122, 90, -143, -286, -144, - 27, 10, 132, 84, 19, 84, -142, 25, 26, -143, - -114, -192, 91, 94, -87, 84, 12, -79, -102, -194, - 139, -198, -102, -164, 203, -102, 31, 84, -98, -100, - -99, -101, 65, 69, 71, 66, 67, 68, 72, -203, - 23, -88, -3, -285, -102, -95, -287, 84, 12, 76, - -287, 84, 154, -172, -174, 84, 322, 324, 325, 75, - 103, -86, -220, 147, -245, -244, -243, -227, -229, -230, - -231, 85, -145, -85, 39, -223, 288, 287, -218, -218, - -218, -218, -218, -219, -169, -219, -219, -219, 83, 83, - -218, -218, -218, -218, -221, 83, -221, -221, -222, 83, - -222, -256, -86, -253, -252, -250, -251, 179, 97, 353, - 76, -248, -142, 91, -83, -185, 173, -254, -251, -263, - -263, -263, -185, -263, 90, -263, 90, 84, 17, -228, - -227, -131, 228, -258, 203, -255, -249, -236, 29, -235, - -236, -236, 154, -263, 84, 27, 108, 108, 108, 108, - 353, 159, 31, -227, -131, -208, 171, -208, -208, 90, - 90, -181, 477, -95, -82, 220, 122, 209, 209, 168, - 168, 222, -102, 233, 234, 232, 21, 221, 223, 225, - 211, -102, -102, -184, 75, -97, -102, 24, -197, -102, - -182, -182, -102, -182, -182, 90, -102, -192, -66, 323, - 353, 20, -67, 20, 100, 101, 102, -121, -113, -113, - -113, -73, 193, 113, -286, -286, -74, -74, -285, 154, - -5, -143, -286, -286, 84, 76, 23, 12, 12, -286, - 12, 12, -286, -286, -74, -136, -134, 120, -86, -286, - -286, 84, 84, -286, -286, -286, -286, -286, -276, 444, - 324, -106, 73, 172, 74, -285, -199, -286, -159, 41, - 49, 60, -86, -86, -141, -159, -176, 20, 12, 56, - 56, -107, 13, -76, -88, -79, 154, -107, -111, 31, - 56, -3, -285, -285, -167, -171, -130, -89, -90, -90, - -89, -90, 65, 65, 65, 70, 65, 70, 65, -99, - -197, -286, -286, -3, -164, 76, -88, -102, -88, -104, - -197, 139, -173, -175, 326, 323, 329, -263, 90, 84, - -243, -231, -282, 100, 114, 30, 75, 285, 97, -280, - -281, 175, 174, 29, 187, 23, 40, -224, 289, -219, - -219, -220, -263, 90, 148, -220, -220, -220, -226, 90, - -226, 91, 91, 85, -32, -27, -28, 32, 79, -250, - -238, 90, 38, -192, 85, -82, -102, 114, 75, -254, - -254, -254, -197, 16, -161, -192, 84, 85, -132, 229, - -130, 85, -192, 85, 83, -236, -236, -193, -192, -285, - 168, 30, 30, -131, -132, -220, -263, 479, 478, 85, - 170, 227, -84, 336, 90, 86, -102, -102, -102, -102, - -102, 162, 159, 212, 171, -95, -102, 84, -60, 188, - 183, -202, -202, 32, 323, 456, 454, -73, 113, -113, - -113, -286, -286, -75, -193, -139, -159, -210, 148, 260, - 192, 258, 254, 274, 265, 287, 256, 288, -208, -210, - -113, -113, -113, -113, 350, -139, 121, -86, 119, -113, - -113, 169, 169, 169, -165, 42, 90, 90, 61, -102, - -137, 14, -86, 139, -143, -166, 75, -167, -124, -126, - -125, -285, -160, -286, -192, -165, -107, 84, 122, -93, - -92, 75, 76, -94, 75, -92, 65, 65, -286, -107, - -88, -107, -107, 154, 323, 327, 328, -243, 100, -113, - 10, 90, 29, 29, -102, 83, -220, -220, 85, 84, - 85, 84, 85, 84, -186, 390, 114, -28, -27, -238, - -238, 91, -263, 170, 24, -102, 75, 75, 75, 17, - 84, -227, -130, 56, -253, -161, -257, -258, -102, -112, - -132, -102, -81, 218, 226, 83, 87, -265, 76, 209, - 285, 209, -102, -60, -32, -102, -182, -182, 32, -263, - -113, -286, -143, -286, -218, -218, -218, -222, -218, 248, - -218, 248, -286, -286, 20, 20, 20, 20, -285, -65, - 346, -86, 84, 84, -285, -285, -285, -286, 90, -219, - -138, 15, 17, 28, -166, 84, -286, -286, 84, 56, - 154, -286, -139, -171, -86, -86, 83, -86, -139, -107, - -116, 83, -113, -219, 90, -219, 91, 91, 390, 30, - 80, 81, 82, 30, 77, 78, -102, -102, -102, -102, - -161, -192, 205, 85, -286, 84, -225, 353, 356, -162, - 83, 85, -262, 353, -264, -263, -192, -192, -192, -159, - -219, -263, -113, -113, -113, -113, -113, -143, 90, -113, - -113, -163, -286, -192, 175, -163, -163, -200, -219, -148, - -153, -179, -86, -122, 29, -126, 56, -3, -192, -124, - -192, -143, -161, -143, -161, 85, -220, -220, 85, 85, - -162, 206, -281, -258, 357, 357, 23, -161, -261, -260, - -193, 83, 76, -286, -286, -286, -286, -68, 132, 353, - -286, -286, -286, 84, -286, -286, -286, -106, -151, 440, - -156, 45, -154, -155, 46, -152, 47, 55, 10, -124, - 154, 85, 85, -146, 23, -285, -3, 85, 84, 122, - -161, -102, -286, 351, 72, 354, -192, 175, -148, 50, - 266, -158, -157, 54, 46, -155, 17, 48, 17, -167, - -192, -272, -273, 75, -282, -279, 100, 114, 97, -280, - 109, 110, -3, -113, 202, -58, 353, -260, -242, -193, - 90, 91, 85, 61, 352, 355, -149, 52, -147, 51, - -147, -157, 17, 17, 90, 17, 90, -273, 75, 11, - 10, 100, 90, -58, -286, -286, -59, 217, 444, -265, - 61, -150, 53, 75, 103, 90, 90, 90, -271, 188, - 183, 186, 31, -271, 180, -262, 353, 75, 103, 182, - 30, 100, 219, 354, 355, + 90, -238, -238, 91, 90, -199, -197, 90, -269, 186, + 228, 230, 91, 91, 91, 91, 30, 90, -270, 30, + 469, 468, 470, 471, 472, 91, 30, 91, 30, 91, + -192, 83, -102, -83, 218, 157, 159, 162, 75, 90, + 232, 122, 43, 84, 171, 168, -263, -184, 173, -184, + -198, -197, -190, 90, -86, -234, 12, 132, -202, -202, + -182, -102, -234, -202, -182, -102, -182, -182, -182, -182, + -202, -202, -202, -182, -197, -197, -102, -102, -102, -102, + -102, -102, -102, -207, -207, -207, -183, 130, -182, 75, + -205, 240, 274, 441, 442, 443, 84, 353, -95, 447, + 447, 447, 447, 447, 447, -86, -86, -86, -86, -120, + 100, 114, 101, 102, -113, -121, -125, -128, 95, 132, + 130, 131, 116, -113, -113, -113, -113, -113, -113, -113, + -113, -113, -113, -113, -113, -113, -113, -113, -208, -263, + 90, 148, -263, -112, -112, -192, -75, 22, 37, -74, + -193, -198, -190, -70, -286, -286, -139, -74, -74, -86, + -86, -130, 90, -74, -130, 90, -74, -74, -69, 22, + 37, -133, -134, 118, -130, -286, -113, -192, -192, -74, + -75, -75, -74, -74, 84, -277, 323, 324, 445, -200, + 203, -199, 23, -123, -122, 90, -143, -286, -144, 27, + 10, 132, 84, 19, 84, -142, 25, 26, -143, -114, + -192, 91, 94, -87, 84, 12, -79, -102, -194, 139, + -198, -102, -164, 203, -102, 31, 84, -98, -100, -99, + -101, 65, 69, 71, 66, 67, 68, 72, -203, 23, + -88, -3, -285, -102, -95, -287, 84, 12, 76, -287, + 84, 154, -172, -174, 84, 322, 324, 325, 75, 103, + -86, -220, 147, -245, -244, -243, -227, -229, -230, -231, + 85, -145, -85, 39, -223, 288, 287, -218, -218, -218, + -218, -218, -219, -169, -219, -219, -219, 83, 83, -218, + -218, -218, -218, -221, 83, -221, -221, -222, 83, -222, + -256, -86, -253, -252, -250, -251, 179, 97, 353, 76, + -248, -142, 91, -83, -185, 173, -254, -251, -263, -263, + -263, -185, -263, 90, -263, 90, 84, 17, -228, -227, + -131, 228, -258, 203, -255, -249, -236, 29, -235, -236, + -236, 154, -263, 84, 27, 108, 108, 108, 108, 353, + 159, 31, -227, -131, -208, 171, -208, -208, 90, 90, + -181, 477, -95, -82, 220, 122, 209, 209, 168, 168, + 222, -102, 233, 234, 232, 21, 221, 223, 225, 211, + -102, -102, -184, 75, -97, -102, 24, -197, -102, -182, + -182, -102, -182, -182, 90, -102, -192, -66, 323, 353, + 20, -67, 20, 100, 101, 102, -121, -113, -113, -113, + -73, 193, 113, -286, -286, -74, -74, -285, 154, -5, + -143, -286, -286, 84, 76, 23, 12, 12, -286, 12, + 12, -286, -286, -74, -136, -134, 120, -86, -286, -286, + 84, 84, -286, -286, -286, -286, -286, -276, 444, 324, + -106, 73, 172, 74, -285, -199, -286, -159, 41, 49, + 60, -86, -86, -141, -159, -176, 20, 12, 56, 56, + -107, 13, -76, -88, -79, 154, -107, -111, 31, 56, + -3, -285, -285, -167, -171, -130, -89, -90, -90, -89, + -90, 65, 65, 65, 70, 65, 70, 65, -99, -197, + -286, -286, -3, -164, 76, -88, -102, -88, -104, -197, + 139, -173, -175, 326, 323, 329, -263, 90, 84, -243, + -231, -282, 100, 114, 30, 75, 285, 97, -280, -281, + 175, 174, 29, 187, 23, 40, -224, 289, -219, -219, + -220, -263, 90, 148, -220, -220, -220, -226, 90, -226, + 91, 91, 85, -32, -27, -28, 32, 79, -250, -238, + 90, 38, -192, 85, -82, -102, 114, 75, -254, -254, + -254, -197, 16, -161, -192, 84, 85, -132, 229, -130, + 85, -192, 85, 83, -236, -236, -193, -192, -285, 168, + 30, 30, -131, -132, -220, -263, 479, 478, 85, 170, + 227, -84, 336, 90, 86, -102, -102, -102, -102, -102, + 162, 159, 212, 171, -95, -102, 84, -60, 188, 183, + -202, -202, 32, 323, 456, 454, -73, 113, -113, -113, + -286, -286, -75, -193, -139, -159, -210, 148, 260, 192, + 258, 254, 274, 265, 287, 256, 288, -208, -210, -113, + -113, -113, -113, 350, -139, 121, -86, 119, -113, -113, + 169, 169, 169, -165, 42, 90, 90, 61, -102, -137, + 14, -86, 139, -143, -166, 75, -167, -124, -126, -125, + -285, -160, -286, -192, -165, -107, 84, 122, -93, -92, + 75, 76, -94, 75, -92, 65, 65, -286, -107, -88, + -107, -107, 154, 323, 327, 328, -243, 100, -113, 10, + 90, 29, 29, -102, 83, -220, -220, 85, 84, 85, + 84, 85, 84, -186, 390, 114, -28, -27, -238, -238, + 91, -263, 170, 24, -102, 75, 75, 75, 17, 84, + -227, -130, 56, -253, -161, -257, -258, -102, -112, -132, + -102, -81, 218, 226, 83, 87, -265, 76, 209, 285, + 209, -102, -60, -32, -102, -182, -182, 32, -263, -113, + -286, -143, -286, -218, -218, -218, -222, -218, 248, -218, + 248, -286, -286, 20, 20, 20, 20, -285, -65, 346, + -86, 84, 84, -285, -285, -285, -286, 90, -219, -138, + 15, 17, 28, -166, 84, -286, -286, 84, 56, 154, + -286, -139, -171, -86, -86, 83, -86, -139, -107, -116, + 83, -113, -219, 90, -219, 91, 91, 390, 30, 80, + 81, 82, 30, 77, 78, -102, -102, -102, -102, -161, + -192, 205, 85, -286, 84, -225, 353, 356, -162, 83, + 85, -262, 353, -264, -263, -192, -192, -192, -159, -219, + -263, -113, -113, -113, -113, -113, -143, 90, -113, -113, + -163, -286, -192, 175, -163, -163, -200, -219, -148, -153, + -179, -86, -122, 29, -126, 56, -3, -192, -124, -192, + -143, -161, -143, -161, 85, -220, -220, 85, 85, -162, + 206, -281, -258, 357, 357, 23, -161, -261, -260, -193, + 83, 76, -286, -286, -286, -286, -68, 132, 353, -286, + -286, -286, 84, -286, -286, -286, -106, -151, 440, -156, + 45, -154, -155, 46, -152, 47, 55, 10, -124, 154, + 85, 85, -146, 23, -285, -3, 85, 84, 122, -161, + -102, -286, 351, 72, 354, -192, 175, -148, 50, 266, + -158, -157, 54, 46, -155, 17, 48, 17, -167, -192, + -272, -273, 75, -282, -279, 100, 114, 97, -280, 109, + 110, -3, -113, 202, -58, 353, -260, -242, -193, 90, + 91, 85, 61, 352, 355, -149, 52, -147, 51, -147, + -157, 17, 17, 90, 17, 90, -273, 75, 11, 10, + 100, 90, -58, -286, -286, -59, 217, 444, -265, 61, + -150, 53, 75, 103, 90, 90, 90, -271, 188, 183, + 186, 31, -271, 180, -262, 353, 75, 103, 182, 30, + 100, 219, 354, 355, } var yyDef = [...]int{ 34, -2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 843, 0, 575, 575, 575, 575, 575, - 575, 575, 0, 0, 575, -2, -2, 575, 979, 0, - 575, 0, 0, -2, 508, 509, 0, 511, -2, 0, - 0, 520, 1394, 1394, 570, 0, 0, 0, 0, 0, - 575, 1392, 55, 56, 526, 527, 528, 1, 3, 0, - 579, 851, 0, 0, -2, 577, 0, 0, 962, 962, - 962, 0, 86, 87, 0, 0, 0, -2, 90, -2, - 114, 115, 0, 119, 384, 345, 387, 343, 373, -2, - 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 348, 237, 237, 0, 0, -2, 336, - 336, 336, 0, 0, 0, 370, 964, 290, 237, 237, + 31, 32, 33, 842, 0, 574, 574, 574, 574, 574, + 574, 574, 0, 0, 574, -2, -2, 574, 978, 0, + 574, 0, 0, -2, 507, 508, 0, 510, -2, 0, + 0, 519, 1393, 1393, 569, 0, 0, 0, 0, 0, + 574, 1391, 55, 56, 525, 526, 527, 1, 3, 0, + 578, 850, 0, 0, -2, 576, 0, 0, 961, 961, + 961, 0, 86, 87, 0, 0, 0, -2, 90, -2, + 114, 115, 0, 119, 383, 344, 386, 342, 372, -2, + 335, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 347, 237, 237, 0, 0, -2, 335, + 335, 335, 0, 0, 0, 369, 963, 290, 237, 237, 0, 237, 237, 237, 237, 0, 0, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, - 237, 237, 867, 118, 980, 977, 978, 35, 36, 37, - 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, - 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, - 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, - 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, - 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, - 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, - 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, - 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, - 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, - 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, - 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, - 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, - 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, - 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, - 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, - 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, - 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, - 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, - 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, - 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, - 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, - 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, - 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, - 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, - 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, - 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, - 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 0, - 956, 0, 440, 664, 0, 499, 499, 0, 499, 499, - 499, 499, 0, 0, 0, 452, 0, 0, 0, 0, - 496, 0, 0, 471, 473, 0, 496, 0, 483, 499, - 1395, 1395, 1395, 947, 0, 493, 491, 505, 506, 488, - 489, 507, 510, 0, 515, 518, 973, 974, 0, 533, - 0, 1200, 525, 538, 539, 0, 571, 572, 40, 715, - 674, 0, 680, 682, 0, 717, 718, 719, 720, 721, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 747, 748, 749, 750, 828, 829, 830, 831, 832, 833, - 834, 835, 684, 685, 825, 0, 936, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 816, 0, 785, 785, - 785, 785, 785, 785, 785, 785, 785, 0, 0, 0, - 0, 0, 0, 0, -2, -2, 1394, 0, 548, 0, - 0, 843, 51, 0, 575, 580, 581, 886, 0, 0, - 843, 1393, 0, 0, -2, -2, 591, 597, 598, 599, - 600, 601, 576, 0, 604, 608, 0, 0, 0, 963, - 0, 0, 72, 0, 1357, 940, -2, -2, 0, 0, - 975, 976, 949, -2, 983, 984, 985, 986, 987, 988, - 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, - 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, - 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, - 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, - 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, - 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, - 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, - 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, - 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, - 1079, 1080, 1081, 1082, 1083, 1084, 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, 1115, 1116, 1117, 1118, - 1119, 1120, 1121, 1122, -2, 0, 0, 128, 129, 0, - 38, 263, 0, 124, 0, 257, 209, 867, 0, 0, - 0, 0, 0, 575, 0, 957, 109, 110, 116, 117, - 237, 237, 0, 118, 118, 352, 353, 354, 0, 0, - -2, 261, 0, 337, 0, 0, 251, 251, 255, 253, - 254, 0, 0, 0, 0, 0, 0, 364, 0, 365, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 424, - 0, 238, 0, 382, 383, 291, 0, 0, 0, 0, - 362, 363, 0, 0, 965, 966, 0, 0, 237, 237, + 237, 237, 866, 118, 979, 976, 977, 35, 36, 37, + 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, + 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, + 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, + 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, + 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, + 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, + 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, + 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, + 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, + 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, + 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, + 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, + 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, + 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, + 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, + 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, + 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, + 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, + 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, + 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, + 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, + 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, + 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, + 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, + 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, + 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, + 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 0, + 955, 0, 439, 663, 0, 498, 498, 0, 498, 498, + 498, 498, 0, 0, 0, 451, 0, 0, 0, 0, + 495, 0, 0, 470, 472, 0, 495, 0, 482, 498, + 1394, 1394, 1394, 946, 0, 492, 490, 504, 505, 487, + 488, 506, 509, 0, 514, 517, 972, 973, 0, 532, + 0, 1199, 524, 537, 538, 0, 570, 571, 40, 714, + 673, 0, 679, 681, 0, 716, 717, 718, 719, 720, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 746, 747, 748, 749, 827, 828, 829, 830, 831, 832, + 833, 834, 683, 684, 824, 0, 935, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 815, 0, 784, 784, + 784, 784, 784, 784, 784, 784, 784, 0, 0, 0, + 0, 0, 0, 0, -2, -2, 1393, 0, 547, 0, + 0, 842, 51, 0, 574, 579, 580, 885, 0, 0, + 842, 1392, 0, 0, -2, -2, 590, 596, 597, 598, + 599, 600, 575, 0, 603, 607, 0, 0, 0, 962, + 0, 0, 72, 0, 1356, 939, -2, -2, 0, 0, + 974, 975, 948, -2, 982, 983, 984, 985, 986, 987, + 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, + 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, + 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, + 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, + 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, + 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, + 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, + 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, + 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, + 1078, 1079, 1080, 1081, 1082, 1083, 1084, 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, 1115, 1116, 1117, + 1118, 1119, 1120, 1121, -2, 0, 0, 128, 129, 0, + 38, 263, 0, 124, 0, 257, 209, 866, 0, 0, + 0, 0, 0, 574, 0, 956, 109, 110, 116, 117, + 237, 237, 0, 118, 118, 351, 352, 353, 0, 0, + -2, 261, 0, 336, 0, 0, 251, 251, 255, 253, + 254, 0, 0, 0, 0, 0, 0, 363, 0, 364, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 423, + 0, 238, 0, 381, 382, 291, 0, 0, 0, 0, + 361, 362, 0, 0, 964, 965, 0, 0, 237, 237, 0, 0, 0, 0, 237, 237, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 108, 880, 0, 0, 0, -2, 0, 432, - 0, 0, 0, 958, 958, 439, 0, 441, 442, 0, - 0, 443, 0, 496, 496, 494, 495, 445, 446, 447, - 448, 499, 0, 0, 246, 247, 248, 496, 499, 0, - 499, 499, 499, 499, 496, 496, 496, 499, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1395, 1395, 1395, - 502, 499, 480, 481, 484, 485, 1396, 1397, 994, 486, - 487, 948, 516, 519, 536, 534, 535, 537, 529, 530, - 531, 532, 0, 550, 551, 556, 0, 0, 0, 0, - 562, 563, 564, 0, 0, 567, 568, 569, 0, 0, - 0, 0, 0, 678, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 702, 703, 704, 705, 706, 707, 708, - 681, 0, 695, 0, 0, 0, 737, 738, 739, 740, - 741, 742, 743, 744, 745, 0, 588, 0, 0, 0, - 843, 0, 0, 0, 0, 0, 0, 0, 585, 0, - 817, 0, 768, 0, 769, 777, 0, 770, 778, 771, - 779, 772, 773, 780, 774, 781, 775, 776, 782, 0, - 0, 0, 588, 588, 0, 0, 41, 540, 541, 0, - 647, 968, 0, 851, 0, 590, 889, 0, 0, 852, - 844, 845, 848, 851, 0, 613, 602, 592, 595, 596, - 578, 0, 605, 609, 0, 611, 612, 0, 0, 70, - 0, 663, 0, 615, 617, 618, 619, 645, 0, 0, - 0, 0, 66, 68, 664, 0, 1357, 946, 0, 74, - 75, 0, 0, 0, 225, 951, 952, 953, -2, 244, + 0, 0, 108, 879, 0, 0, 0, -2, 0, 431, + 0, 0, 0, 957, 957, 438, 0, 440, 441, 0, + 0, 442, 0, 495, 495, 493, 494, 444, 445, 446, + 447, 498, 0, 0, 246, 247, 248, 495, 498, 0, + 498, 498, 498, 498, 495, 495, 495, 498, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1394, 1394, 1394, + 501, 498, 479, 480, 483, 484, 1395, 1396, 993, 485, + 486, 947, 515, 518, 535, 533, 534, 536, 528, 529, + 530, 531, 0, 549, 550, 555, 0, 0, 0, 0, + 561, 562, 563, 0, 0, 566, 567, 568, 0, 0, + 0, 0, 0, 677, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 701, 702, 703, 704, 705, 706, 707, + 680, 0, 694, 0, 0, 0, 736, 737, 738, 739, + 740, 741, 742, 743, 744, 0, 587, 0, 0, 0, + 842, 0, 0, 0, 0, 0, 0, 0, 584, 0, + 816, 0, 767, 0, 768, 776, 0, 769, 777, 770, + 778, 771, 772, 779, 773, 780, 774, 775, 781, 0, + 0, 0, 587, 587, 0, 0, 41, 539, 540, 0, + 646, 967, 0, 850, 0, 589, 888, 0, 0, 851, + 843, 844, 847, 850, 0, 612, 601, 591, 594, 595, + 577, 0, 604, 608, 0, 610, 611, 0, 0, 70, + 0, 662, 0, 614, 616, 617, 618, 644, 0, 0, + 0, 0, 66, 68, 663, 0, 1356, 945, 0, 74, + 75, 0, 0, 0, 225, 950, 951, 952, -2, 244, 0, -2, 216, 160, 161, 162, 209, 164, 209, 209, 209, 209, 221, 221, 221, 221, 192, 193, 194, 195, 196, 0, 0, 179, 209, 209, 209, 209, 199, 200, 201, 202, 203, 204, 205, 206, 165, 166, 167, 168, 169, 170, 171, 172, 173, 211, 211, 211, 213, 213, - 0, 39, 0, 229, 0, 848, 0, 880, 960, 970, - 0, 0, 0, 960, 92, 0, 0, 385, 346, 374, - 386, 0, 349, 350, -2, 0, 0, 336, 0, 338, + 0, 39, 0, 229, 0, 847, 0, 879, 959, 969, + 0, 0, 0, 959, 92, 0, 0, 384, 345, 373, + 385, 0, 348, 349, -2, 0, 0, 335, 0, 337, 0, 245, 0, -2, 0, 255, 0, 251, 255, 252, - 255, 243, 256, 366, 825, 0, 367, 368, 0, 404, - 633, 0, 0, 0, 0, 0, 410, 411, 412, 0, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, - 375, 376, 377, 378, 379, 380, 381, 0, 0, 338, - 0, 371, 0, 292, 293, 0, 0, 296, 297, 298, - 299, 0, 0, 302, 303, 304, 305, 306, 330, 331, - 332, 307, 308, 309, 310, 311, 312, 313, 324, 325, - 326, 327, 328, 329, 314, 315, 316, 317, 318, 321, - 0, 102, 871, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 958, 0, 0, 0, 0, 665, - 981, 982, 500, 501, 0, 249, 250, 499, 499, 449, - 472, 0, 499, 453, 474, 454, 456, 455, 457, 476, - 477, 499, 460, 497, 498, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 478, 0, 479, 0, 0, - 517, 521, 522, 523, 524, 0, 0, 553, 558, 559, - 560, 561, 573, 566, 716, 675, 676, 677, 679, 696, - 0, 698, 700, 686, 687, 711, 712, 713, 0, 0, - 0, 0, 709, 691, 0, 722, 723, 724, 725, 726, - 727, 728, 729, 730, 731, 732, 733, 736, 800, 801, - 802, 0, 734, 735, 746, 0, 0, 0, 589, 826, - 0, -2, 0, 714, 935, 851, 0, 0, 0, 0, - 719, 828, 0, 719, 828, 0, 0, 0, 586, 587, - 823, 820, 0, 0, 786, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 543, 544, 546, 0, 667, 0, - 648, 0, 650, 651, 0, 969, 549, 886, 52, 42, - 0, 887, 0, 0, 0, 0, 847, 849, 850, 886, - 0, 836, 0, 0, 672, 0, 0, 593, 48, 610, - 606, 0, 672, 0, 0, 662, 0, 0, 0, 0, - 0, 0, 652, 0, 0, 655, 0, 0, 0, 0, - 646, 0, 0, 0, -2, 0, 0, 0, 62, 63, - 0, 0, 0, 941, 73, 0, 0, 78, 79, 942, - 943, 944, 945, 0, 111, -2, 287, 130, 132, 133, - 134, 125, 269, 0, 0, 219, 217, 218, 163, 221, - 221, 186, 187, 225, 0, 225, 225, 225, 0, 0, - 180, 181, 182, 183, 174, 0, 175, 176, 177, 0, - 178, 262, 0, 855, 230, 231, 233, 237, 0, 0, - 0, 258, 259, 0, 871, 0, 0, 0, 971, 970, - 970, 970, 0, 120, 121, 122, 123, 118, 0, 0, - 126, 340, 0, 0, 0, 260, 0, 0, 255, 255, - 240, 241, 0, 369, 0, 0, 406, 407, 408, 409, - 0, 0, 0, 338, 340, 225, 0, 294, 295, 300, - 301, 319, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 399, 400, 401, 402, 868, 869, 870, - 0, 0, 433, 0, 0, 279, 64, 959, 438, 496, - 459, 475, 496, 451, 458, 503, 482, 513, 557, 0, - 0, 0, 565, 0, 697, 699, 701, 688, 709, 692, - 0, 689, 0, 0, 683, 751, 0, 0, 588, 0, - 843, 886, 755, 756, 0, 0, 0, 0, 0, 793, - 0, 0, 794, 0, 843, 0, 821, 0, 0, 767, - 787, 0, 0, 788, 789, 790, 791, 792, 542, 545, - 547, 623, 0, 0, 0, 0, 649, 967, 44, 0, - 0, 0, 853, 854, 846, 43, 0, 954, 955, 837, - 838, 839, 0, 603, 614, 594, 0, 851, 929, 0, - 0, 921, 0, 0, 672, 937, 0, 616, 641, 643, - 0, 638, 653, 654, 656, 0, 658, 0, 660, 661, - 620, 621, 622, 0, 672, 0, 672, 67, 672, 69, - 0, 666, 76, 77, 0, 0, 83, 226, 227, 118, - 289, 131, 135, 140, 0, 0, 0, 144, 0, 146, - 270, 0, 156, 158, 0, 0, 138, 159, 220, 225, - 225, 188, 222, 223, 224, 189, 190, 191, 0, 207, - 0, 0, 0, 282, 88, 859, 858, 237, 237, 232, - 0, 235, 0, 972, 210, 0, 101, 0, 0, 0, - 0, 0, 107, 0, 344, 627, 0, 355, 356, 0, - 339, 403, 0, 229, 0, 239, 242, 826, 634, 0, - 0, 357, 0, 340, 360, 361, 372, 322, 323, 320, - 0, 0, 881, 882, 0, 885, 93, 392, 394, 393, - 397, 0, 0, 390, 0, 279, 855, 0, 437, 280, - 281, 499, 499, 552, 0, 555, 0, 690, 0, 710, - 693, 752, 753, 0, 827, 851, 46, 0, 209, 209, - 806, 209, 213, 809, 209, 811, 209, 814, 0, 0, - 0, 0, 0, 0, 0, 818, 766, 824, 0, 0, - 0, 0, 0, 0, 0, 0, 221, 891, 888, 45, - 841, 0, 673, 607, 49, 53, 0, 929, 920, 931, - 933, 0, 0, 0, 925, 0, 843, 0, 0, 635, - 642, 0, 0, 636, 0, 637, 657, 659, -2, 843, - 672, 60, 61, 0, 80, 81, 82, 288, 141, 142, - 0, 145, 155, 157, 0, 0, 184, 185, 221, 0, - 221, 0, 214, 0, 271, 283, 0, 856, 857, 0, - 0, 234, 236, 0, 961, 103, 0, 0, 0, 0, - 0, 127, 341, 0, 228, 0, 0, 428, 425, 358, - 359, 625, 872, 873, 874, 0, 884, 96, 0, 0, - 0, 0, 434, 435, 436, 65, 444, 450, 554, 574, - 694, 754, 886, 757, 803, 221, 807, 808, 810, 812, - 813, 815, 759, 758, 0, 0, 0, 0, 0, 851, - 0, 822, 0, 0, 0, 0, 0, 647, 221, 911, - 50, 0, 0, 0, 54, 0, 934, 0, 0, 0, - 0, 71, 851, 938, 939, 639, 0, 644, 851, 59, - 143, 0, 0, 225, 208, 225, 0, 0, 284, 860, - 861, 862, 863, 864, 865, 866, 625, 104, 105, 106, - 347, 628, 0, 0, 405, 0, 413, 0, 0, 0, - 0, 883, 391, 0, 94, 95, 0, 0, 396, 47, - 804, 805, 0, 0, 0, 0, 795, 0, 819, 0, - 0, 0, 669, 629, 630, 0, 0, 667, 893, 892, - 905, 918, 842, 840, 0, 932, 0, 924, 927, 923, - 926, 57, 0, 58, 0, 149, 197, 198, 212, 215, - 0, 0, 264, 429, 426, 427, 0, 0, 97, 98, - 0, 0, 0, 760, 762, 761, 763, 0, 0, 0, - 765, 783, 784, 0, 668, 670, 671, 624, 911, 0, - 904, 0, -2, 913, 0, 0, 0, 919, 0, 922, - 0, 640, 265, 269, 0, 0, 875, 626, 0, 0, - 0, 398, 764, 0, 0, 0, 631, 632, 898, 896, - 896, 906, 907, 0, 0, 914, 0, 0, 0, 930, - 928, 266, 267, 0, 136, 150, 151, 0, 0, 154, - 147, 148, 875, 0, 0, 388, 877, 99, 100, 333, - 334, 335, 93, 796, 0, 799, 901, 0, 894, 897, - 895, 908, 0, 0, 915, 0, 917, 268, 0, 0, - 0, 152, 153, 89, 430, 431, 0, 878, 879, 96, - 797, 890, 0, 899, 900, 909, 910, 916, 272, 274, - 275, 0, 0, 273, 0, 395, 0, 902, 903, 276, - 277, 278, 876, 0, 798, + 255, 243, 256, 365, 824, 0, 366, 367, 0, 403, + 632, 0, 0, 0, 0, 0, 409, 410, 411, 0, + 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 374, 375, 376, 377, 378, 379, 380, 0, 0, 337, + 0, 370, 0, 292, 293, 0, 0, 296, 297, 298, + 299, 0, 0, 302, 303, 304, 649, 650, 305, 329, + 330, 331, 306, 307, 308, 309, 310, 311, 312, 323, + 324, 325, 326, 327, 328, 313, 314, 315, 316, 317, + 320, 0, 102, 870, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 957, 0, 0, 0, 0, + 664, 980, 981, 499, 500, 0, 249, 250, 498, 498, + 448, 471, 0, 498, 452, 473, 453, 455, 454, 456, + 475, 476, 498, 459, 496, 497, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, 477, 0, 478, 0, + 0, 516, 520, 521, 522, 523, 0, 0, 552, 557, + 558, 559, 560, 572, 565, 715, 674, 675, 676, 678, + 695, 0, 697, 699, 685, 686, 710, 711, 712, 0, + 0, 0, 0, 708, 690, 0, 721, 722, 723, 724, + 725, 726, 727, 728, 729, 730, 731, 732, 735, 799, + 800, 801, 0, 733, 734, 745, 0, 0, 0, 588, + 825, 0, -2, 0, 713, 934, 850, 0, 0, 0, + 0, 718, 827, 0, 718, 827, 0, 0, 0, 585, + 586, 822, 819, 0, 0, 785, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 542, 543, 545, 0, 666, + 0, 647, 0, 0, 968, 548, 885, 52, 42, 0, + 886, 0, 0, 0, 0, 846, 848, 849, 885, 0, + 835, 0, 0, 671, 0, 0, 592, 48, 609, 605, + 0, 671, 0, 0, 661, 0, 0, 0, 0, 0, + 0, 651, 0, 0, 654, 0, 0, 0, 0, 645, + 0, 0, 0, -2, 0, 0, 0, 62, 63, 0, + 0, 0, 940, 73, 0, 0, 78, 79, 941, 942, + 943, 944, 0, 111, -2, 287, 130, 132, 133, 134, + 125, 269, 0, 0, 219, 217, 218, 163, 221, 221, + 186, 187, 225, 0, 225, 225, 225, 0, 0, 180, + 181, 182, 183, 174, 0, 175, 176, 177, 0, 178, + 262, 0, 854, 230, 231, 233, 237, 0, 0, 0, + 258, 259, 0, 870, 0, 0, 0, 970, 969, 969, + 969, 0, 120, 121, 122, 123, 118, 0, 0, 126, + 339, 0, 0, 0, 260, 0, 0, 255, 255, 240, + 241, 0, 368, 0, 0, 405, 406, 407, 408, 0, + 0, 0, 337, 339, 225, 0, 294, 295, 300, 301, + 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 398, 399, 400, 401, 867, 868, 869, 0, + 0, 432, 0, 0, 279, 64, 958, 437, 495, 458, + 474, 495, 450, 457, 502, 481, 512, 556, 0, 0, + 0, 564, 0, 696, 698, 700, 687, 708, 691, 0, + 688, 0, 0, 682, 750, 0, 0, 587, 0, 842, + 885, 754, 755, 0, 0, 0, 0, 0, 792, 0, + 0, 793, 0, 842, 0, 820, 0, 0, 766, 786, + 0, 0, 787, 788, 789, 790, 791, 541, 544, 546, + 622, 0, 0, 0, 0, 648, 966, 44, 0, 0, + 0, 852, 853, 845, 43, 0, 953, 954, 836, 837, + 838, 0, 602, 613, 593, 0, 850, 928, 0, 0, + 920, 0, 0, 671, 936, 0, 615, 640, 642, 0, + 637, 652, 653, 655, 0, 657, 0, 659, 660, 619, + 620, 621, 0, 671, 0, 671, 67, 671, 69, 0, + 665, 76, 77, 0, 0, 83, 226, 227, 118, 289, + 131, 135, 140, 0, 0, 0, 144, 0, 146, 270, + 0, 156, 158, 0, 0, 138, 159, 220, 225, 225, + 188, 222, 223, 224, 189, 190, 191, 0, 207, 0, + 0, 0, 282, 88, 858, 857, 237, 237, 232, 0, + 235, 0, 971, 210, 0, 101, 0, 0, 0, 0, + 0, 107, 0, 343, 626, 0, 354, 355, 0, 338, + 402, 0, 229, 0, 239, 242, 825, 633, 0, 0, + 356, 0, 339, 359, 360, 371, 321, 322, 319, 0, + 0, 880, 881, 0, 884, 93, 391, 393, 392, 396, + 0, 0, 389, 0, 279, 854, 0, 436, 280, 281, + 498, 498, 551, 0, 554, 0, 689, 0, 709, 692, + 751, 752, 0, 826, 850, 46, 0, 209, 209, 805, + 209, 213, 808, 209, 810, 209, 813, 0, 0, 0, + 0, 0, 0, 0, 817, 765, 823, 0, 0, 0, + 0, 0, 0, 0, 0, 221, 890, 887, 45, 840, + 0, 672, 606, 49, 53, 0, 928, 919, 930, 932, + 0, 0, 0, 924, 0, 842, 0, 0, 634, 641, + 0, 0, 635, 0, 636, 656, 658, -2, 842, 671, + 60, 61, 0, 80, 81, 82, 288, 141, 142, 0, + 145, 155, 157, 0, 0, 184, 185, 221, 0, 221, + 0, 214, 0, 271, 283, 0, 855, 856, 0, 0, + 234, 236, 0, 960, 103, 0, 0, 0, 0, 0, + 127, 340, 0, 228, 0, 0, 427, 424, 357, 358, + 624, 871, 872, 873, 0, 883, 96, 0, 0, 0, + 0, 433, 434, 435, 65, 443, 449, 553, 573, 693, + 753, 885, 756, 802, 221, 806, 807, 809, 811, 812, + 814, 758, 757, 0, 0, 0, 0, 0, 850, 0, + 821, 0, 0, 0, 0, 0, 646, 221, 910, 50, + 0, 0, 0, 54, 0, 933, 0, 0, 0, 0, + 71, 850, 937, 938, 638, 0, 643, 850, 59, 143, + 0, 0, 225, 208, 225, 0, 0, 284, 859, 860, + 861, 862, 863, 864, 865, 624, 104, 105, 106, 346, + 627, 0, 0, 404, 0, 412, 0, 0, 0, 0, + 882, 390, 0, 94, 95, 0, 0, 395, 47, 803, + 804, 0, 0, 0, 0, 794, 0, 818, 0, 0, + 0, 668, 628, 629, 0, 0, 666, 892, 891, 904, + 917, 841, 839, 0, 931, 0, 923, 926, 922, 925, + 57, 0, 58, 0, 149, 197, 198, 212, 215, 0, + 0, 264, 428, 425, 426, 0, 0, 97, 98, 0, + 0, 0, 759, 761, 760, 762, 0, 0, 0, 764, + 782, 783, 0, 667, 669, 670, 623, 910, 0, 903, + 0, -2, 912, 0, 0, 0, 918, 0, 921, 0, + 639, 265, 269, 0, 0, 874, 625, 0, 0, 0, + 397, 763, 0, 0, 0, 630, 631, 897, 895, 895, + 905, 906, 0, 0, 913, 0, 0, 0, 929, 927, + 266, 267, 0, 136, 150, 151, 0, 0, 154, 147, + 148, 874, 0, 0, 387, 876, 99, 100, 332, 333, + 334, 93, 795, 0, 798, 900, 0, 893, 896, 894, + 907, 0, 0, 914, 0, 916, 268, 0, 0, 0, + 152, 153, 89, 429, 430, 0, 877, 878, 96, 796, + 889, 0, 898, 899, 908, 909, 915, 272, 274, 275, + 0, 0, 273, 0, 394, 0, 901, 902, 276, 277, + 278, 875, 0, 797, } var yyTok1 = [...]int{ @@ -7997,7 +7993,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1823 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: yyDollar[3].colIdent.String()} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: yyDollar[3].tableIdent.String()} } yyVAL.union = yyLOCAL case 305: @@ -8005,7 +8001,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1827 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 306: @@ -8013,7 +8009,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1831 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 307: @@ -8045,7 +8041,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1847 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 311: @@ -8053,7 +8049,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1851 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 312: @@ -8061,7 +8057,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1855 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewStrLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 313: @@ -8069,7 +8065,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1859 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 314: @@ -8077,7 +8073,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1863 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 315: @@ -8085,7 +8081,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1867 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 316: @@ -8093,7 +8089,7 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1871 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 317: @@ -8101,38 +8097,36 @@ yydefault: var yyLOCAL *TableOption //line sql.y:1875 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: string(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 318: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *TableOption //line sql.y:1879 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Value: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: (yyDollar[3].colIdent.String() + yyDollar[4].str)} } yyVAL.union = yyLOCAL case 319: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *TableOption //line sql.y:1883 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), String: (yyDollar[3].colIdent.String() + yyDollar[4].str)} + yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Tables: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL case 320: - yyDollar = yyS[yypt-5 : yypt+1] - var yyLOCAL *TableOption -//line sql.y:1887 + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:1888 { - yyLOCAL = &TableOption{Name: string(yyDollar[1].str), Tables: yyDollar[4].tableNamesUnion()} + yyVAL.str = "" } - yyVAL.union = yyLOCAL case 321: - yyDollar = yyS[yypt-0 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:1892 { - yyVAL.str = "" + yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 322: yyDollar = yyS[yypt-2 : yypt+1] @@ -8140,144 +8134,146 @@ yydefault: { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) } - case 323: - yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:1900 + case 332: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:1915 { - yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyVAL.str = yyDollar[1].colIdent.String() } case 333: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1919 { - yyVAL.str = yyDollar[1].colIdent.String() + yyVAL.str = encodeSQLString(yyDollar[1].str) } case 334: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:1923 - { - yyVAL.str = encodeSQLString(yyDollar[1].str) - } - case 335: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:1927 { yyVAL.str = string(yyDollar[1].str) } - case 336: + case 335: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:1932 +//line sql.y:1928 { yyVAL.str = "" } - case 338: + case 337: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColName -//line sql.y:1938 +//line sql.y:1934 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 339: + case 338: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColName -//line sql.y:1942 +//line sql.y:1938 { yyLOCAL = yyDollar[2].colNameUnion() } yyVAL.union = yyLOCAL - case 340: + case 339: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ColName -//line sql.y:1947 +//line sql.y:1943 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 341: + case 340: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ColName -//line sql.y:1951 +//line sql.y:1947 { yyLOCAL = yyDollar[2].colNameUnion() } yyVAL.union = yyLOCAL - case 342: + case 341: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:1956 +//line sql.y:1952 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 343: + case 342: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:1960 +//line sql.y:1956 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL - case 344: + case 343: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:1964 +//line sql.y:1960 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &OrderByOption{Cols: yyDollar[5].columnsUnion()}) } - case 345: + case 344: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:1968 +//line sql.y:1964 { yyLOCAL = yyDollar[1].alterOptionsUnion() } yyVAL.union = yyLOCAL - case 346: + case 345: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1972 +//line sql.y:1968 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionsUnion()...) } - case 347: + case 346: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:1976 +//line sql.y:1972 { yyLOCAL = append(append(yyDollar[1].alterOptionsUnion(), yyDollar[3].alterOptionsUnion()...), &OrderByOption{Cols: yyDollar[7].columnsUnion()}) } yyVAL.union = yyLOCAL - case 348: + case 347: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:1982 +//line sql.y:1978 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 349: + case 348: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1986 +//line sql.y:1982 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - case 350: + case 349: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:1990 +//line sql.y:1986 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } - case 351: + case 350: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption -//line sql.y:1996 +//line sql.y:1992 { yyLOCAL = yyDollar[1].tableOptionsUnion() } yyVAL.union = yyLOCAL + case 351: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:1996 + { + yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} + } + yyVAL.union = yyLOCAL case 352: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption @@ -8291,15 +8287,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2004 { - yyLOCAL = &AddConstraintDefinition{ConstraintDefinition: yyDollar[2].constraintDefinitionUnion()} + yyLOCAL = &AddIndexDefinition{IndexDefinition: yyDollar[2].indexDefinitionUnion()} } yyVAL.union = yyLOCAL case 354: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:2008 { - yyLOCAL = &AddIndexDefinition{IndexDefinition: yyDollar[2].indexDefinitionUnion()} + yyLOCAL = &AddColumns{Columns: yyDollar[4].columnDefinitionsUnion()} } yyVAL.union = yyLOCAL case 355: @@ -8307,7 +8303,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2012 { - yyLOCAL = &AddColumns{Columns: yyDollar[4].columnDefinitionsUnion()} + yyLOCAL = &AddColumns{Columns: []*ColumnDefinition{yyDollar[3].columnDefinitionUnion()}, First: yyDollar[4].colNameUnion(), After: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL case 356: @@ -8315,15 +8311,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2016 { - yyLOCAL = &AddColumns{Columns: []*ColumnDefinition{yyDollar[3].columnDefinitionUnion()}, First: yyDollar[4].colNameUnion(), After: yyDollar[5].colNameUnion()} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: true} } yyVAL.union = yyLOCAL case 357: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL AlterOption //line sql.y:2020 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: true} + yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL case 358: @@ -8331,15 +8327,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2024 { - yyLOCAL = &AlterColumn{Column: yyDollar[3].colNameUnion(), DropDefault: false, DefaultVal: yyDollar[6].exprUnion()} + yyLOCAL = &ChangeColumn{OldColumn: yyDollar[3].colNameUnion(), NewColDefinition: yyDollar[4].columnDefinitionUnion(), First: yyDollar[5].colNameUnion(), After: yyDollar[6].colNameUnion()} } yyVAL.union = yyLOCAL case 359: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption //line sql.y:2028 { - yyLOCAL = &ChangeColumn{OldColumn: yyDollar[3].colNameUnion(), NewColDefinition: yyDollar[4].columnDefinitionUnion(), First: yyDollar[5].colNameUnion(), After: yyDollar[6].colNameUnion()} + yyLOCAL = &ModifyColumn{NewColDefinition: yyDollar[3].columnDefinitionUnion(), First: yyDollar[4].colNameUnion(), After: yyDollar[5].colNameUnion()} } yyVAL.union = yyLOCAL case 360: @@ -8347,15 +8343,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2032 { - yyLOCAL = &ModifyColumn{NewColDefinition: yyDollar[3].columnDefinitionUnion(), First: yyDollar[4].colNameUnion(), After: yyDollar[5].colNameUnion()} + yyLOCAL = &AlterCharset{CharacterSet: yyDollar[4].str, Collate: yyDollar[5].str} } yyVAL.union = yyLOCAL case 361: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:2036 { - yyLOCAL = &AlterCharset{CharacterSet: yyDollar[4].str, Collate: yyDollar[5].str} + yyLOCAL = &KeyState{Enable: false} } yyVAL.union = yyLOCAL case 362: @@ -8363,7 +8359,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2040 { - yyLOCAL = &KeyState{Enable: false} + yyLOCAL = &KeyState{Enable: true} } yyVAL.union = yyLOCAL case 363: @@ -8371,7 +8367,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2044 { - yyLOCAL = &KeyState{Enable: true} + yyLOCAL = &TablespaceOperation{Import: false} } yyVAL.union = yyLOCAL case 364: @@ -8379,15 +8375,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2048 { - yyLOCAL = &TablespaceOperation{Import: false} + yyLOCAL = &TablespaceOperation{Import: true} } yyVAL.union = yyLOCAL case 365: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption //line sql.y:2052 { - yyLOCAL = &TablespaceOperation{Import: true} + yyLOCAL = &DropColumn{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL case 366: @@ -8395,72 +8391,72 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2056 { - yyLOCAL = &DropColumn{Name: yyDollar[3].colNameUnion()} + yyLOCAL = &DropKey{Type: NormalKeyType, Name: yyDollar[3].colIdent} } yyVAL.union = yyLOCAL case 367: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption //line sql.y:2060 - { - yyLOCAL = &DropKey{Type: NormalKeyType, Name: yyDollar[3].colIdent} - } - yyVAL.union = yyLOCAL - case 368: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:2064 { yyLOCAL = &DropKey{Type: PrimaryKeyType} } yyVAL.union = yyLOCAL - case 369: + case 368: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2068 +//line sql.y:2064 { yyLOCAL = &DropKey{Type: ForeignKeyType, Name: yyDollar[4].colIdent} } yyVAL.union = yyLOCAL - case 370: + case 369: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2072 +//line sql.y:2068 { yyLOCAL = &Force{} } yyVAL.union = yyLOCAL - case 371: + case 370: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2076 +//line sql.y:2072 { yyLOCAL = &RenameTableName{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 372: + case 371: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL AlterOption -//line sql.y:2080 +//line sql.y:2076 { yyLOCAL = &RenameIndex{OldName: yyDollar[3].colIdent, NewName: yyDollar[5].colIdent} } yyVAL.union = yyLOCAL - case 373: + case 372: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:2086 +//line sql.y:2082 { yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL - case 374: + case 373: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2090 +//line sql.y:2086 { yySLICE := (*[]AlterOption)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].alterOptionUnion()) } + case 374: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:2092 + { + yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) + } + yyVAL.union = yyLOCAL case 375: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption @@ -8482,7 +8478,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2104 { - yyLOCAL = AlgorithmValue(string(yyDollar[3].str)) + yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL case 378: @@ -8490,7 +8486,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2108 { - yyLOCAL = &LockOption{Type: DefaultType} + yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL case 379: @@ -8498,7 +8494,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2112 { - yyLOCAL = &LockOption{Type: NoneType} + yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL case 380: @@ -8506,47 +8502,39 @@ yydefault: var yyLOCAL AlterOption //line sql.y:2116 { - yyLOCAL = &LockOption{Type: SharedType} + yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL case 381: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:2120 { - yyLOCAL = &LockOption{Type: ExclusiveType} + yyLOCAL = &Validation{With: true} } yyVAL.union = yyLOCAL case 382: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL AlterOption //line sql.y:2124 - { - yyLOCAL = &Validation{With: true} - } - yyVAL.union = yyLOCAL - case 383: - yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:2128 { yyLOCAL = &Validation{With: false} } yyVAL.union = yyLOCAL - case 384: + case 383: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2134 +//line sql.y:2130 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 385: + case 384: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:2140 +//line sql.y:2136 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -8554,10 +8542,10 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 386: + case 385: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:2147 +//line sql.y:2143 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().AlterOptions = yyDollar[2].alterOptionsUnion() @@ -8565,28 +8553,28 @@ yydefault: yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 387: + case 386: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2154 +//line sql.y:2150 { yyDollar[1].alterTableUnion().FullyParsed = true yyDollar[1].alterTableUnion().PartitionSpec = yyDollar[2].partSpecUnion() yyLOCAL = yyDollar[1].alterTableUnion() } yyVAL.union = yyLOCAL - case 388: + case 387: yyDollar = yyS[yypt-11 : yypt+1] var yyLOCAL Statement -//line sql.y:2160 +//line sql.y:2156 { yyLOCAL = &AlterView{ViewName: yyDollar[7].tableName.ToViewName(), Algorithm: yyDollar[3].str, Definer: yyDollar[4].str, Security: yyDollar[5].str, Columns: yyDollar[8].columnsUnion(), Select: yyDollar[10].selStmtUnion(), CheckOption: yyDollar[11].str} } yyVAL.union = yyLOCAL - case 389: + case 388: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2164 +//line sql.y:2160 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].tableIdent @@ -8594,10 +8582,10 @@ yydefault: yyLOCAL = yyDollar[1].alterDatabaseUnion() } yyVAL.union = yyLOCAL - case 390: + case 389: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2171 +//line sql.y:2167 { yyDollar[1].alterDatabaseUnion().FullyParsed = true yyDollar[1].alterDatabaseUnion().DBName = yyDollar[2].tableIdent @@ -8605,10 +8593,10 @@ yydefault: yyLOCAL = yyDollar[1].alterDatabaseUnion() } yyVAL.union = yyLOCAL - case 391: + case 390: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:2178 +//line sql.y:2174 { yyLOCAL = &AlterVschema{ Action: CreateVindexDDLAction, @@ -8621,10 +8609,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 392: + case 391: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2190 +//line sql.y:2186 { yyLOCAL = &AlterVschema{ Action: DropVindexDDLAction, @@ -8635,26 +8623,26 @@ yydefault: } } yyVAL.union = yyLOCAL - case 393: + case 392: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2200 +//line sql.y:2196 { yyLOCAL = &AlterVschema{Action: AddVschemaTableDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 394: + case 393: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2204 +//line sql.y:2200 { yyLOCAL = &AlterVschema{Action: DropVschemaTableDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 395: + case 394: yyDollar = yyS[yypt-13 : yypt+1] var yyLOCAL Statement -//line sql.y:2208 +//line sql.y:2204 { yyLOCAL = &AlterVschema{ Action: AddColVindexDDLAction, @@ -8668,10 +8656,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 396: + case 395: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Statement -//line sql.y:2221 +//line sql.y:2217 { yyLOCAL = &AlterVschema{ Action: DropColVindexDDLAction, @@ -8682,18 +8670,18 @@ yydefault: } } yyVAL.union = yyLOCAL - case 397: + case 396: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2231 +//line sql.y:2227 { yyLOCAL = &AlterVschema{Action: AddSequenceDDLAction, Table: yyDollar[6].tableName} } yyVAL.union = yyLOCAL - case 398: + case 397: yyDollar = yyS[yypt-10 : yypt+1] var yyLOCAL Statement -//line sql.y:2235 +//line sql.y:2231 { yyLOCAL = &AlterVschema{ Action: AddAutoIncDDLAction, @@ -8705,10 +8693,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 399: + case 398: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2246 +//line sql.y:2242 { yyLOCAL = &AlterMigration{ Type: RetryMigrationType, @@ -8716,10 +8704,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 400: + case 399: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2253 +//line sql.y:2249 { yyLOCAL = &AlterMigration{ Type: CompleteMigrationType, @@ -8727,10 +8715,10 @@ yydefault: } } yyVAL.union = yyLOCAL - case 401: + case 400: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2260 +//line sql.y:2256 { yyLOCAL = &AlterMigration{ Type: CancelMigrationType, @@ -8738,46 +8726,54 @@ yydefault: } } yyVAL.union = yyLOCAL - case 402: + case 401: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2267 +//line sql.y:2263 { yyLOCAL = &AlterMigration{ Type: CancelAllMigrationType, } } yyVAL.union = yyLOCAL - case 403: + case 402: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:2275 +//line sql.y:2271 { yyLOCAL = &PartitionSpec{Action: AddAction, Definitions: []*PartitionDefinition{yyDollar[4].partDefUnion()}} } yyVAL.union = yyLOCAL - case 404: + case 403: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:2279 +//line sql.y:2275 { yyLOCAL = &PartitionSpec{Action: DropAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL - case 405: + case 404: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:2283 +//line sql.y:2279 { yyLOCAL = &PartitionSpec{Action: ReorganizeAction, Names: yyDollar[3].partitionsUnion(), Definitions: yyDollar[6].partDefsUnion()} } yyVAL.union = yyLOCAL + case 405: + yyDollar = yyS[yypt-4 : yypt+1] + var yyLOCAL *PartitionSpec +//line sql.y:2283 + { + yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} + } + yyVAL.union = yyLOCAL case 406: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:2287 { - yyLOCAL = &PartitionSpec{Action: DiscardAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} } yyVAL.union = yyLOCAL case 407: @@ -8785,7 +8781,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2291 { - yyLOCAL = &PartitionSpec{Action: DiscardAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 408: @@ -8793,15 +8789,15 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2295 { - yyLOCAL = &PartitionSpec{Action: ImportAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} } yyVAL.union = yyLOCAL case 409: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:2299 { - yyLOCAL = &PartitionSpec{Action: ImportAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 410: @@ -8809,7 +8805,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2303 { - yyLOCAL = &PartitionSpec{Action: TruncateAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} } yyVAL.union = yyLOCAL case 411: @@ -8817,23 +8813,23 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2307 { - yyLOCAL = &PartitionSpec{Action: TruncateAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} } yyVAL.union = yyLOCAL case 412: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:2311 { - yyLOCAL = &PartitionSpec{Action: CoalesceAction, Number: NewIntLiteral(yyDollar[3].str)} + yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].colIdent}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} } yyVAL.union = yyLOCAL case 413: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:2315 { - yyLOCAL = &PartitionSpec{Action: ExchangeAction, Names: Partitions{yyDollar[3].colIdent}, TableName: yyDollar[6].tableName, WithoutValidation: yyDollar[7].booleanUnion()} + yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 414: @@ -8841,7 +8837,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2319 { - yyLOCAL = &PartitionSpec{Action: AnalyzeAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} } yyVAL.union = yyLOCAL case 415: @@ -8849,7 +8845,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2323 { - yyLOCAL = &PartitionSpec{Action: AnalyzeAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 416: @@ -8857,7 +8853,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2327 { - yyLOCAL = &PartitionSpec{Action: CheckAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} } yyVAL.union = yyLOCAL case 417: @@ -8865,7 +8861,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2331 { - yyLOCAL = &PartitionSpec{Action: CheckAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 418: @@ -8873,7 +8869,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2335 { - yyLOCAL = &PartitionSpec{Action: OptimizeAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} } yyVAL.union = yyLOCAL case 419: @@ -8881,7 +8877,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2339 { - yyLOCAL = &PartitionSpec{Action: OptimizeAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 420: @@ -8889,7 +8885,7 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2343 { - yyLOCAL = &PartitionSpec{Action: RebuildAction, Names: yyDollar[3].partitionsUnion()} + yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} } yyVAL.union = yyLOCAL case 421: @@ -8897,123 +8893,115 @@ yydefault: var yyLOCAL *PartitionSpec //line sql.y:2347 { - yyLOCAL = &PartitionSpec{Action: RebuildAction, IsAll: true} + yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} } yyVAL.union = yyLOCAL case 422: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *PartitionSpec //line sql.y:2351 - { - yyLOCAL = &PartitionSpec{Action: RepairAction, Names: yyDollar[3].partitionsUnion()} - } - yyVAL.union = yyLOCAL - case 423: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL *PartitionSpec -//line sql.y:2355 { yyLOCAL = &PartitionSpec{Action: RepairAction, IsAll: true} } yyVAL.union = yyLOCAL - case 424: + case 423: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *PartitionSpec -//line sql.y:2359 +//line sql.y:2355 { yyLOCAL = &PartitionSpec{Action: UpgradeAction} } yyVAL.union = yyLOCAL - case 425: + case 424: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2364 +//line sql.y:2360 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 426: + case 425: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:2368 +//line sql.y:2364 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 427: + case 426: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:2372 +//line sql.y:2368 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 428: + case 427: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*PartitionDefinition -//line sql.y:2379 +//line sql.y:2375 { yyLOCAL = []*PartitionDefinition{yyDollar[1].partDefUnion()} } yyVAL.union = yyLOCAL - case 429: + case 428: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2383 +//line sql.y:2379 { yySLICE := (*[]*PartitionDefinition)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].partDefUnion()) } - case 430: + case 429: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *PartitionDefinition -//line sql.y:2389 +//line sql.y:2385 { yyLOCAL = &PartitionDefinition{Name: yyDollar[2].colIdent, Limit: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 431: + case 430: yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL *PartitionDefinition -//line sql.y:2393 +//line sql.y:2389 { yyLOCAL = &PartitionDefinition{Name: yyDollar[2].colIdent, Maxvalue: true} } yyVAL.union = yyLOCAL - case 432: + case 431: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2399 +//line sql.y:2395 { yyLOCAL = &RenameTable{TablePairs: yyDollar[3].renameTablePairsUnion()} } yyVAL.union = yyLOCAL - case 433: + case 432: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL []*RenameTablePair -//line sql.y:2405 +//line sql.y:2401 { yyLOCAL = []*RenameTablePair{{FromTable: yyDollar[1].tableName, ToTable: yyDollar[3].tableName}} } yyVAL.union = yyLOCAL - case 434: + case 433: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:2409 +//line sql.y:2405 { yySLICE := (*[]*RenameTablePair)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, &RenameTablePair{FromTable: yyDollar[3].tableName, ToTable: yyDollar[5].tableName}) } - case 435: + case 434: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:2415 +//line sql.y:2411 { yyLOCAL = &DropTable{FromTables: yyDollar[6].tableNamesUnion(), IfExists: yyDollar[5].booleanUnion(), Comments: Comments(yyDollar[2].strs), Temp: yyDollar[3].booleanUnion()} } yyVAL.union = yyLOCAL - case 436: + case 435: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:2419 +//line sql.y:2415 { // Change this to an alter statement if yyDollar[4].colIdent.Lowered() == "primary" { @@ -9023,68 +9011,76 @@ yydefault: } } yyVAL.union = yyLOCAL - case 437: + case 436: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2428 +//line sql.y:2424 { yyLOCAL = &DropView{FromTables: yyDollar[5].tableNamesUnion(), IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 438: + case 437: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2432 +//line sql.y:2428 { yyLOCAL = &DropDatabase{Comments: Comments(yyDollar[2].strs), DBName: yyDollar[5].tableIdent, IfExists: yyDollar[4].booleanUnion()} } yyVAL.union = yyLOCAL - case 439: + case 438: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2438 +//line sql.y:2434 { yyLOCAL = &TruncateTable{Table: yyDollar[3].tableName} } yyVAL.union = yyLOCAL - case 440: + case 439: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2442 +//line sql.y:2438 { yyLOCAL = &TruncateTable{Table: yyDollar[2].tableName} } yyVAL.union = yyLOCAL - case 441: + case 440: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2447 +//line sql.y:2443 { yyLOCAL = &OtherRead{} } yyVAL.union = yyLOCAL + case 441: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL Statement +//line sql.y:2449 + { + yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} + } + yyVAL.union = yyLOCAL case 442: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:2453 { - yyLOCAL = &Show{&ShowBasic{Command: Charset, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 443: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement //line sql.y:2457 { - yyLOCAL = &Show{&ShowBasic{Command: Collation, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].tableIdent, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL case 444: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:2461 { - yyLOCAL = &Show{&ShowBasic{Full: yyDollar[2].booleanUnion(), Command: Column, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].tableIdent, Filter: yyDollar[7].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 445: @@ -9100,7 +9096,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2469 { - yyLOCAL = &Show{&ShowBasic{Command: Database, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} } yyVAL.union = yyLOCAL case 447: @@ -9112,43 +9108,43 @@ yydefault: } yyVAL.union = yyLOCAL case 448: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:2477 { - yyLOCAL = &Show{&ShowBasic{Command: Keyspace, Filter: yyDollar[3].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 449: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement //line sql.y:2481 { - yyLOCAL = &Show{&ShowBasic{Command: Function, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].tableIdent, Filter: yyDollar[7].showFilterUnion()}} } yyVAL.union = yyLOCAL case 450: - yyDollar = yyS[yypt-7 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:2485 { - yyLOCAL = &Show{&ShowBasic{Command: Index, Tbl: yyDollar[5].tableName, DbName: yyDollar[6].tableIdent, Filter: yyDollar[7].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].tableIdent, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL case 451: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:2489 { - yyLOCAL = &Show{&ShowBasic{Command: OpenTable, DbName: yyDollar[4].tableIdent, Filter: yyDollar[5].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Privilege}} } yyVAL.union = yyLOCAL case 452: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:2493 { - yyLOCAL = &Show{&ShowBasic{Command: Privilege}} + yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 453: @@ -9156,7 +9152,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2497 { - yyLOCAL = &Show{&ShowBasic{Command: Procedure, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 454: @@ -9164,7 +9160,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2501 { - yyLOCAL = &Show{&ShowBasic{Command: StatusSession, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 455: @@ -9172,7 +9168,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2505 { - yyLOCAL = &Show{&ShowBasic{Command: StatusGlobal, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 456: @@ -9180,15 +9176,15 @@ yydefault: var yyLOCAL Statement //line sql.y:2509 { - yyLOCAL = &Show{&ShowBasic{Command: VariableSession, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 457: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:2513 { - yyLOCAL = &Show{&ShowBasic{Command: VariableGlobal, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].tableIdent, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL case 458: @@ -9196,15 +9192,15 @@ yydefault: var yyLOCAL Statement //line sql.y:2517 { - yyLOCAL = &Show{&ShowBasic{Command: TableStatus, DbName: yyDollar[4].tableIdent, Filter: yyDollar[5].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].tableIdent, Filter: yyDollar[5].showFilterUnion()}} } yyVAL.union = yyLOCAL case 459: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:2521 { - yyLOCAL = &Show{&ShowBasic{Command: Table, Full: yyDollar[2].booleanUnion(), DbName: yyDollar[4].tableIdent, Filter: yyDollar[5].showFilterUnion()}} + yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].tableIdent, Filter: yyDollar[4].showFilterUnion()}} } yyVAL.union = yyLOCAL case 460: @@ -9212,7 +9208,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2525 { - yyLOCAL = &Show{&ShowBasic{Command: Trigger, DbName: yyDollar[3].tableIdent, Filter: yyDollar[4].showFilterUnion()}} + yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 461: @@ -9220,7 +9216,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2529 { - yyLOCAL = &Show{&ShowCreate{Command: CreateDb, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 462: @@ -9228,7 +9224,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2533 { - yyLOCAL = &Show{&ShowCreate{Command: CreateE, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 463: @@ -9236,7 +9232,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2537 { - yyLOCAL = &Show{&ShowCreate{Command: CreateF, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 464: @@ -9244,7 +9240,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2541 { - yyLOCAL = &Show{&ShowCreate{Command: CreateProc, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 465: @@ -9252,7 +9248,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2545 { - yyLOCAL = &Show{&ShowCreate{Command: CreateTbl, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 466: @@ -9260,7 +9256,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2549 { - yyLOCAL = &Show{&ShowCreate{Command: CreateTr, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} } yyVAL.union = yyLOCAL case 467: @@ -9268,7 +9264,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2553 { - yyLOCAL = &Show{&ShowCreate{Command: CreateV, Op: yyDollar[4].tableName}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 468: @@ -9276,7 +9272,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2557 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].colIdent.String()), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 469: @@ -9284,55 +9280,55 @@ yydefault: var yyLOCAL Statement //line sql.y:2561 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].colIdent.String()), Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 470: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:2565 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 471: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:2569 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str), Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Table: yyDollar[4].tableName, Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 472: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement //line sql.y:2573 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Table: yyDollar[4].tableName, Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 473: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:2577 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str), Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Table: yyDollar[4].tableName, Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 474: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement //line sql.y:2581 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Table: yyDollar[4].tableName, Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[3].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 475: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement //line sql.y:2585 { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[3].str), Scope: ImplicitScope}} + yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].tableIdent}} } yyVAL.union = yyLOCAL case 476: @@ -9340,7 +9336,7 @@ yydefault: var yyLOCAL Statement //line sql.y:2589 { - yyLOCAL = &Show{&ShowBasic{Command: GtidExecGlobal, DbName: yyDollar[4].tableIdent}} + yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].tableIdent}} } yyVAL.union = yyLOCAL case 477: @@ -9348,24 +9344,24 @@ yydefault: var yyLOCAL Statement //line sql.y:2593 { - yyLOCAL = &Show{&ShowBasic{Command: VGtidExecGlobal, DbName: yyDollar[4].tableIdent}} + showTablesOpt := &ShowTablesOpt{Filter: yyDollar[4].showFilterUnion()} + yyLOCAL = &Show{&ShowLegacy{Scope: VitessMetadataScope, Type: string(yyDollar[3].str), ShowTablesOpt: showTablesOpt}} } yyVAL.union = yyLOCAL case 478: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:2597 +//line sql.y:2598 { - showTablesOpt := &ShowTablesOpt{Filter: yyDollar[4].showFilterUnion()} - yyLOCAL = &Show{&ShowLegacy{Scope: VitessMetadataScope, Type: string(yyDollar[3].str), ShowTablesOpt: showTablesOpt}} + yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].tableIdent}} } yyVAL.union = yyLOCAL case 479: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement //line sql.y:2602 { - yyLOCAL = &Show{&ShowBasic{Command: VitessMigrations, Filter: yyDollar[4].showFilterUnion(), DbName: yyDollar[3].tableIdent}} + yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL case 480: @@ -9377,33 +9373,25 @@ yydefault: } yyVAL.union = yyLOCAL case 481: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL Statement -//line sql.y:2610 - { - yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), Scope: ImplicitScope}} - } - yyVAL.union = yyLOCAL - case 482: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2614 +//line sql.y:2610 { yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str) + " " + string(yyDollar[3].str), OnTable: yyDollar[5].tableName, Scope: ImplicitScope}} } yyVAL.union = yyLOCAL - case 483: + case 482: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2618 +//line sql.y:2614 { yyLOCAL = &Show{&ShowBasic{Command: Warnings}} } yyVAL.union = yyLOCAL - case 484: + case 483: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2623 +//line sql.y:2619 { // This should probably be a different type (ShowVitessTopoOpt), but // just getting the thing working for now @@ -9411,268 +9399,276 @@ yydefault: yyLOCAL = &Show{&ShowLegacy{Type: yyDollar[2].str, ShowTablesOpt: showTablesOpt}} } yyVAL.union = yyLOCAL - case 485: + case 484: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2637 +//line sql.y:2633 { yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].colIdent.String()), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL - case 486: + case 485: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2641 +//line sql.y:2637 { yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL - case 487: + case 486: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2645 +//line sql.y:2641 { yyLOCAL = &Show{&ShowLegacy{Type: string(yyDollar[2].str), Scope: ImplicitScope}} } yyVAL.union = yyLOCAL - case 488: + case 487: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2651 +//line sql.y:2647 { yyVAL.str = string(yyDollar[1].str) } - case 489: + case 488: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2655 +//line sql.y:2651 { yyVAL.str = string(yyDollar[1].str) } - case 490: + case 489: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2661 +//line sql.y:2657 { yyVAL.str = "" } - case 491: + case 490: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2665 +//line sql.y:2661 { yyVAL.str = "extended " } - case 492: + case 491: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:2671 +//line sql.y:2667 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 493: + case 492: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:2675 +//line sql.y:2671 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 494: + case 493: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2681 +//line sql.y:2677 { yyVAL.str = string(yyDollar[1].str) } - case 495: + case 494: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2685 +//line sql.y:2681 { yyVAL.str = string(yyDollar[1].str) } - case 496: + case 495: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2691 +//line sql.y:2687 { yyVAL.tableIdent = NewTableIdent("") } - case 497: + case 496: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2695 +//line sql.y:2691 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 498: + case 497: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:2699 +//line sql.y:2695 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 499: + case 498: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:2705 +//line sql.y:2701 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 500: + case 499: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:2709 +//line sql.y:2705 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 501: + case 500: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:2713 +//line sql.y:2709 { yyLOCAL = &ShowFilter{Filter: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 502: + case 501: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:2719 +//line sql.y:2715 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 503: + case 502: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ShowFilter -//line sql.y:2723 +//line sql.y:2719 { yyLOCAL = &ShowFilter{Like: string(yyDollar[2].str)} } yyVAL.union = yyLOCAL - case 504: + case 503: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2729 +//line sql.y:2725 { yyVAL.empty = struct{}{} } - case 505: + case 504: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2733 +//line sql.y:2729 { yyVAL.empty = struct{}{} } - case 506: + case 505: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2737 +//line sql.y:2733 { yyVAL.empty = struct{}{} } - case 507: + case 506: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2743 +//line sql.y:2739 { yyLOCAL = &Use{DBName: yyDollar[2].tableIdent} } yyVAL.union = yyLOCAL - case 508: + case 507: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:2747 +//line sql.y:2743 { yyLOCAL = &Use{DBName: TableIdent{v: ""}} } yyVAL.union = yyLOCAL - case 509: + case 508: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:2753 +//line sql.y:2749 { yyLOCAL = &Begin{} } yyVAL.union = yyLOCAL - case 510: + case 509: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2757 +//line sql.y:2753 { yyLOCAL = &Begin{} } yyVAL.union = yyLOCAL - case 511: + case 510: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:2763 +//line sql.y:2759 { yyLOCAL = &Commit{} } yyVAL.union = yyLOCAL - case 512: + case 511: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement -//line sql.y:2769 +//line sql.y:2765 { yyLOCAL = &Rollback{} } yyVAL.union = yyLOCAL - case 513: + case 512: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:2773 +//line sql.y:2769 { yyLOCAL = &SRollback{Name: yyDollar[5].colIdent} } yyVAL.union = yyLOCAL - case 514: + case 513: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2778 +//line sql.y:2774 { yyVAL.empty = struct{}{} } - case 515: + case 514: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2780 +//line sql.y:2776 { yyVAL.empty = struct{}{} } - case 516: + case 515: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2783 +//line sql.y:2779 { yyVAL.empty = struct{}{} } - case 517: + case 516: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2785 +//line sql.y:2781 { yyVAL.empty = struct{}{} } - case 518: + case 517: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2790 +//line sql.y:2786 { yyLOCAL = &Savepoint{Name: yyDollar[2].colIdent} } yyVAL.union = yyLOCAL - case 519: + case 518: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2796 +//line sql.y:2792 { yyLOCAL = &Release{Name: yyDollar[3].colIdent} } yyVAL.union = yyLOCAL - case 520: + case 519: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL ExplainType -//line sql.y:2801 +//line sql.y:2797 { yyLOCAL = EmptyType } yyVAL.union = yyLOCAL + case 520: + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL ExplainType +//line sql.y:2801 + { + yyLOCAL = JSONType + } + yyVAL.union = yyLOCAL case 521: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ExplainType //line sql.y:2805 { - yyLOCAL = JSONType + yyLOCAL = TreeType } yyVAL.union = yyLOCAL case 522: @@ -9680,7 +9676,7 @@ yydefault: var yyLOCAL ExplainType //line sql.y:2809 { - yyLOCAL = TreeType + yyLOCAL = VitessType } yyVAL.union = yyLOCAL case 523: @@ -9688,25 +9684,23 @@ yydefault: var yyLOCAL ExplainType //line sql.y:2813 { - yyLOCAL = VitessType + yyLOCAL = TraditionalType } yyVAL.union = yyLOCAL case 524: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ExplainType //line sql.y:2817 { - yyLOCAL = TraditionalType + yyLOCAL = AnalyzeType } yyVAL.union = yyLOCAL case 525: yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL ExplainType -//line sql.y:2821 +//line sql.y:2823 { - yyLOCAL = AnalyzeType + yyVAL.str = yyDollar[1].str } - yyVAL.union = yyLOCAL case 526: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2827 @@ -9721,16 +9715,18 @@ yydefault: } case 528: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2835 + var yyLOCAL Statement +//line sql.y:2837 { - yyVAL.str = yyDollar[1].str + yyLOCAL = yyDollar[1].selStmtUnion() } + yyVAL.union = yyLOCAL case 529: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Statement //line sql.y:2841 { - yyLOCAL = yyDollar[1].selStmtUnion() + yyLOCAL = yyDollar[1].statementUnion() } yyVAL.union = yyLOCAL case 530: @@ -9750,202 +9746,200 @@ yydefault: } yyVAL.union = yyLOCAL case 532: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL Statement -//line sql.y:2853 - { - yyLOCAL = yyDollar[1].statementUnion() - } - yyVAL.union = yyLOCAL - case 533: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:2858 +//line sql.y:2854 { yyVAL.str = "" } - case 534: + case 533: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2862 +//line sql.y:2858 { yyVAL.str = yyDollar[1].colIdent.val } - case 535: + case 534: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2866 +//line sql.y:2862 { yyVAL.str = encodeSQLString(yyDollar[1].str) } - case 536: + case 535: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2872 +//line sql.y:2868 { yyLOCAL = &ExplainTab{Table: yyDollar[2].tableName, Wild: yyDollar[3].str} } yyVAL.union = yyLOCAL - case 537: + case 536: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2876 +//line sql.y:2872 { yyLOCAL = &ExplainStmt{Type: yyDollar[2].explainTypeUnion(), Statement: yyDollar[3].statementUnion()} } yyVAL.union = yyLOCAL - case 538: + case 537: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2882 +//line sql.y:2878 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 539: + case 538: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2886 +//line sql.y:2882 { yyLOCAL = &OtherAdmin{} } yyVAL.union = yyLOCAL - case 540: + case 539: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2892 +//line sql.y:2888 { yyLOCAL = &LockTables{Tables: yyDollar[3].tableAndLockTypesUnion()} } yyVAL.union = yyLOCAL - case 541: + case 540: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableAndLockTypes -//line sql.y:2898 +//line sql.y:2894 { yyLOCAL = TableAndLockTypes{yyDollar[1].tableAndLockTypeUnion()} } yyVAL.union = yyLOCAL - case 542: + case 541: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2902 +//line sql.y:2898 { yySLICE := (*TableAndLockTypes)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableAndLockTypeUnion()) } - case 543: + case 542: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *TableAndLockType -//line sql.y:2908 +//line sql.y:2904 { yyLOCAL = &TableAndLockType{Table: yyDollar[1].aliasedTableNameUnion(), Lock: yyDollar[2].lockTypeUnion()} } yyVAL.union = yyLOCAL - case 544: + case 543: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:2914 +//line sql.y:2910 { yyLOCAL = Read } yyVAL.union = yyLOCAL - case 545: + case 544: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:2918 +//line sql.y:2914 { yyLOCAL = ReadLocal } yyVAL.union = yyLOCAL - case 546: + case 545: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL LockType -//line sql.y:2922 +//line sql.y:2918 { yyLOCAL = Write } yyVAL.union = yyLOCAL - case 547: + case 546: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL LockType -//line sql.y:2926 +//line sql.y:2922 { yyLOCAL = LowPriorityWrite } yyVAL.union = yyLOCAL - case 548: + case 547: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Statement -//line sql.y:2932 +//line sql.y:2928 { yyLOCAL = &UnlockTables{} } yyVAL.union = yyLOCAL - case 549: + case 548: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:2938 +//line sql.y:2934 { yyLOCAL = &RevertMigration{Comments: Comments(yyDollar[2].strs), UUID: string(yyDollar[4].str)} } yyVAL.union = yyLOCAL - case 550: + case 549: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2944 +//line sql.y:2940 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), FlushOptions: yyDollar[3].strs} } yyVAL.union = yyLOCAL - case 551: + case 550: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Statement -//line sql.y:2948 +//line sql.y:2944 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion()} } yyVAL.union = yyLOCAL - case 552: + case 551: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2952 +//line sql.y:2948 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 553: + case 552: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Statement -//line sql.y:2956 +//line sql.y:2952 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion()} } yyVAL.union = yyLOCAL - case 554: + case 553: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL Statement -//line sql.y:2960 +//line sql.y:2956 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), WithLock: true} } yyVAL.union = yyLOCAL - case 555: + case 554: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Statement -//line sql.y:2964 +//line sql.y:2960 { yyLOCAL = &Flush{IsLocal: yyDollar[2].booleanUnion(), TableNames: yyDollar[4].tableNamesUnion(), ForExport: true} } yyVAL.union = yyLOCAL - case 556: + case 555: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:2970 +//line sql.y:2966 { yyVAL.strs = []string{yyDollar[1].str} } - case 557: + case 556: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:2974 +//line sql.y:2970 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[3].str) } + case 557: + yyDollar = yyS[yypt-2 : yypt+1] +//line sql.y:2976 + { + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + } case 558: yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:2980 @@ -9965,10 +9959,10 @@ yydefault: yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 561: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:2992 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyVAL.str = string(yyDollar[1].str) } case 562: yyDollar = yyS[yypt-1 : yypt+1] @@ -9983,22 +9977,22 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 564: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:3004 { - yyVAL.str = string(yyDollar[1].str) + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str } case 565: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] //line sql.y:3008 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyDollar[3].str + yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) } case 566: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3012 { - yyVAL.str = string(yyDollar[1].str) + " " + string(yyDollar[2].str) + yyVAL.str = string(yyDollar[1].str) } case 567: yyDollar = yyS[yypt-1 : yypt+1] @@ -10013,195 +10007,195 @@ yydefault: yyVAL.str = string(yyDollar[1].str) } case 569: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3024 - { - yyVAL.str = string(yyDollar[1].str) - } - case 570: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3029 +//line sql.y:3025 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 571: + case 570: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3033 +//line sql.y:3029 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 572: + case 571: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3037 +//line sql.y:3033 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 573: + case 572: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3042 +//line sql.y:3038 { yyVAL.str = "" } - case 574: + case 573: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3046 +//line sql.y:3042 { yyVAL.str = " " + string(yyDollar[1].str) + " " + string(yyDollar[2].str) + " " + yyDollar[3].colIdent.String() } - case 575: + case 574: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3051 +//line sql.y:3047 { setAllowComments(yylex, true) } - case 576: + case 575: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3055 +//line sql.y:3051 { yyVAL.strs = yyDollar[2].strs setAllowComments(yylex, false) } - case 577: + case 576: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3061 +//line sql.y:3057 { yyVAL.strs = nil } - case 578: + case 577: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3065 +//line sql.y:3061 { yyVAL.strs = append(yyDollar[1].strs, yyDollar[2].str) } - case 579: + case 578: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3071 +//line sql.y:3067 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 580: + case 579: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3075 +//line sql.y:3071 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 581: + case 580: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:3079 +//line sql.y:3075 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 582: + case 581: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3084 +//line sql.y:3080 { yyVAL.str = "" } - case 583: + case 582: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3088 +//line sql.y:3084 { yyVAL.str = SQLNoCacheStr } - case 584: + case 583: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3092 +//line sql.y:3088 { yyVAL.str = SQLCacheStr } - case 585: + case 584: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:3097 +//line sql.y:3093 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 586: + case 585: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3101 +//line sql.y:3097 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 587: + case 586: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:3105 +//line sql.y:3101 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 588: + case 587: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:3110 +//line sql.y:3106 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 589: + case 588: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:3114 +//line sql.y:3110 { yyLOCAL = yyDollar[1].selectExprsUnion() } yyVAL.union = yyLOCAL - case 590: + case 589: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3119 +//line sql.y:3115 { yyVAL.strs = nil } - case 591: + case 590: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3123 +//line sql.y:3119 { yyVAL.strs = []string{yyDollar[1].str} } - case 592: + case 591: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3127 +//line sql.y:3123 { // TODO: This is a hack since I couldn't get it to work in a nicer way. I got 'conflicts: 8 shift/reduce' yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str} } - case 593: + case 592: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3131 +//line sql.y:3127 { yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str, yyDollar[3].str} } - case 594: + case 593: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3135 +//line sql.y:3131 { yyVAL.strs = []string{yyDollar[1].str, yyDollar[2].str, yyDollar[3].str, yyDollar[4].str} } + case 594: + yyDollar = yyS[yypt-1 : yypt+1] +//line sql.y:3137 + { + yyVAL.str = SQLNoCacheStr + } case 595: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3141 { - yyVAL.str = SQLNoCacheStr + yyVAL.str = SQLCacheStr } case 596: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3145 { - yyVAL.str = SQLCacheStr + yyVAL.str = DistinctStr } case 597: yyDollar = yyS[yypt-1 : yypt+1] @@ -10213,432 +10207,426 @@ yydefault: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3153 { - yyVAL.str = DistinctStr + yyVAL.str = StraightJoinHint } case 599: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3157 { - yyVAL.str = StraightJoinHint + yyVAL.str = SQLCalcFoundRowsStr } case 600: yyDollar = yyS[yypt-1 : yypt+1] //line sql.y:3161 - { - yyVAL.str = SQLCalcFoundRowsStr - } - case 601: - yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3165 { yyVAL.str = AllStr // These are not picked up by NewSelect, and so ALL will be dropped. But this is OK, since it's redundant anyway } - case 602: + case 601: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExprs -//line sql.y:3171 +//line sql.y:3167 { yyLOCAL = SelectExprs{yyDollar[1].selectExprUnion()} } yyVAL.union = yyLOCAL - case 603: + case 602: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3175 +//line sql.y:3171 { yySLICE := (*SelectExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].selectExprUnion()) } - case 604: + case 603: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:3181 +//line sql.y:3177 { yyLOCAL = &StarExpr{} } yyVAL.union = yyLOCAL - case 605: + case 604: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:3185 +//line sql.y:3181 { yyLOCAL = &AliasedExpr{Expr: yyDollar[1].exprUnion(), As: yyDollar[2].colIdent} } yyVAL.union = yyLOCAL - case 606: + case 605: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:3189 +//line sql.y:3185 { yyLOCAL = &StarExpr{TableName: TableName{Name: yyDollar[1].tableIdent}} } yyVAL.union = yyLOCAL - case 607: + case 606: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL SelectExpr -//line sql.y:3193 +//line sql.y:3189 { yyLOCAL = &StarExpr{TableName: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}} } yyVAL.union = yyLOCAL - case 608: + case 607: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3198 +//line sql.y:3194 { yyVAL.colIdent = ColIdent{} } - case 609: + case 608: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3202 +//line sql.y:3198 { yyVAL.colIdent = yyDollar[1].colIdent } - case 610: + case 609: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3206 +//line sql.y:3202 { yyVAL.colIdent = yyDollar[2].colIdent } - case 612: + case 611: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3213 +//line sql.y:3209 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].str)) } - case 613: + case 612: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL TableExprs -//line sql.y:3218 +//line sql.y:3214 { yyLOCAL = TableExprs{&AliasedTableExpr{Expr: TableName{Name: NewTableIdent("dual")}}} } yyVAL.union = yyLOCAL - case 614: + case 613: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL TableExprs -//line sql.y:3222 +//line sql.y:3218 { yyLOCAL = yyDollar[2].tableExprsUnion() } yyVAL.union = yyLOCAL - case 615: + case 614: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExprs -//line sql.y:3228 +//line sql.y:3224 { yyLOCAL = TableExprs{yyDollar[1].tableExprUnion()} } yyVAL.union = yyLOCAL - case 616: + case 615: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3232 +//line sql.y:3228 { yySLICE := (*TableExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].tableExprUnion()) } - case 619: + case 618: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3242 +//line sql.y:3238 { yyLOCAL = yyDollar[1].aliasedTableNameUnion() } yyVAL.union = yyLOCAL - case 620: + case 619: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3246 +//line sql.y:3242 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].derivedTableUnion(), As: yyDollar[3].tableIdent} } yyVAL.union = yyLOCAL - case 621: + case 620: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3250 +//line sql.y:3246 { yyLOCAL = &ParenTableExpr{Exprs: yyDollar[2].tableExprsUnion()} } yyVAL.union = yyLOCAL - case 622: + case 621: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *DerivedTable -//line sql.y:3256 +//line sql.y:3252 { yyLOCAL = &DerivedTable{yyDollar[2].selStmtUnion()} } yyVAL.union = yyLOCAL - case 623: + case 622: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:3262 +//line sql.y:3258 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, As: yyDollar[2].tableIdent, Hints: yyDollar[3].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 624: + case 623: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL *AliasedTableExpr -//line sql.y:3266 +//line sql.y:3262 { yyLOCAL = &AliasedTableExpr{Expr: yyDollar[1].tableName, Partitions: yyDollar[4].partitionsUnion(), As: yyDollar[6].tableIdent, Hints: yyDollar[7].indexHintsUnion()} } yyVAL.union = yyLOCAL - case 625: + case 624: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Columns -//line sql.y:3271 +//line sql.y:3267 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 626: + case 625: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:3275 +//line sql.y:3271 { yyLOCAL = yyDollar[2].columnsUnion() } yyVAL.union = yyLOCAL - case 627: + case 626: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:3281 +//line sql.y:3277 { yyLOCAL = Columns{yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 628: + case 627: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3285 +//line sql.y:3281 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colIdent) } - case 629: + case 628: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:3291 +//line sql.y:3287 { yyLOCAL = Columns{yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 630: + case 629: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:3295 +//line sql.y:3291 { yyLOCAL = Columns{NewColIdent(string(yyDollar[1].str))} } yyVAL.union = yyLOCAL - case 631: + case 630: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3299 +//line sql.y:3295 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colIdent) } - case 632: + case 631: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3303 +//line sql.y:3299 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, NewColIdent(string(yyDollar[3].str))) } - case 633: + case 632: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Partitions -//line sql.y:3309 +//line sql.y:3305 { yyLOCAL = Partitions{yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 634: + case 633: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3313 +//line sql.y:3309 { yySLICE := (*Partitions)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colIdent) } - case 635: + case 634: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3326 +//line sql.y:3322 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 636: + case 635: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3330 +//line sql.y:3326 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 637: + case 636: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3334 +//line sql.y:3330 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion(), Condition: yyDollar[4].joinCondition} } yyVAL.union = yyLOCAL - case 638: + case 637: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL TableExpr -//line sql.y:3338 +//line sql.y:3334 { yyLOCAL = &JoinTableExpr{LeftExpr: yyDollar[1].tableExprUnion(), Join: yyDollar[2].joinTypeUnion(), RightExpr: yyDollar[3].tableExprUnion()} } yyVAL.union = yyLOCAL - case 639: + case 638: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3344 +//line sql.y:3340 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].exprUnion()} } - case 640: + case 639: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:3346 +//line sql.y:3342 { yyVAL.joinCondition = JoinCondition{Using: yyDollar[3].columnsUnion()} } - case 641: + case 640: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3350 +//line sql.y:3346 { yyVAL.joinCondition = JoinCondition{} } - case 642: + case 641: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3352 +//line sql.y:3348 { yyVAL.joinCondition = yyDollar[1].joinCondition } - case 643: + case 642: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3356 +//line sql.y:3352 { yyVAL.joinCondition = JoinCondition{} } - case 644: + case 643: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3358 +//line sql.y:3354 { yyVAL.joinCondition = JoinCondition{On: yyDollar[2].exprUnion()} } - case 645: + case 644: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3361 +//line sql.y:3357 { yyVAL.empty = struct{}{} } - case 646: + case 645: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3363 +//line sql.y:3359 { yyVAL.empty = struct{}{} } - case 647: + case 646: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3366 +//line sql.y:3362 { yyVAL.tableIdent = NewTableIdent("") } - case 648: + case 647: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3370 +//line sql.y:3366 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 649: + case 648: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3374 +//line sql.y:3370 { yyVAL.tableIdent = yyDollar[2].tableIdent } - case 651: + case 650: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3381 +//line sql.y:3377 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].str)) } - case 652: + case 651: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:3387 +//line sql.y:3383 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 653: + case 652: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3391 +//line sql.y:3387 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 654: + case 653: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3395 +//line sql.y:3391 { yyLOCAL = NormalJoinType } yyVAL.union = yyLOCAL - case 655: + case 654: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL JoinType -//line sql.y:3401 +//line sql.y:3397 { yyLOCAL = StraightJoinType } yyVAL.union = yyLOCAL - case 656: + case 655: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3407 +//line sql.y:3403 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 657: + case 656: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:3411 +//line sql.y:3407 { yyLOCAL = LeftJoinType } yyVAL.union = yyLOCAL - case 658: + case 657: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3415 +//line sql.y:3411 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 659: + case 658: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL JoinType -//line sql.y:3419 +//line sql.y:3415 { yyLOCAL = RightJoinType } yyVAL.union = yyLOCAL - case 660: + case 659: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3425 +//line sql.y:3421 { yyLOCAL = NaturalJoinType } yyVAL.union = yyLOCAL - case 661: + case 660: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL JoinType -//line sql.y:3429 +//line sql.y:3425 { if yyDollar[2].joinTypeUnion() == LeftJoinType { yyLOCAL = NaturalLeftJoinType @@ -10647,438 +10635,446 @@ yydefault: } } yyVAL.union = yyLOCAL - case 662: + case 661: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:3439 +//line sql.y:3435 { yyVAL.tableName = yyDollar[2].tableName } - case 663: + case 662: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3443 +//line sql.y:3439 { yyVAL.tableName = yyDollar[1].tableName } - case 664: + case 663: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:3449 +//line sql.y:3445 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 665: + case 664: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3453 +//line sql.y:3449 { yyVAL.tableName = TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent} } - case 666: + case 665: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3459 +//line sql.y:3455 { yyVAL.tableName = TableName{Name: yyDollar[1].tableIdent} } - case 667: + case 666: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3464 +//line sql.y:3460 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 668: + case 667: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3468 +//line sql.y:3464 { yyLOCAL = &IndexHints{Type: UseOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 669: + case 668: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3472 +//line sql.y:3468 { yyLOCAL = &IndexHints{Type: UseOp} } yyVAL.union = yyLOCAL - case 670: + case 669: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3476 +//line sql.y:3472 { yyLOCAL = &IndexHints{Type: IgnoreOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 671: + case 670: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *IndexHints -//line sql.y:3480 +//line sql.y:3476 { yyLOCAL = &IndexHints{Type: ForceOp, Indexes: yyDollar[4].columnsUnion()} } yyVAL.union = yyLOCAL - case 672: + case 671: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:3485 +//line sql.y:3481 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 673: + case 672: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3489 +//line sql.y:3485 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 674: + case 673: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3495 +//line sql.y:3491 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 675: + case 674: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3499 +//line sql.y:3495 { yyLOCAL = &AndExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 676: + case 675: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3503 +//line sql.y:3499 { yyLOCAL = &OrExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 677: + case 676: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3507 +//line sql.y:3503 { yyLOCAL = &XorExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 678: + case 677: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3511 +//line sql.y:3507 { yyLOCAL = &NotExpr{Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 679: + case 678: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3515 +//line sql.y:3511 { yyLOCAL = &IsExpr{Left: yyDollar[1].exprUnion(), Right: yyDollar[3].isExprOperatorUnion()} } yyVAL.union = yyLOCAL - case 680: + case 679: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:3519 +//line sql.y:3515 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 681: + case 680: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3523 +//line sql.y:3519 { yyLOCAL = &Default{ColName: yyDollar[2].str} } yyVAL.union = yyLOCAL - case 682: + case 681: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:3529 +//line sql.y:3525 { yyVAL.str = "" } - case 683: + case 682: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3533 +//line sql.y:3529 { yyVAL.str = string(yyDollar[2].colIdent.String()) } - case 684: + case 683: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:3539 +//line sql.y:3535 { yyLOCAL = BoolVal(true) } yyVAL.union = yyLOCAL - case 685: + case 684: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL BoolVal -//line sql.y:3543 +//line sql.y:3539 { yyLOCAL = BoolVal(false) } yyVAL.union = yyLOCAL - case 686: + case 685: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3549 +//line sql.y:3545 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: yyDollar[2].comparisonExprOperatorUnion(), Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 687: + case 686: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3553 +//line sql.y:3549 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: InOp, Right: yyDollar[3].colTupleUnion()} } yyVAL.union = yyLOCAL - case 688: + case 687: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3557 +//line sql.y:3553 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotInOp, Right: yyDollar[4].colTupleUnion()} } yyVAL.union = yyLOCAL - case 689: + case 688: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3561 +//line sql.y:3557 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: LikeOp, Right: yyDollar[3].exprUnion(), Escape: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 690: + case 689: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3565 +//line sql.y:3561 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotLikeOp, Right: yyDollar[4].exprUnion(), Escape: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 691: + case 690: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3569 +//line sql.y:3565 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: RegexpOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 692: + case 691: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3573 +//line sql.y:3569 { yyLOCAL = &ComparisonExpr{Left: yyDollar[1].exprUnion(), Operator: NotRegexpOp, Right: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 693: + case 692: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr -//line sql.y:3577 +//line sql.y:3573 { yyLOCAL = &RangeCond{Left: yyDollar[1].exprUnion(), Operator: BetweenOp, From: yyDollar[3].exprUnion(), To: yyDollar[5].exprUnion()} } yyVAL.union = yyLOCAL - case 694: + case 693: yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr -//line sql.y:3581 +//line sql.y:3577 { yyLOCAL = &RangeCond{Left: yyDollar[1].exprUnion(), Operator: NotBetweenOp, From: yyDollar[4].exprUnion(), To: yyDollar[6].exprUnion()} } yyVAL.union = yyLOCAL - case 695: + case 694: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3585 +//line sql.y:3581 { yyLOCAL = &ExistsExpr{Subquery: yyDollar[2].subqueryUnion()} } yyVAL.union = yyLOCAL - case 696: + case 695: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3591 +//line sql.y:3587 { yyLOCAL = IsNullOp } yyVAL.union = yyLOCAL - case 697: + case 696: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3595 +//line sql.y:3591 { yyLOCAL = IsNotNullOp } yyVAL.union = yyLOCAL - case 698: + case 697: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3599 +//line sql.y:3595 { yyLOCAL = IsTrueOp } yyVAL.union = yyLOCAL - case 699: + case 698: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3603 +//line sql.y:3599 { yyLOCAL = IsNotTrueOp } yyVAL.union = yyLOCAL - case 700: + case 699: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3607 +//line sql.y:3603 { yyLOCAL = IsFalseOp } yyVAL.union = yyLOCAL - case 701: + case 700: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL IsExprOperator -//line sql.y:3611 +//line sql.y:3607 { yyLOCAL = IsNotFalseOp } yyVAL.union = yyLOCAL - case 702: + case 701: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3617 +//line sql.y:3613 { yyLOCAL = EqualOp } yyVAL.union = yyLOCAL - case 703: + case 702: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3621 +//line sql.y:3617 { yyLOCAL = LessThanOp } yyVAL.union = yyLOCAL - case 704: + case 703: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3625 +//line sql.y:3621 { yyLOCAL = GreaterThanOp } yyVAL.union = yyLOCAL - case 705: + case 704: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3629 +//line sql.y:3625 { yyLOCAL = LessEqualOp } yyVAL.union = yyLOCAL - case 706: + case 705: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3633 +//line sql.y:3629 { yyLOCAL = GreaterEqualOp } yyVAL.union = yyLOCAL - case 707: + case 706: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3637 +//line sql.y:3633 { yyLOCAL = NotEqualOp } yyVAL.union = yyLOCAL - case 708: + case 707: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ComparisonExprOperator -//line sql.y:3641 +//line sql.y:3637 { yyLOCAL = NullSafeEqualOp } yyVAL.union = yyLOCAL - case 709: + case 708: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:3646 +//line sql.y:3642 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 710: + case 709: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3650 +//line sql.y:3646 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 711: + case 710: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:3656 +//line sql.y:3652 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 712: + case 711: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:3660 +//line sql.y:3656 { yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL - case 713: + case 712: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ColTuple -//line sql.y:3664 +//line sql.y:3660 { yyLOCAL = ListArg(yyDollar[1].str[2:]) bindVariable(yylex, yyDollar[1].str[2:]) } yyVAL.union = yyLOCAL - case 714: + case 713: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *Subquery -//line sql.y:3671 +//line sql.y:3667 { yyLOCAL = &Subquery{yyDollar[2].selStmtUnion()} } yyVAL.union = yyLOCAL - case 715: + case 714: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:3677 +//line sql.y:3673 { yyLOCAL = Exprs{yyDollar[1].exprUnion()} } yyVAL.union = yyLOCAL - case 716: + case 715: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:3681 +//line sql.y:3677 { yySLICE := (*Exprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].exprUnion()) } + case 716: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Expr +//line sql.y:3683 + { + yyLOCAL = yyDollar[1].exprUnion() + } + yyVAL.union = yyLOCAL case 717: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:3687 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = yyDollar[1].boolValUnion() } yyVAL.union = yyLOCAL case 718: @@ -11086,7 +11082,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3691 { - yyLOCAL = yyDollar[1].boolValUnion() + yyLOCAL = yyDollar[1].colNameUnion() } yyVAL.union = yyLOCAL case 719: @@ -11094,7 +11090,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3695 { - yyLOCAL = yyDollar[1].colNameUnion() + yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL case 720: @@ -11102,15 +11098,15 @@ yydefault: var yyLOCAL Expr //line sql.y:3699 { - yyLOCAL = yyDollar[1].exprUnion() + yyLOCAL = yyDollar[1].subqueryUnion() } yyVAL.union = yyLOCAL case 721: - yyDollar = yyS[yypt-1 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr //line sql.y:3703 { - yyLOCAL = yyDollar[1].subqueryUnion() + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 722: @@ -11118,7 +11114,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3707 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitAndOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 723: @@ -11126,7 +11122,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3711 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitOrOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 724: @@ -11134,7 +11130,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3715 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: BitXorOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 725: @@ -11142,7 +11138,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3719 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: PlusOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 726: @@ -11150,7 +11146,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3723 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MinusOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 727: @@ -11158,7 +11154,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3727 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: MultOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 728: @@ -11166,7 +11162,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3731 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: DivOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 729: @@ -11174,7 +11170,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3735 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: IntDivOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 730: @@ -11190,7 +11186,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3743 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ModOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 732: @@ -11198,7 +11194,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3747 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftLeftOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 733: @@ -11206,7 +11202,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3751 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].exprUnion(), Operator: ShiftRightOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].colNameUnion(), Operator: JSONExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 734: @@ -11214,7 +11210,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3755 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].colNameUnion(), Operator: JSONExtractOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &BinaryExpr{Left: yyDollar[1].colNameUnion(), Operator: JSONUnquoteExtractOp, Right: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL case 735: @@ -11222,15 +11218,15 @@ yydefault: var yyLOCAL Expr //line sql.y:3759 { - yyLOCAL = &BinaryExpr{Left: yyDollar[1].colNameUnion(), Operator: JSONUnquoteExtractOp, Right: yyDollar[3].exprUnion()} + yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Charset: yyDollar[3].str} } yyVAL.union = yyLOCAL case 736: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:3763 { - yyLOCAL = &CollateExpr{Expr: yyDollar[1].exprUnion(), Charset: yyDollar[3].str} + yyLOCAL = &UnaryExpr{Operator: BinaryOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 737: @@ -11238,7 +11234,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3767 { - yyLOCAL = &UnaryExpr{Operator: BinaryOp, Expr: yyDollar[2].exprUnion()} + yyLOCAL = &UnaryExpr{Operator: UBinaryOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 738: @@ -11246,7 +11242,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3771 { - yyLOCAL = &UnaryExpr{Operator: UBinaryOp, Expr: yyDollar[2].exprUnion()} + yyLOCAL = &UnaryExpr{Operator: Utf8Op, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 739: @@ -11254,7 +11250,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3775 { - yyLOCAL = &UnaryExpr{Operator: Utf8Op, Expr: yyDollar[2].exprUnion()} + yyLOCAL = &UnaryExpr{Operator: Utf8mb4Op, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 740: @@ -11262,7 +11258,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3779 { - yyLOCAL = &UnaryExpr{Operator: Utf8mb4Op, Expr: yyDollar[2].exprUnion()} + yyLOCAL = &UnaryExpr{Operator: Latin1Op, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 741: @@ -11270,7 +11266,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3783 { - yyLOCAL = &UnaryExpr{Operator: Latin1Op, Expr: yyDollar[2].exprUnion()} + yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL case 742: @@ -11278,7 +11274,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3787 { - yyLOCAL = yyDollar[2].exprUnion() + yyLOCAL = handleUnaryMinus(yyDollar[2].exprUnion()) } yyVAL.union = yyLOCAL case 743: @@ -11286,29 +11282,21 @@ yydefault: var yyLOCAL Expr //line sql.y:3791 { - yyLOCAL = handleUnaryMinus(yyDollar[2].exprUnion()) + yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 744: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:3795 - { - yyLOCAL = &UnaryExpr{Operator: TildaOp, Expr: yyDollar[2].exprUnion()} - } - yyVAL.union = yyLOCAL - case 745: - yyDollar = yyS[yypt-2 : yypt+1] - var yyLOCAL Expr -//line sql.y:3799 { yyLOCAL = &UnaryExpr{Operator: BangOp, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 746: + case 745: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3803 +//line sql.y:3799 { // This rule prevents the usage of INTERVAL // as a function. If support is needed for that, @@ -11317,14 +11305,22 @@ yydefault: yyLOCAL = &IntervalExpr{Expr: yyDollar[2].exprUnion(), Unit: yyDollar[3].colIdent.String()} } yyVAL.union = yyLOCAL - case 751: + case 750: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3821 +//line sql.y:3817 { yyLOCAL = &FuncExpr{Name: yyDollar[1].colIdent, Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL + case 751: + yyDollar = yyS[yypt-5 : yypt+1] + var yyLOCAL Expr +//line sql.y:3821 + { + yyLOCAL = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprsUnion()} + } + yyVAL.union = yyLOCAL case 752: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr @@ -11334,19 +11330,19 @@ yydefault: } yyVAL.union = yyLOCAL case 753: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:3829 { - yyLOCAL = &FuncExpr{Name: yyDollar[1].colIdent, Distinct: true, Exprs: yyDollar[4].selectExprsUnion()} + yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprsUnion()} } yyVAL.union = yyLOCAL case 754: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3833 +//line sql.y:3839 { - yyLOCAL = &FuncExpr{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].colIdent, Exprs: yyDollar[5].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 755: @@ -11354,15 +11350,15 @@ yydefault: var yyLOCAL Expr //line sql.y:3843 { - yyLOCAL = &FuncExpr{Name: NewColIdent("left"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 756: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-6 : yypt+1] var yyLOCAL Expr //line sql.y:3847 { - yyLOCAL = &FuncExpr{Name: NewColIdent("right"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} } yyVAL.union = yyLOCAL case 757: @@ -11378,15 +11374,15 @@ yydefault: var yyLOCAL Expr //line sql.y:3855 { - yyLOCAL = &ConvertExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].convertTypeUnion()} + yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} } yyVAL.union = yyLOCAL case 759: - yyDollar = yyS[yypt-6 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:3859 { - yyLOCAL = &ConvertUsingExpr{Expr: yyDollar[3].exprUnion(), Type: yyDollar[5].str} + yyLOCAL = &SubstrExpr{Name: yyDollar[3].colNameUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 760: @@ -11402,7 +11398,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3867 { - yyLOCAL = &SubstrExpr{Name: yyDollar[3].colNameUnion(), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} + yyLOCAL = &SubstrExpr{StrVal: NewStrLiteral(yyDollar[3].str), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 762: @@ -11414,51 +11410,51 @@ yydefault: } yyVAL.union = yyLOCAL case 763: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL Expr //line sql.y:3875 { - yyLOCAL = &SubstrExpr{StrVal: NewStrLiteral(yyDollar[3].str), From: yyDollar[5].exprUnion(), To: yyDollar[7].exprUnion()} + yyLOCAL = &MatchExpr{Columns: yyDollar[3].selectExprsUnion(), Expr: yyDollar[7].exprUnion(), Option: yyDollar[8].matchExprOptionUnion()} } yyVAL.union = yyLOCAL case 764: - yyDollar = yyS[yypt-9 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:3879 { - yyLOCAL = &MatchExpr{Columns: yyDollar[3].selectExprsUnion(), Expr: yyDollar[7].exprUnion(), Option: yyDollar[8].matchExprOptionUnion()} + yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].selectExprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} } yyVAL.union = yyLOCAL case 765: - yyDollar = yyS[yypt-8 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Expr //line sql.y:3883 { - yyLOCAL = &GroupConcatExpr{Distinct: yyDollar[3].booleanUnion(), Exprs: yyDollar[4].selectExprsUnion(), OrderBy: yyDollar[5].orderByUnion(), Separator: yyDollar[6].str, Limit: yyDollar[7].limitUnion()} + yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL case 766: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr //line sql.y:3887 { - yyLOCAL = &CaseExpr{Expr: yyDollar[2].exprUnion(), Whens: yyDollar[3].whensUnion(), Else: yyDollar[4].exprUnion()} + yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} } yyVAL.union = yyLOCAL case 767: - yyDollar = yyS[yypt-4 : yypt+1] + yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr //line sql.y:3891 { - yyLOCAL = &ValuesFuncExpr{Name: yyDollar[3].colNameUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent(yyDollar[1].str)} } yyVAL.union = yyLOCAL case 768: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3895 +//line sql.y:3901 { - yyLOCAL = &FuncExpr{Name: NewColIdent(yyDollar[1].str)} + yyLOCAL = &FuncExpr{Name: NewColIdent("current_timestamp")} } yyVAL.union = yyLOCAL case 769: @@ -11466,7 +11462,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3905 { - yyLOCAL = &FuncExpr{Name: NewColIdent("current_timestamp")} + yyLOCAL = &FuncExpr{Name: NewColIdent("utc_timestamp")} } yyVAL.union = yyLOCAL case 770: @@ -11474,55 +11470,55 @@ yydefault: var yyLOCAL Expr //line sql.y:3909 { - yyLOCAL = &FuncExpr{Name: NewColIdent("utc_timestamp")} + yyLOCAL = &FuncExpr{Name: NewColIdent("utc_time")} } yyVAL.union = yyLOCAL case 771: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3913 +//line sql.y:3914 { - yyLOCAL = &FuncExpr{Name: NewColIdent("utc_time")} + yyLOCAL = &FuncExpr{Name: NewColIdent("utc_date")} } yyVAL.union = yyLOCAL case 772: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3918 +//line sql.y:3919 { - yyLOCAL = &FuncExpr{Name: NewColIdent("utc_date")} + yyLOCAL = &FuncExpr{Name: NewColIdent("localtime")} } yyVAL.union = yyLOCAL case 773: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3923 +//line sql.y:3924 { - yyLOCAL = &FuncExpr{Name: NewColIdent("localtime")} + yyLOCAL = &FuncExpr{Name: NewColIdent("localtimestamp")} } yyVAL.union = yyLOCAL case 774: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3928 +//line sql.y:3930 { - yyLOCAL = &FuncExpr{Name: NewColIdent("localtimestamp")} + yyLOCAL = &FuncExpr{Name: NewColIdent("current_date")} } yyVAL.union = yyLOCAL case 775: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3934 +//line sql.y:3935 { - yyLOCAL = &FuncExpr{Name: NewColIdent("current_date")} + yyLOCAL = &FuncExpr{Name: NewColIdent("current_time")} } yyVAL.union = yyLOCAL case 776: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3939 +//line sql.y:3940 { - yyLOCAL = &FuncExpr{Name: NewColIdent("current_time")} + yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 777: @@ -11530,7 +11526,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3944 { - yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("current_timestamp"), Fsp: yyDollar[2].exprUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 778: @@ -11538,39 +11534,39 @@ yydefault: var yyLOCAL Expr //line sql.y:3948 { - yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("utc_timestamp"), Fsp: yyDollar[2].exprUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 779: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3952 +//line sql.y:3953 { - yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("utc_time"), Fsp: yyDollar[2].exprUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 780: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3957 +//line sql.y:3958 { - yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("localtime"), Fsp: yyDollar[2].exprUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 781: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:3962 +//line sql.y:3963 { - yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("localtimestamp"), Fsp: yyDollar[2].exprUnion()} + yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL case 782: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-8 : yypt+1] var yyLOCAL Expr //line sql.y:3967 { - yyLOCAL = &CurTimeFuncExpr{Name: NewColIdent("current_time"), Fsp: yyDollar[2].exprUnion()} + yyLOCAL = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL case 783: @@ -11578,23 +11574,23 @@ yydefault: var yyLOCAL Expr //line sql.y:3971 { - yyLOCAL = &TimestampFuncExpr{Name: string("timestampadd"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} + yyLOCAL = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} } yyVAL.union = yyLOCAL - case 784: - yyDollar = yyS[yypt-8 : yypt+1] + case 786: + yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Expr -//line sql.y:3975 +//line sql.y:3981 { - yyLOCAL = &TimestampFuncExpr{Name: string("timestampdiff"), Unit: yyDollar[3].colIdent.String(), Expr1: yyDollar[5].exprUnion(), Expr2: yyDollar[7].exprUnion()} + yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL case 787: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Expr -//line sql.y:3985 +//line sql.y:3991 { - yyLOCAL = yyDollar[2].exprUnion() + yyLOCAL = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 788: @@ -11602,7 +11598,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3995 { - yyLOCAL = &FuncExpr{Name: NewColIdent("if"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 789: @@ -11610,7 +11606,7 @@ yydefault: var yyLOCAL Expr //line sql.y:3999 { - yyLOCAL = &FuncExpr{Name: NewColIdent("database"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("schema"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 790: @@ -11618,7 +11614,7 @@ yydefault: var yyLOCAL Expr //line sql.y:4003 { - yyLOCAL = &FuncExpr{Name: NewColIdent("schema"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 791: @@ -11626,7 +11622,7 @@ yydefault: var yyLOCAL Expr //line sql.y:4007 { - yyLOCAL = &FuncExpr{Name: NewColIdent("mod"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 792: @@ -11634,7 +11630,7 @@ yydefault: var yyLOCAL Expr //line sql.y:4011 { - yyLOCAL = &FuncExpr{Name: NewColIdent("replace"), Exprs: yyDollar[3].selectExprsUnion()} + yyLOCAL = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprsUnion()} } yyVAL.union = yyLOCAL case 793: @@ -11646,274 +11642,274 @@ yydefault: } yyVAL.union = yyLOCAL case 794: - yyDollar = yyS[yypt-4 : yypt+1] - var yyLOCAL Expr -//line sql.y:4019 - { - yyLOCAL = &FuncExpr{Name: NewColIdent("substr"), Exprs: yyDollar[3].selectExprsUnion()} - } - yyVAL.union = yyLOCAL - case 795: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:4025 +//line sql.y:4021 { yyLOCAL = NoOption } yyVAL.union = yyLOCAL - case 796: + case 795: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:4029 +//line sql.y:4025 { yyLOCAL = BooleanModeOpt } yyVAL.union = yyLOCAL - case 797: + case 796: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:4033 +//line sql.y:4029 { yyLOCAL = NaturalLanguageModeOpt } yyVAL.union = yyLOCAL - case 798: + case 797: yyDollar = yyS[yypt-7 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:4037 +//line sql.y:4033 { yyLOCAL = NaturalLanguageModeWithQueryExpansionOpt } yyVAL.union = yyLOCAL - case 799: + case 798: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL MatchExprOption -//line sql.y:4041 +//line sql.y:4037 { yyLOCAL = QueryExpansionOpt } yyVAL.union = yyLOCAL - case 800: + case 799: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4047 +//line sql.y:4043 { yyVAL.str = string(yyDollar[1].colIdent.String()) } - case 801: + case 800: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4051 +//line sql.y:4047 { yyVAL.str = string(yyDollar[1].str) } - case 802: + case 801: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4055 +//line sql.y:4051 { yyVAL.str = string(yyDollar[1].str) } - case 803: + case 802: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4061 +//line sql.y:4057 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 804: + case 803: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4065 +//line sql.y:4061 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: yyDollar[3].str, Operator: CharacterSetOp} } yyVAL.union = yyLOCAL - case 805: + case 804: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4069 +//line sql.y:4065 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion(), Charset: string(yyDollar[3].colIdent.String())} } yyVAL.union = yyLOCAL - case 806: + case 805: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4073 +//line sql.y:4069 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 807: + case 806: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4077 +//line sql.y:4073 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 808: + case 807: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4081 +//line sql.y:4077 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} yyLOCAL.Length = yyDollar[2].LengthScaleOption.Length yyLOCAL.Scale = yyDollar[2].LengthScaleOption.Scale } yyVAL.union = yyLOCAL - case 809: + case 808: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4087 +//line sql.y:4083 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 810: + case 809: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4091 +//line sql.y:4087 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 811: + case 810: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4095 +//line sql.y:4091 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 812: + case 811: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4099 +//line sql.y:4095 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 813: + case 812: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4103 +//line sql.y:4099 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str), Length: yyDollar[2].literalUnion()} } yyVAL.union = yyLOCAL - case 814: + case 813: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4107 +//line sql.y:4103 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 815: + case 814: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *ConvertType -//line sql.y:4111 +//line sql.y:4107 { yyLOCAL = &ConvertType{Type: string(yyDollar[1].str)} } yyVAL.union = yyLOCAL - case 816: + case 815: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:4116 +//line sql.y:4112 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 817: + case 816: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4120 +//line sql.y:4116 { yyLOCAL = yyDollar[1].exprUnion() } yyVAL.union = yyLOCAL - case 818: + case 817: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4125 +//line sql.y:4121 { yyVAL.str = string("") } - case 819: + case 818: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4129 +//line sql.y:4125 { yyVAL.str = " separator " + encodeSQLString(yyDollar[2].str) } - case 820: + case 819: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*When -//line sql.y:4135 +//line sql.y:4131 { yyLOCAL = []*When{yyDollar[1].whenUnion()} } yyVAL.union = yyLOCAL - case 821: + case 820: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4139 +//line sql.y:4135 { yySLICE := (*[]*When)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[2].whenUnion()) } - case 822: + case 821: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *When -//line sql.y:4145 +//line sql.y:4141 { yyLOCAL = &When{Cond: yyDollar[2].exprUnion(), Val: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 823: + case 822: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:4150 +//line sql.y:4146 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 824: + case 823: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4154 +//line sql.y:4150 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 825: + case 824: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *ColName -//line sql.y:4160 +//line sql.y:4156 { yyLOCAL = &ColName{Name: yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 826: + case 825: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *ColName -//line sql.y:4164 +//line sql.y:4160 { yyLOCAL = &ColName{Qualifier: TableName{Name: yyDollar[1].tableIdent}, Name: yyDollar[3].colIdent} } yyVAL.union = yyLOCAL - case 827: + case 826: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *ColName -//line sql.y:4168 +//line sql.y:4164 { yyLOCAL = &ColName{Qualifier: TableName{Qualifier: yyDollar[1].tableIdent, Name: yyDollar[3].tableIdent}, Name: yyDollar[5].colIdent} } yyVAL.union = yyLOCAL + case 827: + yyDollar = yyS[yypt-1 : yypt+1] + var yyLOCAL Expr +//line sql.y:4170 + { + yyLOCAL = NewStrLiteral(yyDollar[1].str) + } + yyVAL.union = yyLOCAL case 828: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:4174 { - yyLOCAL = NewStrLiteral(yyDollar[1].str) + yyLOCAL = NewHexLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 829: @@ -11921,7 +11917,7 @@ yydefault: var yyLOCAL Expr //line sql.y:4178 { - yyLOCAL = NewHexLiteral(yyDollar[1].str) + yyLOCAL = NewBitLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 830: @@ -11929,7 +11925,7 @@ yydefault: var yyLOCAL Expr //line sql.y:4182 { - yyLOCAL = NewBitLiteral(yyDollar[1].str) + yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 831: @@ -11937,7 +11933,7 @@ yydefault: var yyLOCAL Expr //line sql.y:4186 { - yyLOCAL = NewIntLiteral(yyDollar[1].str) + yyLOCAL = NewFloatLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 832: @@ -11945,38 +11941,30 @@ yydefault: var yyLOCAL Expr //line sql.y:4190 { - yyLOCAL = NewFloatLiteral(yyDollar[1].str) + yyLOCAL = NewHexNumLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL case 833: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr //line sql.y:4194 - { - yyLOCAL = NewHexNumLiteral(yyDollar[1].str) - } - yyVAL.union = yyLOCAL - case 834: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL Expr -//line sql.y:4198 { yyLOCAL = NewArgument(yyDollar[1].str[1:]) bindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 835: + case 834: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4203 +//line sql.y:4199 { yyLOCAL = &NullVal{} } yyVAL.union = yyLOCAL - case 836: + case 835: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4209 +//line sql.y:4205 { // TODO(sougou): Deprecate this construct. if yyDollar[1].colIdent.Lowered() != "value" { @@ -11986,158 +11974,166 @@ yydefault: yyLOCAL = NewIntLiteral("1") } yyVAL.union = yyLOCAL - case 837: + case 836: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4218 +//line sql.y:4214 { yyLOCAL = NewIntLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 838: + case 837: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4222 +//line sql.y:4218 { yyLOCAL = NewArgument(yyDollar[1].str[1:]) bindVariable(yylex, yyDollar[1].str[1:]) } yyVAL.union = yyLOCAL - case 839: + case 838: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:4228 +//line sql.y:4224 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 840: + case 839: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Exprs -//line sql.y:4232 +//line sql.y:4228 { yyLOCAL = yyDollar[3].exprsUnion() } yyVAL.union = yyLOCAL - case 841: + case 840: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Expr -//line sql.y:4237 +//line sql.y:4233 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 842: + case 841: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Expr -//line sql.y:4241 +//line sql.y:4237 { yyLOCAL = yyDollar[2].exprUnion() } yyVAL.union = yyLOCAL - case 843: + case 842: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderBy -//line sql.y:4246 +//line sql.y:4242 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 844: + case 843: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL OrderBy -//line sql.y:4250 +//line sql.y:4246 { yyLOCAL = yyDollar[3].orderByUnion() } yyVAL.union = yyLOCAL - case 845: + case 844: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderBy -//line sql.y:4256 +//line sql.y:4252 { yyLOCAL = OrderBy{yyDollar[1].orderUnion()} } yyVAL.union = yyLOCAL - case 846: + case 845: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4260 +//line sql.y:4256 { yySLICE := (*OrderBy)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].orderUnion()) } - case 847: + case 846: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Order -//line sql.y:4266 +//line sql.y:4262 { yyLOCAL = &Order{Expr: yyDollar[1].exprUnion(), Direction: yyDollar[2].orderDirectionUnion()} } yyVAL.union = yyLOCAL - case 848: + case 847: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:4271 +//line sql.y:4267 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 849: + case 848: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:4275 +//line sql.y:4271 { yyLOCAL = AscOrder } yyVAL.union = yyLOCAL - case 850: + case 849: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL OrderDirection -//line sql.y:4279 +//line sql.y:4275 { yyLOCAL = DescOrder } yyVAL.union = yyLOCAL - case 851: + case 850: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *Limit -//line sql.y:4284 +//line sql.y:4280 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 852: + case 851: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Limit -//line sql.y:4288 +//line sql.y:4284 { yyLOCAL = &Limit{Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 853: + case 852: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:4292 +//line sql.y:4288 { yyLOCAL = &Limit{Offset: yyDollar[2].exprUnion(), Rowcount: yyDollar[4].exprUnion()} } yyVAL.union = yyLOCAL - case 854: + case 853: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Limit -//line sql.y:4296 +//line sql.y:4292 { yyLOCAL = &Limit{Offset: yyDollar[4].exprUnion(), Rowcount: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 855: + case 854: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []AlterOption -//line sql.y:4301 +//line sql.y:4297 { yyLOCAL = nil } yyVAL.union = yyLOCAL + case 855: + yyDollar = yyS[yypt-2 : yypt+1] + var yyLOCAL []AlterOption +//line sql.y:4301 + { + yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} + } + yyVAL.union = yyLOCAL case 856: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL []AlterOption @@ -12147,11 +12143,11 @@ yydefault: } yyVAL.union = yyLOCAL case 857: - yyDollar = yyS[yypt-2 : yypt+1] + yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []AlterOption //line sql.y:4309 { - yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion(), yyDollar[2].alterOptionUnion()} + yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} } yyVAL.union = yyLOCAL case 858: @@ -12163,11 +12159,11 @@ yydefault: } yyVAL.union = yyLOCAL case 859: - yyDollar = yyS[yypt-1 : yypt+1] - var yyLOCAL []AlterOption -//line sql.y:4317 + yyDollar = yyS[yypt-3 : yypt+1] + var yyLOCAL AlterOption +//line sql.y:4320 { - yyLOCAL = []AlterOption{yyDollar[1].alterOptionUnion()} + yyLOCAL = &LockOption{Type: DefaultType} } yyVAL.union = yyLOCAL case 860: @@ -12175,7 +12171,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:4324 { - yyLOCAL = &LockOption{Type: DefaultType} + yyLOCAL = &LockOption{Type: NoneType} } yyVAL.union = yyLOCAL case 861: @@ -12183,7 +12179,7 @@ yydefault: var yyLOCAL AlterOption //line sql.y:4328 { - yyLOCAL = &LockOption{Type: NoneType} + yyLOCAL = &LockOption{Type: SharedType} } yyVAL.union = yyLOCAL case 862: @@ -12191,15 +12187,15 @@ yydefault: var yyLOCAL AlterOption //line sql.y:4332 { - yyLOCAL = &LockOption{Type: SharedType} + yyLOCAL = &LockOption{Type: ExclusiveType} } yyVAL.union = yyLOCAL case 863: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL AlterOption -//line sql.y:4336 +//line sql.y:4338 { - yyLOCAL = &LockOption{Type: ExclusiveType} + yyLOCAL = AlgorithmValue(yyDollar[3].str) } yyVAL.union = yyLOCAL case 864: @@ -12219,18 +12215,16 @@ yydefault: } yyVAL.union = yyLOCAL case 866: - yyDollar = yyS[yypt-3 : yypt+1] - var yyLOCAL AlterOption -//line sql.y:4350 + yyDollar = yyS[yypt-0 : yypt+1] +//line sql.y:4351 { - yyLOCAL = AlgorithmValue(yyDollar[3].str) + yyVAL.str = "" } - yyVAL.union = yyLOCAL case 867: - yyDollar = yyS[yypt-0 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line sql.y:4355 { - yyVAL.str = "" + yyVAL.str = string(yyDollar[3].str) } case 868: yyDollar = yyS[yypt-3 : yypt+1] @@ -12245,448 +12239,442 @@ yydefault: yyVAL.str = string(yyDollar[3].str) } case 870: - yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4367 - { - yyVAL.str = string(yyDollar[3].str) - } - case 871: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4372 +//line sql.y:4368 { yyVAL.str = "" } - case 872: + case 871: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4376 +//line sql.y:4372 { yyVAL.str = yyDollar[3].str } - case 873: + case 872: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4382 +//line sql.y:4378 { yyVAL.str = string(yyDollar[1].str) } - case 874: + case 873: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4386 +//line sql.y:4382 { yyVAL.str = string(yyDollar[1].str) } - case 875: + case 874: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4391 +//line sql.y:4387 { yyVAL.str = "" } - case 876: + case 875: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4395 +//line sql.y:4391 { yyVAL.str = yyDollar[2].str } - case 877: + case 876: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4400 +//line sql.y:4396 { yyVAL.str = "cascaded" } - case 878: + case 877: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4404 +//line sql.y:4400 { yyVAL.str = string(yyDollar[1].str) } - case 879: + case 878: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4408 +//line sql.y:4404 { yyVAL.str = string(yyDollar[1].str) } - case 880: + case 879: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4413 +//line sql.y:4409 { yyVAL.str = "" } - case 881: + case 880: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4417 +//line sql.y:4413 { yyVAL.str = yyDollar[3].str } - case 882: + case 881: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4423 +//line sql.y:4419 { yyVAL.str = string(yyDollar[1].str) } - case 883: + case 882: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4427 +//line sql.y:4423 { yyVAL.str = string(yyDollar[1].str) } - case 884: + case 883: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4431 +//line sql.y:4427 { yyVAL.str = encodeSQLString(yyDollar[1].str) + "@" + string(yyDollar[2].str) } - case 885: + case 884: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4435 +//line sql.y:4431 { yyVAL.str = string(yyDollar[1].str) } - case 886: + case 885: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Lock -//line sql.y:4440 +//line sql.y:4436 { yyLOCAL = NoLock } yyVAL.union = yyLOCAL - case 887: + case 886: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL Lock -//line sql.y:4444 +//line sql.y:4440 { yyLOCAL = ForUpdateLock } yyVAL.union = yyLOCAL - case 888: + case 887: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL Lock -//line sql.y:4448 +//line sql.y:4444 { yyLOCAL = ShareModeLock } yyVAL.union = yyLOCAL - case 889: + case 888: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4453 +//line sql.y:4449 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 890: + case 889: yyDollar = yyS[yypt-9 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4457 +//line sql.y:4453 { yyLOCAL = &SelectInto{Type: IntoOutfileS3, FileName: encodeSQLString(yyDollar[4].str), Charset: yyDollar[5].str, FormatOption: yyDollar[6].str, ExportOption: yyDollar[7].str, Manifest: yyDollar[8].str, Overwrite: yyDollar[9].str} } yyVAL.union = yyLOCAL - case 891: + case 890: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4461 +//line sql.y:4457 { yyLOCAL = &SelectInto{Type: IntoDumpfile, FileName: encodeSQLString(yyDollar[3].str), Charset: "", FormatOption: "", ExportOption: "", Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 892: + case 891: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *SelectInto -//line sql.y:4465 +//line sql.y:4461 { yyLOCAL = &SelectInto{Type: IntoOutfile, FileName: encodeSQLString(yyDollar[3].str), Charset: yyDollar[4].str, FormatOption: "", ExportOption: yyDollar[5].str, Manifest: "", Overwrite: ""} } yyVAL.union = yyLOCAL - case 893: + case 892: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4470 +//line sql.y:4466 { yyVAL.str = "" } - case 894: + case 893: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4474 +//line sql.y:4470 { yyVAL.str = " format csv" + yyDollar[3].str } - case 895: + case 894: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4478 +//line sql.y:4474 { yyVAL.str = " format text" + yyDollar[3].str } - case 896: + case 895: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4483 +//line sql.y:4479 { yyVAL.str = "" } - case 897: + case 896: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4487 +//line sql.y:4483 { yyVAL.str = " header" } - case 898: + case 897: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4492 +//line sql.y:4488 { yyVAL.str = "" } - case 899: + case 898: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4496 +//line sql.y:4492 { yyVAL.str = " manifest on" } - case 900: + case 899: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4500 +//line sql.y:4496 { yyVAL.str = " manifest off" } - case 901: + case 900: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4505 +//line sql.y:4501 { yyVAL.str = "" } - case 902: + case 901: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4509 +//line sql.y:4505 { yyVAL.str = " overwrite on" } - case 903: + case 902: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4513 +//line sql.y:4509 { yyVAL.str = " overwrite off" } - case 904: + case 903: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4519 +//line sql.y:4515 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 905: + case 904: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4524 +//line sql.y:4520 { yyVAL.str = "" } - case 906: + case 905: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4528 +//line sql.y:4524 { yyVAL.str = " lines" + yyDollar[2].str } - case 907: + case 906: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4534 +//line sql.y:4530 { yyVAL.str = yyDollar[1].str } - case 908: + case 907: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4538 +//line sql.y:4534 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 909: + case 908: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4544 +//line sql.y:4540 { yyVAL.str = " starting by " + encodeSQLString(yyDollar[3].str) } - case 910: + case 909: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4548 +//line sql.y:4544 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 911: + case 910: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4553 +//line sql.y:4549 { yyVAL.str = "" } - case 912: + case 911: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4557 +//line sql.y:4553 { yyVAL.str = " " + yyDollar[1].str + yyDollar[2].str } - case 913: + case 912: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4563 +//line sql.y:4559 { yyVAL.str = yyDollar[1].str } - case 914: + case 913: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4567 +//line sql.y:4563 { yyVAL.str = yyDollar[1].str + yyDollar[2].str } - case 915: + case 914: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4573 +//line sql.y:4569 { yyVAL.str = " terminated by " + encodeSQLString(yyDollar[3].str) } - case 916: + case 915: yyDollar = yyS[yypt-4 : yypt+1] -//line sql.y:4577 +//line sql.y:4573 { yyVAL.str = yyDollar[1].str + " enclosed by " + encodeSQLString(yyDollar[4].str) } - case 917: + case 916: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4581 +//line sql.y:4577 { yyVAL.str = " escaped by " + encodeSQLString(yyDollar[3].str) } - case 918: + case 917: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4586 +//line sql.y:4582 { yyVAL.str = "" } - case 919: + case 918: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4590 +//line sql.y:4586 { yyVAL.str = " optionally" } - case 920: + case 919: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *Insert -//line sql.y:4603 +//line sql.y:4599 { yyLOCAL = &Insert{Rows: yyDollar[2].valuesUnion()} } yyVAL.union = yyLOCAL - case 921: + case 920: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL *Insert -//line sql.y:4607 +//line sql.y:4603 { yyLOCAL = &Insert{Rows: yyDollar[1].selStmtUnion()} } yyVAL.union = yyLOCAL - case 922: + case 921: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL *Insert -//line sql.y:4611 +//line sql.y:4607 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[5].valuesUnion()} } yyVAL.union = yyLOCAL - case 923: + case 922: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:4615 +//line sql.y:4611 { yyLOCAL = &Insert{Rows: yyDollar[4].valuesUnion()} } yyVAL.union = yyLOCAL - case 924: + case 923: yyDollar = yyS[yypt-4 : yypt+1] var yyLOCAL *Insert -//line sql.y:4619 +//line sql.y:4615 { yyLOCAL = &Insert{Columns: yyDollar[2].columnsUnion(), Rows: yyDollar[4].selStmtUnion()} } yyVAL.union = yyLOCAL - case 925: + case 924: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Columns -//line sql.y:4625 +//line sql.y:4621 { yyLOCAL = Columns{yyDollar[1].colIdent} } yyVAL.union = yyLOCAL - case 926: + case 925: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL Columns -//line sql.y:4629 +//line sql.y:4625 { yyLOCAL = Columns{yyDollar[3].colIdent} } yyVAL.union = yyLOCAL - case 927: + case 926: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4633 +//line sql.y:4629 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].colIdent) } - case 928: + case 927: yyDollar = yyS[yypt-5 : yypt+1] -//line sql.y:4637 +//line sql.y:4633 { yySLICE := (*Columns)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[5].colIdent) } - case 929: + case 928: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:4642 +//line sql.y:4638 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 930: + case 929: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:4646 +//line sql.y:4642 { yyLOCAL = yyDollar[5].updateExprsUnion() } yyVAL.union = yyLOCAL - case 931: + case 930: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Values -//line sql.y:4652 +//line sql.y:4648 { yyLOCAL = Values{yyDollar[1].valTupleUnion()} } yyVAL.union = yyLOCAL - case 932: + case 931: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4656 +//line sql.y:4652 { yySLICE := (*Values)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].valTupleUnion()) } - case 933: + case 932: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL ValTuple -//line sql.y:4662 +//line sql.y:4658 { yyLOCAL = yyDollar[1].valTupleUnion() } yyVAL.union = yyLOCAL - case 934: + case 933: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL ValTuple -//line sql.y:4666 +//line sql.y:4662 { yyLOCAL = ValTuple{} } yyVAL.union = yyLOCAL - case 935: + case 934: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL ValTuple -//line sql.y:4672 +//line sql.y:4668 { yyLOCAL = ValTuple(yyDollar[2].exprsUnion()) } yyVAL.union = yyLOCAL - case 936: + case 935: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4678 +//line sql.y:4674 { if len(yyDollar[1].valTupleUnion()) == 1 { yyLOCAL = yyDollar[1].valTupleUnion()[0] @@ -12695,329 +12683,329 @@ yydefault: } } yyVAL.union = yyLOCAL - case 937: + case 936: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL UpdateExprs -//line sql.y:4688 +//line sql.y:4684 { yyLOCAL = UpdateExprs{yyDollar[1].updateExprUnion()} } yyVAL.union = yyLOCAL - case 938: + case 937: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4692 +//line sql.y:4688 { yySLICE := (*UpdateExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].updateExprUnion()) } - case 939: + case 938: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *UpdateExpr -//line sql.y:4698 +//line sql.y:4694 { yyLOCAL = &UpdateExpr{Name: yyDollar[1].colNameUnion(), Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 940: + case 939: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL SetExprs -//line sql.y:4704 +//line sql.y:4700 { yyLOCAL = SetExprs{yyDollar[1].setExprUnion()} } yyVAL.union = yyLOCAL - case 941: + case 940: yyDollar = yyS[yypt-3 : yypt+1] -//line sql.y:4708 +//line sql.y:4704 { yySLICE := (*SetExprs)(yyIaddr(yyVAL.union)) *yySLICE = append(*yySLICE, yyDollar[3].setExprUnion()) } - case 942: + case 941: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4714 +//line sql.y:4710 { yyLOCAL = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral("on")} } yyVAL.union = yyLOCAL - case 943: + case 942: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4718 +//line sql.y:4714 { yyLOCAL = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: NewStrLiteral("off")} } yyVAL.union = yyLOCAL - case 944: + case 943: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4722 +//line sql.y:4718 { yyLOCAL = &SetExpr{Name: yyDollar[1].colIdent, Scope: ImplicitScope, Expr: yyDollar[3].exprUnion()} } yyVAL.union = yyLOCAL - case 945: + case 944: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4726 +//line sql.y:4722 { yyLOCAL = &SetExpr{Name: NewColIdent(string(yyDollar[1].str)), Scope: ImplicitScope, Expr: yyDollar[2].exprUnion()} } yyVAL.union = yyLOCAL - case 946: + case 945: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *SetExpr -//line sql.y:4730 +//line sql.y:4726 { yyDollar[2].setExprUnion().Scope = yyDollar[1].scopeUnion() yyLOCAL = yyDollar[2].setExprUnion() } yyVAL.union = yyLOCAL - case 948: + case 947: yyDollar = yyS[yypt-2 : yypt+1] -//line sql.y:4738 +//line sql.y:4734 { yyVAL.str = "charset" } - case 951: + case 950: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4748 +//line sql.y:4744 { yyLOCAL = NewStrLiteral(yyDollar[1].colIdent.String()) } yyVAL.union = yyLOCAL - case 952: + case 951: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4752 +//line sql.y:4748 { yyLOCAL = NewStrLiteral(yyDollar[1].str) } yyVAL.union = yyLOCAL - case 953: + case 952: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Expr -//line sql.y:4756 +//line sql.y:4752 { yyLOCAL = &Default{} } yyVAL.union = yyLOCAL - case 956: + case 955: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4765 +//line sql.y:4761 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 957: + case 956: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL bool -//line sql.y:4767 +//line sql.y:4763 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 958: + case 957: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4770 +//line sql.y:4766 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 959: + case 958: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL bool -//line sql.y:4772 +//line sql.y:4768 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 960: + case 959: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL bool -//line sql.y:4775 +//line sql.y:4771 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 961: + case 960: yyDollar = yyS[yypt-3 : yypt+1] var yyLOCAL bool -//line sql.y:4777 +//line sql.y:4773 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 962: + case 961: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Ignore -//line sql.y:4780 +//line sql.y:4776 { yyLOCAL = false } yyVAL.union = yyLOCAL - case 963: + case 962: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Ignore -//line sql.y:4782 +//line sql.y:4778 { yyLOCAL = true } yyVAL.union = yyLOCAL - case 964: + case 963: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4785 +//line sql.y:4781 { yyVAL.empty = struct{}{} } - case 965: + case 964: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4787 +//line sql.y:4783 { yyVAL.empty = struct{}{} } - case 966: + case 965: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4789 +//line sql.y:4785 { yyVAL.empty = struct{}{} } - case 967: + case 966: yyDollar = yyS[yypt-5 : yypt+1] var yyLOCAL Statement -//line sql.y:4793 +//line sql.y:4789 { yyLOCAL = &CallProc{Name: yyDollar[2].tableName, Params: yyDollar[4].exprsUnion()} } yyVAL.union = yyLOCAL - case 968: + case 967: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL Exprs -//line sql.y:4798 +//line sql.y:4794 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 969: + case 968: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL Exprs -//line sql.y:4802 +//line sql.y:4798 { yyLOCAL = yyDollar[1].exprsUnion() } yyVAL.union = yyLOCAL - case 970: + case 969: yyDollar = yyS[yypt-0 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:4807 +//line sql.y:4803 { yyLOCAL = nil } yyVAL.union = yyLOCAL - case 971: + case 970: yyDollar = yyS[yypt-1 : yypt+1] var yyLOCAL []*IndexOption -//line sql.y:4809 +//line sql.y:4805 { yyLOCAL = []*IndexOption{yyDollar[1].indexOptionUnion()} } yyVAL.union = yyLOCAL - case 972: + case 971: yyDollar = yyS[yypt-2 : yypt+1] var yyLOCAL *IndexOption -//line sql.y:4813 +//line sql.y:4809 { yyLOCAL = &IndexOption{Name: string(yyDollar[1].str), String: string(yyDollar[2].colIdent.String())} } yyVAL.union = yyLOCAL - case 973: + case 972: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4819 +//line sql.y:4815 { yyVAL.colIdent = yyDollar[1].colIdent } - case 974: + case 973: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4823 +//line sql.y:4819 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].str)) } - case 976: + case 975: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4830 +//line sql.y:4826 { yyVAL.colIdent = NewColIdent(string(yyDollar[1].str)) } - case 977: + case 976: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4836 +//line sql.y:4832 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].colIdent.String())) } - case 978: + case 977: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4840 +//line sql.y:4836 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].str)) } - case 979: + case 978: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:4845 +//line sql.y:4841 { yyVAL.tableIdent = NewTableIdent("") } - case 980: + case 979: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4849 +//line sql.y:4845 { yyVAL.tableIdent = yyDollar[1].tableIdent } - case 982: + case 981: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:4856 +//line sql.y:4852 { yyVAL.tableIdent = NewTableIdent(string(yyDollar[1].str)) } - case 1392: + case 1391: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5290 +//line sql.y:5286 { if incNesting(yylex) { yylex.Error("max nesting level reached") return 1 } } - case 1393: + case 1392: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5299 +//line sql.y:5295 { decNesting(yylex) } - case 1394: + case 1393: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5304 +//line sql.y:5300 { skipToEnd(yylex) } - case 1395: + case 1394: yyDollar = yyS[yypt-0 : yypt+1] -//line sql.y:5309 +//line sql.y:5305 { skipToEnd(yylex) } - case 1396: + case 1395: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5313 +//line sql.y:5309 { skipToEnd(yylex) } - case 1397: + case 1396: yyDollar = yyS[yypt-1 : yypt+1] -//line sql.y:5317 +//line sql.y:5313 { skipToEnd(yylex) } diff --git a/go/vt/sqlparser/sql.y b/go/vt/sqlparser/sql.y index 2f580af3bb0..09220a09d79 100644 --- a/go/vt/sqlparser/sql.y +++ b/go/vt/sqlparser/sql.y @@ -1819,14 +1819,10 @@ table_option: { $$ = &TableOption{Name:string($1), Value:NewStrLiteral($3)} } -| ENGINE equal_opt id_or_var +| ENGINE equal_opt table_alias { $$ = &TableOption{Name:string($1), String:$3.String()} } -| ENGINE equal_opt STRING - { - $$ = &TableOption{Name:string($1), Value:NewStrLiteral($3)} - } | INSERT_METHOD equal_opt insert_method_options { $$ = &TableOption{Name:string($1), String:string($3)} From 2034f8973e4ba1eb848a5cf518a9b8d52a83e59a Mon Sep 17 00:00:00 2001 From: Sara Bee <855595+doeg@users.noreply.github.com> Date: Fri, 11 Jun 2021 06:20:12 -0400 Subject: [PATCH 232/310] [vtadmin-web] Small bugfix where stream source displayed instead of target Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com> --- web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx b/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx index 81272cb7d43..b9c8a472a70 100644 --- a/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx +++ b/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx @@ -89,7 +89,7 @@ export const WorkflowStreams = ({ clusterID, keyspace, name }: Props) => { {target ? ( - {source} + {target} ) : ( N/A From 8edb2842ddf7e7daf64dff30ea16ae4def421c5d Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 11 Jun 2021 23:20:54 +0530 Subject: [PATCH 233/310] sem table to store scope of each sqlparser.Select Signed-off-by: Harshit Gangal --- go/vt/vtgate/semantics/analyzer.go | 13 +++++++++---- go/vt/vtgate/semantics/semantic_state.go | 7 +++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go index cc82c982669..f9f70871aef 100644 --- a/go/vt/vtgate/semantics/analyzer.go +++ b/go/vt/vtgate/semantics/analyzer.go @@ -34,15 +34,18 @@ type ( exprDeps map[sqlparser.Expr]TableSet err error currentDb string + + selectScope map[*sqlparser.Select]*scope } ) // newAnalyzer create the semantic analyzer func newAnalyzer(dbName string, si SchemaInformation) *analyzer { return &analyzer{ - exprDeps: map[sqlparser.Expr]TableSet{}, - currentDb: dbName, - si: si, + exprDeps: map[sqlparser.Expr]TableSet{}, + selectScope: map[*sqlparser.Select]*scope{}, + currentDb: dbName, + si: si, } } @@ -54,7 +57,7 @@ func Analyze(statement sqlparser.Statement, currentDb string, si SchemaInformati if err != nil { return nil, err } - return &SemTable{exprDependencies: analyzer.exprDeps, Tables: analyzer.Tables}, nil + return &SemTable{exprDependencies: analyzer.exprDeps, Tables: analyzer.Tables, selectScope: analyzer.selectScope}, nil } // analyzeDown pushes new scopes when we encounter sub queries, @@ -65,6 +68,7 @@ func (a *analyzer) analyzeDown(cursor *sqlparser.Cursor) bool { switch node := n.(type) { case *sqlparser.Select: a.push(newScope(current)) + a.selectScope[node] = a.currentScope() if err := a.analyzeTableExprs(node.From); err != nil { a.err = err return false @@ -87,6 +91,7 @@ func (a *analyzer) analyzeDown(cursor *sqlparser.Cursor) bool { a.exprDeps[node] = t } } + // this is the visitor going down the tree. Returning false here would just not visit the children // to the current node, but that is not what we want if we have encountered an error. // In order to abort the whole visitation, we have to return true here and then return false in the `analyzeUp` method diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go index 3fbfb749ba4..7f05ada4e61 100644 --- a/go/vt/vtgate/semantics/semantic_state.go +++ b/go/vt/vtgate/semantics/semantic_state.go @@ -43,6 +43,7 @@ type ( SemTable struct { Tables []*TableInfo exprDependencies map[sqlparser.Expr]TableSet + selectScope map[*sqlparser.Select]*scope } scope struct { @@ -100,6 +101,12 @@ func (st *SemTable) Dependencies(expr sqlparser.Expr) TableSet { return deps } +// GetSelectTables returns the table in the select. +func (st *SemTable) GetSelectTables(node *sqlparser.Select) []*TableInfo { + scope := st.selectScope[node] + return scope.tables +} + func newScope(parent *scope) *scope { return &scope{parent: parent} } From 5e81293fd915402439f1dc6ba9daa1a80b9cee07 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Fri, 11 Jun 2021 23:24:33 +0530 Subject: [PATCH 234/310] expand the starExpr in select Signed-off-by: Harshit Gangal --- go/vt/vtgate/planbuilder/route_planning.go | 43 ++++++++++++- .../vtgate/planbuilder/route_planning_test.go | 61 ++++++++++++++++--- 2 files changed, 95 insertions(+), 9 deletions(-) diff --git a/go/vt/vtgate/planbuilder/route_planning.go b/go/vt/vtgate/planbuilder/route_planning.go index 75c4d2b4de3..4cedb6e137d 100644 --- a/go/vt/vtgate/planbuilder/route_planning.go +++ b/go/vt/vtgate/planbuilder/route_planning.go @@ -55,7 +55,7 @@ func newBuildSelectPlan(sel *sqlparser.Select, vschema ContextVSchema) (engine.P return nil, err } - sel = expandStar(sel, semTable, vschema) + sel = expandStar(sel, semTable) qgraph, err := createQGFromSelect(sel, semTable) if err != nil { @@ -99,8 +99,47 @@ func newBuildSelectPlan(sel *sqlparser.Select, vschema ContextVSchema) (engine.P return plan.Primitive(), nil } -func expandStar(sel *sqlparser.Select, semTable *semantics.SemTable, vschema semantics.SchemaInformation) *sqlparser.Select { +func expandStar(sel *sqlparser.Select, semTable *semantics.SemTable) *sqlparser.Select { // TODO we could store in semTable whether there are any * in the query that needs expanding or not + + _ = sqlparser.Rewrite(sel, func(cursor *sqlparser.Cursor) bool { + switch node := cursor.Node().(type) { + case *sqlparser.Select: + tables := semTable.GetSelectTables(node) + var selExprs sqlparser.SelectExprs + for _, selectExpr := range node.SelectExprs { + _, isStarExpr := selectExpr.(*sqlparser.StarExpr) + if !isStarExpr { + selExprs = append(selExprs, selectExpr) + continue + } + //if !starExpr.TableName.IsEmpty() { + // // TODO: only expand specific table + //} + var colNames sqlparser.SelectExprs + expandStar := true + for _, tbl := range tables { + if !tbl.Table.ColumnListAuthoritative { + expandStar = false + break + } + for _, col := range tbl.Table.Columns { + colNames = append(colNames, &sqlparser.AliasedExpr{ + Expr: sqlparser.NewColNameWithQualifier(col.Name.String(), sqlparser.TableName{Name: tbl.Table.Name}), + }) + } + } + if !expandStar { + selExprs = append(selExprs, selectExpr) + continue + } + selExprs = append(selExprs, colNames...) + } + node.SelectExprs = selExprs + } + + return true + }, nil) return sel } diff --git a/go/vt/vtgate/planbuilder/route_planning_test.go b/go/vt/vtgate/planbuilder/route_planning_test.go index ecf861474b9..8e2f1ee3950 100644 --- a/go/vt/vtgate/planbuilder/route_planning_test.go +++ b/go/vt/vtgate/planbuilder/route_planning_test.go @@ -128,11 +128,10 @@ func TestClone(t *testing.T) { } func TestExpandStar(t *testing.T) { - ast, err := sqlparser.Parse("select * from tbl") - require.NoError(t, err) schemaInfo := &fakeSI{ tables: map[string]*vindexes.Table{ - "tbl": { + "t1": { + Name: sqlparser.NewTableIdent("t1"), Columns: []vindexes.Column{{ Name: sqlparser.NewColIdent("a"), Type: sqltypes.VarChar, @@ -145,10 +144,58 @@ func TestExpandStar(t *testing.T) { }}, ColumnListAuthoritative: true, }, + "t2": { + Name: sqlparser.NewTableIdent("t2"), + Columns: []vindexes.Column{{ + Name: sqlparser.NewColIdent("c1"), + Type: sqltypes.VarChar, + }, { + Name: sqlparser.NewColIdent("c2"), + Type: sqltypes.VarChar, + }}, + ColumnListAuthoritative: true, + }, + "t3": { // non authoritative table. + Name: sqlparser.NewTableIdent("t3"), + Columns: []vindexes.Column{{ + Name: sqlparser.NewColIdent("col"), + Type: sqltypes.VarChar, + }}, + ColumnListAuthoritative: false, + }, }, } - semState, err := semantics.Analyze(ast, "db", schemaInfo) - require.NoError(t, err) - expanded := expandStar(ast.(*sqlparser.Select), semState, schemaInfo) - assert.Equal(t, "select tbl.a, tbl.b, tbl.c from tbl", sqlparser.String(expanded)) + cDB := "db" + tcases := []struct { + sql string + expSQL string + }{{ + sql: "select * from t1", + expSQL: "select t1.a, t1.b, t1.c from t1", + }, { + sql: "select t1.* from t1", + expSQL: "select t1.a, t1.b, t1.c from t1", + }, { + sql: "select *, 42, t1.* from t1", + expSQL: "select t1.a, t1.b, t1.c, 42, t1.a, t1.b, t1.c from t1", + }, { + sql: "select 42, t1.* from t1", + expSQL: "select 42, t1.a, t1.b, t1.c from t1", + }, { + sql: "select * from t1, t2", + expSQL: "select t1.a, t1.b, t1.c, t2.c1, t2.c2 from t1, t2", + }, { + sql: "select t1.* from t1, t2", + expSQL: "select t1.a, t1.b, t1.c from t1, t2", + }} + for _, tcase := range tcases { + t.Run(tcase.sql, func(t *testing.T) { + ast, err := sqlparser.Parse(tcase.sql) + require.NoError(t, err) + semState, err := semantics.Analyze(ast, cDB, schemaInfo) + require.NoError(t, err) + expanded := expandStar(ast.(*sqlparser.Select), semState) + assert.Equal(t, tcase.expSQL, sqlparser.String(expanded)) + }) + } } From e36e4b75144b570dd08532b579b9780ad688c5e4 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Sat, 12 Jun 2021 11:43:00 -0400 Subject: [PATCH 235/310] [vtctldserver] Update tests to prevent races during tmclient init Signed-off-by: Andrew Mason --- go/vt/vtctl/grpcvtctldserver/server_test.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 3fb15bf0f10..3db13543e1f 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -1328,7 +1328,9 @@ func TestDeleteCellsAlias(t *testing.T) { require.NoError(t, err, "test setup failed") } - vtctld := NewVtctldServer(tt.ts) + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, tt.ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) _, err := vtctld.DeleteCellsAlias(ctx, tt.req) if tt.shouldErr { assert.Error(t, err) @@ -2719,6 +2721,8 @@ func TestFindAllShardsInKeyspace(t *testing.T) { } func TestGetBackups(t *testing.T) { + t.Parallel() + ctx := context.Background() ts := memorytopo.NewServer() vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { @@ -3003,7 +3007,9 @@ func TestGetRoutingRules(t *testing.T) { factory.SetError(errors.New("topo down for testing")) } - vtctld := NewVtctldServer(ts) + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) resp, err := vtctld.GetRoutingRules(ctx, &vtctldatapb.GetRoutingRulesRequest{}) if tt.shouldErr { assert.Error(t, err) @@ -4515,7 +4521,9 @@ func TestRebuildVSchemaGraph(t *testing.T) { factory.SetError(errors.New("topo down for testing")) } - vtctld := NewVtctldServer(ts) + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, ts, nil, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) _, err := vtctld.RebuildVSchemaGraph(ctx, req) if tt.shouldErr { assert.Error(t, err) From 938c328361c578290f45fe8f799f658ccb6a8c98 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 10:55:31 +0300 Subject: [PATCH 236/310] Adding EnumText to Rule Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/proto/binlogdata/binlogdata.pb.go | 633 +++++++++--------- .../proto/binlogdata/binlogdata_vtproto.pb.go | 154 +++++ proto/binlogdata.proto | 5 + 3 files changed, 486 insertions(+), 306 deletions(-) diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index af9c9f9580c..fd65cda5f94 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -752,6 +752,11 @@ type Rule struct { // to be excluded. // TODO(sougou): support this on vstreamer side also. Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + // EnumText: optional, list per enum column name, the list of textual values. + // When reading the binary log, all enum values are numeric. But sometimes it + // is useful/needed to know what the textual mapping are. + // Online DDL provides such use case. + EnumText map[string]string `protobuf:"bytes,3,rep,name=enum_text,json=enumText,proto3" json:"enum_text,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Rule) Reset() { @@ -800,6 +805,13 @@ func (x *Rule) GetFilter() string { return "" } +func (x *Rule) GetEnumText() map[string]string { + if x != nil { + return x.EnumText + } + return nil +} + // Filter represents a list of ordered rules. The first // match wins. type Filter struct { @@ -2406,252 +2418,259 @@ var file_binlogdata_proto_rawDesc = []byte{ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x34, 0x0a, - 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x22, 0xb3, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, - 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, - 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, - 0x64, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, - 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, - 0x70, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x22, 0x51, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, + 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xae, 0x01, + 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x65, 0x78, + 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x65, + 0x78, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x65, 0x78, + 0x74, 0x1a, 0x3b, 0x0a, 0x0d, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, + 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x75, 0x6c, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, + 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, + 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, + 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x0e, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x13, + 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, + 0x52, 0x54, 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, + 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x6f, 0x6e, + 0x44, 0x64, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, + 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, + 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, + 0x70, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, + 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0x51, 0x0a, + 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x20, + 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, + 0x22, 0x61, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, + 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, + 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, - 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, - 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, - 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, - 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, - 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, - 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, - 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, - 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, - 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, - 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, - 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, - 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, - 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, - 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, - 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, - 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x4b, + 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, + 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, + 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x0c, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, + 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1c, 0x0a, + 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x72, + 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x37, + 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, + 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, + 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, + 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6d, + 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, + 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, + 0x70, 0x5f, 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x03, 0x52, 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x22, 0x41, 0x0a, 0x0d, + 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, + 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, + 0xc7, 0x02, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, + 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, 0x0a, 0x0f, 0x56, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x12, 0x56, 0x53, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, + 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, + 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, + 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, + 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, + 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, + 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, + 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, + 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, - 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, - 0x0a, 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, - 0x0a, 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, - 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, + 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, + 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, - 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, - 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, - 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, - 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, - 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, - 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, - 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, - 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, - 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, - 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, - 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, - 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, - 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, - 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, - 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, - 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, - 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, - 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, - 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, - 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, - 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, - 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, - 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, - 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, - 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, - 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, + 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, + 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, + 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, + 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, + 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, + 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, + 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, 0x0a, 0x0a, 0x56, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, + 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, 0x44, 0x10, 0x01, 0x12, 0x09, + 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, + 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, + 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, + 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, + 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, + 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x09, 0x12, 0x07, 0x0a, + 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, + 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49, + 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, + 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, 0x49, 0x44, 0x10, 0x0f, 0x12, + 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x10, 0x12, 0x0b, 0x0a, 0x07, + 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x53, + 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, + 0x4e, 0x54, 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, + 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, + 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, + 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2667,7 +2686,7 @@ func file_binlogdata_proto_rawDescGZIP() []byte { } var file_binlogdata_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_binlogdata_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_binlogdata_proto_msgTypes = make([]protoimpl.MessageInfo, 29) var file_binlogdata_proto_goTypes = []interface{}{ (OnDDLAction)(0), // 0: binlogdata.OnDDLAction (VEventType)(0), // 1: binlogdata.VEventType @@ -2702,75 +2721,77 @@ var file_binlogdata_proto_goTypes = []interface{}{ (*VStreamResultsRequest)(nil), // 30: binlogdata.VStreamResultsRequest (*VStreamResultsResponse)(nil), // 31: binlogdata.VStreamResultsResponse (*BinlogTransaction_Statement)(nil), // 32: binlogdata.BinlogTransaction.Statement - (*query.EventToken)(nil), // 33: query.EventToken - (*topodata.KeyRange)(nil), // 34: topodata.KeyRange - (topodata.TabletType)(0), // 35: topodata.TabletType - (*query.Row)(nil), // 36: query.Row - (*query.Field)(nil), // 37: query.Field - (*vtrpc.CallerID)(nil), // 38: vtrpc.CallerID - (*query.VTGateCallerID)(nil), // 39: query.VTGateCallerID - (*query.Target)(nil), // 40: query.Target - (*query.QueryResult)(nil), // 41: query.QueryResult + nil, // 33: binlogdata.Rule.EnumTextEntry + (*query.EventToken)(nil), // 34: query.EventToken + (*topodata.KeyRange)(nil), // 35: topodata.KeyRange + (topodata.TabletType)(0), // 36: topodata.TabletType + (*query.Row)(nil), // 37: query.Row + (*query.Field)(nil), // 38: query.Field + (*vtrpc.CallerID)(nil), // 39: vtrpc.CallerID + (*query.VTGateCallerID)(nil), // 40: query.VTGateCallerID + (*query.Target)(nil), // 41: query.Target + (*query.QueryResult)(nil), // 42: query.QueryResult } var file_binlogdata_proto_depIdxs = []int32{ 32, // 0: binlogdata.BinlogTransaction.statements:type_name -> binlogdata.BinlogTransaction.Statement - 33, // 1: binlogdata.BinlogTransaction.event_token:type_name -> query.EventToken - 34, // 2: binlogdata.StreamKeyRangeRequest.key_range:type_name -> topodata.KeyRange + 34, // 1: binlogdata.BinlogTransaction.event_token:type_name -> query.EventToken + 35, // 2: binlogdata.StreamKeyRangeRequest.key_range:type_name -> topodata.KeyRange 5, // 3: binlogdata.StreamKeyRangeRequest.charset:type_name -> binlogdata.Charset 6, // 4: binlogdata.StreamKeyRangeResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction 5, // 5: binlogdata.StreamTablesRequest.charset:type_name -> binlogdata.Charset 6, // 6: binlogdata.StreamTablesResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction - 11, // 7: binlogdata.Filter.rules:type_name -> binlogdata.Rule - 4, // 8: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode - 35, // 9: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType - 34, // 10: binlogdata.BinlogSource.key_range:type_name -> topodata.KeyRange - 12, // 11: binlogdata.BinlogSource.filter:type_name -> binlogdata.Filter - 0, // 12: binlogdata.BinlogSource.on_ddl:type_name -> binlogdata.OnDDLAction - 36, // 13: binlogdata.RowChange.before:type_name -> query.Row - 36, // 14: binlogdata.RowChange.after:type_name -> query.Row - 14, // 15: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange - 37, // 16: binlogdata.FieldEvent.fields:type_name -> query.Field - 29, // 17: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK - 17, // 18: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid - 2, // 19: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType - 17, // 20: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid - 19, // 21: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard - 1, // 22: binlogdata.VEvent.type:type_name -> binlogdata.VEventType - 15, // 23: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent - 16, // 24: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent - 18, // 25: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid - 20, // 26: binlogdata.VEvent.journal:type_name -> binlogdata.Journal - 28, // 27: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent - 37, // 28: binlogdata.MinimalTable.fields:type_name -> query.Field - 22, // 29: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable - 38, // 30: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 31: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 32: binlogdata.VStreamRequest.target:type_name -> query.Target - 12, // 33: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter - 29, // 34: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK - 21, // 35: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent - 38, // 36: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 37: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 38: binlogdata.VStreamRowsRequest.target:type_name -> query.Target - 41, // 39: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult - 37, // 40: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field - 37, // 41: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field - 36, // 42: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row - 36, // 43: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row - 29, // 44: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK - 41, // 45: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult - 38, // 46: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 47: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 48: binlogdata.VStreamResultsRequest.target:type_name -> query.Target - 37, // 49: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field - 36, // 50: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row - 3, // 51: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category - 5, // 52: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset - 53, // [53:53] is the sub-list for method output_type - 53, // [53:53] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 33, // 7: binlogdata.Rule.enum_text:type_name -> binlogdata.Rule.EnumTextEntry + 11, // 8: binlogdata.Filter.rules:type_name -> binlogdata.Rule + 4, // 9: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode + 36, // 10: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType + 35, // 11: binlogdata.BinlogSource.key_range:type_name -> topodata.KeyRange + 12, // 12: binlogdata.BinlogSource.filter:type_name -> binlogdata.Filter + 0, // 13: binlogdata.BinlogSource.on_ddl:type_name -> binlogdata.OnDDLAction + 37, // 14: binlogdata.RowChange.before:type_name -> query.Row + 37, // 15: binlogdata.RowChange.after:type_name -> query.Row + 14, // 16: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange + 38, // 17: binlogdata.FieldEvent.fields:type_name -> query.Field + 29, // 18: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK + 17, // 19: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid + 2, // 20: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType + 17, // 21: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid + 19, // 22: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard + 1, // 23: binlogdata.VEvent.type:type_name -> binlogdata.VEventType + 15, // 24: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent + 16, // 25: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent + 18, // 26: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid + 20, // 27: binlogdata.VEvent.journal:type_name -> binlogdata.Journal + 28, // 28: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent + 38, // 29: binlogdata.MinimalTable.fields:type_name -> query.Field + 22, // 30: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable + 39, // 31: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID + 40, // 32: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 41, // 33: binlogdata.VStreamRequest.target:type_name -> query.Target + 12, // 34: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter + 29, // 35: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK + 21, // 36: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent + 39, // 37: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 40, // 38: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 41, // 39: binlogdata.VStreamRowsRequest.target:type_name -> query.Target + 42, // 40: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult + 38, // 41: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field + 38, // 42: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field + 37, // 43: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row + 37, // 44: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row + 29, // 45: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK + 42, // 46: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult + 39, // 47: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 40, // 48: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 41, // 49: binlogdata.VStreamResultsRequest.target:type_name -> query.Target + 38, // 50: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field + 37, // 51: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row + 3, // 52: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category + 5, // 53: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset + 54, // [54:54] is the sub-list for method output_type + 54, // [54:54] is the sub-list for method input_type + 54, // [54:54] is the sub-list for extension type_name + 54, // [54:54] is the sub-list for extension extendee + 0, // [0:54] is the sub-list for field type_name } func init() { file_binlogdata_proto_init() } @@ -3122,7 +3143,7 @@ func file_binlogdata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_binlogdata_proto_rawDesc, NumEnums: 5, - NumMessages: 28, + NumMessages: 29, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go index 3c2cea19927..d23f617edf4 100644 --- a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go +++ b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go @@ -430,6 +430,25 @@ func (m *Rule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.EnumText) > 0 { + for k := range m.EnumText { + v := m.EnumText[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = encodeVarint(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } if len(m.Filter) > 0 { i -= len(m.Filter) copy(dAtA[i:], m.Filter) @@ -2046,6 +2065,14 @@ func (m *Rule) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + if len(m.EnumText) > 0 { + for k, v := range m.EnumText { + _ = k + _ = v + mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) + n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + } + } if m.unknownFields != nil { n += len(m.unknownFields) } @@ -3571,6 +3598,133 @@ func (m *Rule) UnmarshalVT(dAtA []byte) error { } m.Filter = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EnumText", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.EnumText == nil { + m.EnumText = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return ErrInvalidLength + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return ErrInvalidLength + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.EnumText[mapkey] = mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 777affe1766..23c5c727aa4 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -138,6 +138,11 @@ message Rule { // to be excluded. // TODO(sougou): support this on vstreamer side also. string filter = 2; + // EnumText: optional, list per enum column name, the list of textual values. + // When reading the binary log, all enum values are numeric. But sometimes it + // is useful/needed to know what the textual mapping are. + // Online DDL provides such use case. + map enum_text = 3; } // Filter represents a list of ordered rules. The first From 41d344ceef77803b0f7e587f07922d2e2d89ae22 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 10:56:09 +0300 Subject: [PATCH 237/310] more powerful parsing for enum column types Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/schema/parser.go | 36 ++++++++++++++++++++ go/vt/schema/parser_test.go | 55 +++++++++++++++++++++++++++++++ go/vt/vttablet/onlineddl/vrepl.go | 15 +++++++-- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/go/vt/schema/parser.go b/go/vt/schema/parser.go index aaac0b7e7b5..65527ba408b 100644 --- a/go/vt/schema/parser.go +++ b/go/vt/schema/parser.go @@ -19,8 +19,10 @@ package schema import ( "fmt" "regexp" + "strconv" "strings" + "vitess.io/vitess/go/textutil" "vitess.io/vitess/go/vt/sqlparser" ) @@ -51,6 +53,8 @@ var ( } createTableRegexp = regexp.MustCompile(`(?s)(?i)(CREATE\s+TABLE\s+)` + "`" + `([^` + "`" + `]+)` + "`" + `(\s*[(].*$)`) revertStatementRegexp = regexp.MustCompile(`(?i)^revert\s+([\S]*)$`) + + enumValuesRegexp = regexp.MustCompile("(?i)^enum[(](.*)[)]$") ) // ReplaceTableNameInCreateTableStatement returns a modified CREATE TABLE statement, such that the table name is replaced with given name. @@ -101,3 +105,35 @@ func legacyParseRevertUUID(sql string) (uuid string, err error) { } return uuid, nil } + +// ParseEnumValues parses the comma delimited part of an enum column definition +func ParseEnumValues(enumColumnType string) string { + if submatch := enumValuesRegexp.FindStringSubmatch(enumColumnType); len(submatch) > 0 { + return submatch[1] + } + return enumColumnType +} + +// ParseEnumTokens parses the comma delimited part of an enum column definition and +// returns the (unquoted) text values +func ParseEnumTokens(enumValues string) []string { + enumValues = ParseEnumValues(enumValues) + tokens := textutil.SplitDelimitedList(enumValues) + for i := range tokens { + if strings.HasPrefix(tokens[i], `'`) && strings.HasSuffix(tokens[i], `'`) { + tokens[i] = strings.Trim(tokens[i], `'`) + } + } + return tokens +} + +// ParseEnumTokensMap parses the comma delimited part of an enum column definition +// and returns a map where ["1"] is the first token, and [""] is th elast token +func ParseEnumTokensMap(enumValues string) map[string]string { + tokens := ParseEnumTokens(enumValues) + tokensMap := map[string]string{} + for i, token := range tokens { + tokensMap[strconv.Itoa(i+1)] = token + } + return tokensMap +} diff --git a/go/vt/schema/parser_test.go b/go/vt/schema/parser_test.go index f16dc8122f3..f0ab9bdfc4c 100644 --- a/go/vt/schema/parser_test.go +++ b/go/vt/schema/parser_test.go @@ -109,3 +109,58 @@ func TestLegacyParseRevertUUID(t *testing.T) { assert.Error(t, err) } } + +func TestParseEnumValues(t *testing.T) { + { + inputs := []string{ + `enum('x-small','small','medium','large','x-large')`, + `ENUM('x-small','small','medium','large','x-large')`, + `'x-small','small','medium','large','x-large'`, + } + for _, input := range inputs { + enumValues := ParseEnumValues(input) + assert.Equal(t, `'x-small','small','medium','large','x-large'`, enumValues) + } + } + { + inputs := []string{ + ``, + `abc`, + `func('x-small','small','medium','large','x-large')`, + } + for _, input := range inputs { + enumValues := ParseEnumValues(input) + assert.Equal(t, input, enumValues) + } + } +} + +func TestParseEnumTokens(t *testing.T) { + inputs := []string{ + `enum('x-small','small','medium','large','x-large')`, + `'x-small','small','medium','large','x-large'`, + } + for _, input := range inputs { + enumTokens := ParseEnumTokens(input) + expect := []string{"x-small", "small", "medium", "large", "x-large"} + assert.Equal(t, expect, enumTokens) + } +} + +func TestParseEnumTokensMap(t *testing.T) { + inputs := []string{ + `enum('x-small','small','medium','large','x-large')`, + `'x-small','small','medium','large','x-large'`, + } + for _, input := range inputs { + enumTokensMap := ParseEnumTokensMap(input) + expect := map[string]string{ + "1": "x-small", + "2": "small", + "3": "medium", + "4": "large", + "5": "x-large", + } + assert.Equal(t, expect, enumTokensMap) + } +} diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 561211d12b5..c322d97ae48 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -35,6 +35,7 @@ import ( "vitess.io/vitess/go/vt/dbconnpool" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/onlineddl/vrepl" @@ -73,6 +74,7 @@ type VRepl struct { sourceAutoIncrement uint64 filterQuery string + enumTextMap map[string]string bls *binlogdatapb.BinlogSource parser *vrepl.AlterTableParser @@ -89,6 +91,7 @@ func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alter targetTable: targetTable, alterOptions: alterOptions, parser: vrepl.NewAlterTableParser(), + enumTextMap: map[string]string{}, } } @@ -217,7 +220,7 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect } if strings.HasPrefix(columnType, "enum") { column.Type = vrepl.EnumColumnType - column.EnumValues = vrepl.ParseEnumValues(columnType) + column.EnumValues = schema.ParseEnumValues(columnType) } if strings.HasPrefix(columnType, "binary") { column.Type = vrepl.BinaryColumnType @@ -364,6 +367,7 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection if column.Name == mappedColumn.Name && column.Type == vrepl.EnumColumnType && mappedColumn.Charset != "" { v.targetSharedColumns.SetEnumToTextConversion(column.Name) v.targetSharedColumns.SetEnumValues(column.Name, column.EnumValues) + v.enumTextMap[column.Name] = column.EnumValues } } @@ -394,7 +398,10 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { case col.Type == vrepl.JSONColumnType: sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) case col.EnumToTextConversion: - sb.WriteString(fmt.Sprintf("ELT(%s, %s)", escapeName(name), col.EnumValues)) + // sb.WriteString(fmt.Sprintf("ELT(%s, %s)", escapeName(name), col.EnumValues)) + // Enforce ENUM value to be textual + sb.WriteString(fmt.Sprintf("CONCAT(%s)", escapeName(name))) + // sb.WriteString(escapeName(name)) default: sb.WriteString(escapeName(name)) } @@ -419,6 +426,10 @@ func (v *VRepl) analyzeBinlogSource(ctx context.Context) { Match: v.targetTable, Filter: v.filterQuery, } + if len(v.enumTextMap) > 0 { + rule.EnumText = v.enumTextMap + } + bls.Filter.Rules = append(bls.Filter.Rules, rule) v.bls = bls } From a51e637a9ee386ef038639bac961bfe3294c7cd4 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 10:57:04 +0300 Subject: [PATCH 238/310] populating EnumText in vreplication, table planner uses enum-to-text mapping Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl/parser.go | 9 ----- .../vreplication/replicator_plan.go | 36 +++++++++++++------ .../vreplication/table_plan_builder.go | 34 +++++++++--------- .../tabletmanager/vreplication/vcopier.go | 1 - 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl/parser.go b/go/vt/vttablet/onlineddl/vrepl/parser.go index 0bd1a75eb01..897dcaf060a 100644 --- a/go/vt/vttablet/onlineddl/vrepl/parser.go +++ b/go/vt/vttablet/onlineddl/vrepl/parser.go @@ -19,7 +19,6 @@ var ( dropColumnRegexp = regexp.MustCompile(`(?i)\bdrop\s+(column\s+|)([\S]+)$`) renameTableRegexp = regexp.MustCompile(`(?i)\brename\s+(to|as)\s+`) autoIncrementRegexp = regexp.MustCompile(`(?i)\bauto_increment[\s]*[=]?[\s]*([0-9]+)`) - enumValuesRegexp = regexp.MustCompile("^enum[(](.*)[)]$") ) // AlterTableParser is a parser tool for ALTER TABLE statements @@ -199,11 +198,3 @@ func (p *AlterTableParser) GetAlterStatementOptions() string { func (p *AlterTableParser) ColumnRenameMap() map[string]string { return p.columnRenameMap } - -// ParseEnumValues parses the comma delimited part of an enum column definition -func ParseEnumValues(enumColumnType string) string { - if submatch := enumValuesRegexp.FindStringSubmatch(enumColumnType); len(submatch) > 0 { - return submatch[1] - } - return enumColumnType -} diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 672c40c56bc..5a5b48dfd7b 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -25,15 +25,14 @@ import ( "google.golang.org/protobuf/proto" "vitess.io/vitess/go/bytes2" - - "vitess.io/vitess/go/vt/binlog/binlogplayer" - "vitess.io/vitess/go/vt/vtgate/evalengine" - "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/sqlparser" - + "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" + 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/evalengine" ) // ReplicatorPlan is the execution plan for the replicator. It contains @@ -175,10 +174,11 @@ type TablePlan struct { // If the plan is an insertIgnore type, then Insert // and Update contain 'insert ignore' statements and // Delete is nil. - Insert *sqlparser.ParsedQuery - Update *sqlparser.ParsedQuery - Delete *sqlparser.ParsedQuery - Fields []*querypb.Field + Insert *sqlparser.ParsedQuery + Update *sqlparser.ParsedQuery + Delete *sqlparser.ParsedQuery + Fields []*querypb.Field + EnumValuesMap map[string](map[string]string) // PKReferences is used to check if an event changed // a primary key column (row move). PKReferences []string @@ -289,7 +289,21 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun after = true vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + if enumValues, ok := tp.EnumValuesMap[field.Name]; ok && vals[i].IsQuoted() { + // The fact that this fielkd has a EnumValuesMap entry, means we must + // use the enum's text value as opposed to the enum's numerical value. + // Once known use case is with Online DDL, when a column is converted from + // ENUM to a VARCHAR/TEXT. + // The above vals[i].IsQuoted() helps us to exclude a NULL value + enumValue, enumValueOK := enumValues[vals[i].ToString()] + if !enumValueOK { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Invalid enum value: %v for field %s", vals[i], field.Name) + } + // get the enum text fir this val + bindvars["a_"+field.Name] = sqltypes.StringBindVariable(enumValue) + } else { + bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + } } } switch { diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 87836b8dcf3..15fc3ef7537 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -22,13 +22,12 @@ import ( "sort" "strings" - "vitess.io/vitess/go/vt/binlog/binlogplayer" - - querypb "vitess.io/vitess/go/vt/proto/query" - "vitess.io/vitess/go/sqltypes" + "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/key" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + "vitess.io/vitess/go/vt/schema" "vitess.io/vitess/go/vt/sqlparser" ) @@ -144,7 +143,7 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, pkInfoMap map[string][]*Pr if rule == nil { continue } - tablePlan, err := buildTablePlan(tableName, rule.Filter, pkInfoMap, lastpk, stats) + tablePlan, err := buildTablePlan(tableName, rule.Filter, pkInfoMap, lastpk, rule.EnumText, stats) if err != nil { return nil, err } @@ -183,7 +182,7 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru return nil, nil } -func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKeyInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { +func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKeyInfo, lastpk *sqltypes.Result, enumTextMap map[string]string, stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. switch { @@ -206,6 +205,12 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey Match: fromTable, } + enumValuesMap := map[string](map[string]string){} + for k, v := range enumTextMap { + tokensMap := schema.ParseEnumTokensMap(v) + enumValuesMap[k] = tokensMap + } + if expr, ok := sel.SelectExprs[0].(*sqlparser.StarExpr); ok { // If it's a "select *", we return a partial plan, and complete // it when we get back field info from the stream. @@ -217,11 +222,13 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey } sendRule.Filter = query tablePlan := &TablePlan{ - TargetName: tableName, - SendRule: sendRule, - Lastpk: lastpk, - Stats: stats, + TargetName: tableName, + SendRule: sendRule, + Lastpk: lastpk, + Stats: stats, + EnumValuesMap: enumValuesMap, } + return tablePlan, nil } @@ -272,6 +279,7 @@ func buildTablePlan(tableName, filter string, pkInfoMap map[string][]*PrimaryKey tablePlan := tpb.generate() tablePlan.SendRule = sendRule + tablePlan.EnumValuesMap = enumValuesMap return tablePlan, nil } @@ -547,9 +555,6 @@ func (tpb *tablePlanBuilder) generateValuesPart(buf *sqlparser.TrackedBuffer, bv separator = "," switch cexpr.operation { case opExpr: - // if cexpr.colType == querypb.Type_ENUM { - // fmt.Printf("========= found ENUM type for %v\n", cexpr.expr) - // } if cexpr.colType == querypb.Type_JSON { buf.Myprintf("convert(%v using utf8mb4)", cexpr.expr) } else { @@ -635,9 +640,6 @@ func (tpb *tablePlanBuilder) generateUpdateStatement() *sqlparser.ParsedQuery { separator = ", " switch cexpr.operation { case opExpr: - // if cexpr.colType == querypb.Type_ENUM { - // fmt.Printf("========= found ENUM type for %v\n", cexpr.expr) - // } bvf.mode = bvAfter if cexpr.colType == querypb.Type_JSON { buf.Myprintf("convert(%v using utf8mb4)", cexpr.expr) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index a16cb1ba528..2da479cd34d 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -234,7 +234,6 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma break } } - if vc.tablePlan == nil { if len(rows.Fields) == 0 { return fmt.Errorf("expecting field event first, got: %v", rows) From 7afb9a95c2ac41c5622d9ce0ecfedd48aa2e5267 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 10:57:47 +0300 Subject: [PATCH 239/310] adding enum-to-varchar suite test Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../testdata/enum-to-varchar/alter | 1 + .../testdata/enum-to-varchar/create.sql | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/create.sql diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/alter new file mode 100644 index 00000000000..a7f5412d310 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/alter @@ -0,0 +1 @@ +change e e varchar(32) not null default '' diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/create.sql new file mode 100644 index 00000000000..109b4f63101 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar/create.sql @@ -0,0 +1,26 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + i int not null, + e enum('red', 'green', 'blue', 'orange') null default null collate 'utf8_bin', + primary key(id) +) auto_increment=1; + +insert into onlineddl_test values (null, 7, 'red'); + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, 11, 'red'); + insert into onlineddl_test values (null, 13, 'green'); + insert into onlineddl_test values (null, 17, 'blue'); + set @last_insert_id := last_insert_id(); + update onlineddl_test set e='orange' where id = @last_insert_id; +end ;; From 65276ab4bb457d41185d9150ef1bb0f35df8c068 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 10:57:56 +0300 Subject: [PATCH 240/310] go mod tidy Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index 9217f1c5bc0..a97abe16eb7 100644 --- a/go.sum +++ b/go.sum @@ -695,6 +695,7 @@ github.com/spyzhov/ajson v0.4.2 h1:JMByd/jZApPKDvNsmO90X2WWGbmT2ahDFp73QhZbg3s= github.com/spyzhov/ajson v0.4.2/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzyqMuVA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= From 6ca964e0099906876215e03cd823b4be55f5e013 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 11:18:08 +0300 Subject: [PATCH 241/310] stricter check that mapped column is not an enum Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index c322d97ae48..0f53e8ebe6e 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -364,7 +364,8 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection for i := range v.sourceSharedColumns.Columns() { column := v.sourceSharedColumns.Columns()[i] mappedColumn := v.targetSharedColumns.Columns()[i] - if column.Name == mappedColumn.Name && column.Type == vrepl.EnumColumnType && mappedColumn.Charset != "" { + if column.Name == mappedColumn.Name && column.Type == vrepl.EnumColumnType && mappedColumn.Type != vrepl.EnumColumnType && mappedColumn.Charset != "" { + // A column is converted from ENUM type to textual type v.targetSharedColumns.SetEnumToTextConversion(column.Name) v.targetSharedColumns.SetEnumValues(column.Name, column.EnumValues) v.enumTextMap[column.Name] = column.EnumValues From 4462415aacce5e2c05046deffc1ebfa318e3323f Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 11:19:26 +0300 Subject: [PATCH 242/310] remove comments Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 0f53e8ebe6e..a52f6a2bc60 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -399,10 +399,7 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { case col.Type == vrepl.JSONColumnType: sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) case col.EnumToTextConversion: - // sb.WriteString(fmt.Sprintf("ELT(%s, %s)", escapeName(name), col.EnumValues)) - // Enforce ENUM value to be textual sb.WriteString(fmt.Sprintf("CONCAT(%s)", escapeName(name))) - // sb.WriteString(escapeName(name)) default: sb.WriteString(escapeName(name)) } From 363c0cc367f3652bc2b11766eb06b073948b9de8 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 11:26:22 +0300 Subject: [PATCH 243/310] code comments Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl/types.go | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index 9f3aa83b3d8..2bceef5c2a0 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -170,16 +170,19 @@ func (l *ColumnList) Len() int { return len(l.columns) } -func (this *ColumnList) SetEnumToTextConversion(columnName string) { - this.GetColumn(columnName).EnumToTextConversion = true +// SetEnumToTextConversion tells this column list that an enum is conveted to text +func (l *ColumnList) SetEnumToTextConversion(columnName string) { + l.GetColumn(columnName).EnumToTextConversion = true } -func (this *ColumnList) IsEnumToTextConversion(columnName string) bool { - return this.GetColumn(columnName).EnumToTextConversion +// IsEnumToTextConversion tells whether an enum was converted to text +func (l *ColumnList) IsEnumToTextConversion(columnName string) bool { + return l.GetColumn(columnName).EnumToTextConversion } -func (this *ColumnList) SetEnumValues(columnName string, enumValues string) { - this.GetColumn(columnName).EnumValues = enumValues +// SetEnumValues sets a columns enum values list, e.g. 'red','green','blue' +func (l *ColumnList) SetEnumValues(columnName string, enumValues string) { + l.GetColumn(columnName).EnumValues = enumValues } // UniqueKey is the combination of a key's name and columns From 88d509ead786cb5b6b969810a49a9ecb2d0e9aeb Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 12:17:22 +0300 Subject: [PATCH 244/310] only convert using utf8, no binary Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 2 +- go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 54aee9a9909..ecbf42aec96 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -403,7 +403,7 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { fmt.Printf("============ collcation change: %s => %s\n", col.Collation, targetCol.Collation) if strings.HasPrefix(targetCol.Charset, "utf8") { // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - sb.WriteString(fmt.Sprintf("convert(convert(convert(%s USING %s) USING binary) USING %s)", escapeName(name), col.Charset, targetCol.Charset)) + sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) } else { sb.WriteString(fmt.Sprintf("convert(%s, char character set %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 89c0c3190fa..f7be38644e2 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -173,7 +173,8 @@ func (rs *rowStreamer) buildSelect() (string, error) { for _, col := range rs.plan.Table.Fields { if rs.plan.convertToBinary[col.Name] { // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) - buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + buf.Myprintf("%sconvert(%v using utf8)", prefix, sqlparser.NewColIdent(col.Name)) // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } else { buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) From 8b96f759728f52eb092ffe173f52c3bc988cfd81 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 15:11:52 +0300 Subject: [PATCH 245/310] mapped column Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index a52f6a2bc60..87e2ef1a588 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -366,9 +366,9 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection mappedColumn := v.targetSharedColumns.Columns()[i] if column.Name == mappedColumn.Name && column.Type == vrepl.EnumColumnType && mappedColumn.Type != vrepl.EnumColumnType && mappedColumn.Charset != "" { // A column is converted from ENUM type to textual type - v.targetSharedColumns.SetEnumToTextConversion(column.Name) - v.targetSharedColumns.SetEnumValues(column.Name, column.EnumValues) - v.enumTextMap[column.Name] = column.EnumValues + v.targetSharedColumns.SetEnumToTextConversion(mappedColumn.Name) + v.targetSharedColumns.SetEnumValues(mappedColumn.Name, column.EnumValues) + v.enumTextMap[mappedColumn.Name] = column.EnumValues } } From 68e10c4a0f9a44f51395d27103e589b6f54616f2 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 15:20:23 +0300 Subject: [PATCH 246/310] test suite: enum to varchar while renaming it Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../enum-to-varchar-rename/after_columns | 1 + .../testdata/enum-to-varchar-rename/alter | 1 + .../enum-to-varchar-rename/before_columns | 1 + .../enum-to-varchar-rename/create.sql | 26 +++++++++++++++++++ 4 files changed, 29 insertions(+) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/after_columns create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/alter create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/before_columns create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/create.sql diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/after_columns b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/after_columns new file mode 100644 index 00000000000..25931ae510f --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/after_columns @@ -0,0 +1 @@ +id, i, e2 diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/alter new file mode 100644 index 00000000000..a6577ee09e9 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/alter @@ -0,0 +1 @@ +change e e2 varchar(32) not null default '' diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/before_columns b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/before_columns new file mode 100644 index 00000000000..8dbd253ca71 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/before_columns @@ -0,0 +1 @@ +id, i, e diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/create.sql new file mode 100644 index 00000000000..109b4f63101 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/enum-to-varchar-rename/create.sql @@ -0,0 +1,26 @@ +drop table if exists onlineddl_test; +create table onlineddl_test ( + id int auto_increment, + i int not null, + e enum('red', 'green', 'blue', 'orange') null default null collate 'utf8_bin', + primary key(id) +) auto_increment=1; + +insert into onlineddl_test values (null, 7, 'red'); + +drop event if exists onlineddl_test; +delimiter ;; +create event onlineddl_test + on schedule every 1 second + starts current_timestamp + ends current_timestamp + interval 60 second + on completion not preserve + enable + do +begin + insert into onlineddl_test values (null, 11, 'red'); + insert into onlineddl_test values (null, 13, 'green'); + insert into onlineddl_test values (null, 17, 'blue'); + set @last_insert_id := last_insert_id(); + update onlineddl_test set e='orange' where id = @last_insert_id; +end ;; From 21b59edca61b614ae7744dd883fca6b40344e61f Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:24:44 +0300 Subject: [PATCH 247/310] working. Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/mysql/constants.go | 34 +- .../alter-charset-non-utf8-80}/alter | 0 .../alter-charset-non-utf8-80}/create.sql | 13 +- .../alter-charset-non-utf8-80/ignore_versions | 1 + .../alter-charset-non-utf8}/alter | 0 .../alter-charset-non-utf8}/create.sql | 9 +- .../alter-charset-non-utf8/ignore_versions | 1 + .../__expect_failure | 1 - go/vt/proto/binlogdata/binlogdata.pb.go | 938 ++++++++++-------- .../proto/binlogdata/binlogdata_vtproto.pb.go | 348 +++++++ go/vt/vttablet/onlineddl/vrepl.go | 78 +- .../vreplication/replicator_plan.go | 61 +- .../vreplication/table_plan_builder.go | 16 +- .../tabletserver/vstreamer/rowstreamer.go | 2 +- 14 files changed, 1036 insertions(+), 466 deletions(-) rename go/test/endtoend/onlineddl/vrepl_suite/{tmptestdata/fail-alter-charset-non-utf8 => testdata/alter-charset-non-utf8-80}/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset-all-dml => testdata/alter-charset-non-utf8-80}/create.sql (50%) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata/alter-charset-all-dml => testdata/alter-charset-non-utf8}/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{tmptestdata/fail-alter-charset-non-utf8 => testdata/alter-charset-non-utf8}/create.sql (57%) create mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure diff --git a/go/mysql/constants.go b/go/mysql/constants.go index b2d4c86db1d..726ec00b76e 100644 --- a/go/mysql/constants.go +++ b/go/mysql/constants.go @@ -16,7 +16,13 @@ limitations under the License. package mysql -import "strings" +import ( + "strings" + + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/charmap" + "golang.org/x/text/encoding/simplifiedchinese" +) const ( // MaxPacketSize is the maximum payload length of a packet @@ -626,6 +632,32 @@ var CharacterSetMap = map[string]uint8{ "eucjpms": 97, } +// CharacterSetEncoding maps a charset name to a golang encoder. +// golang does not support encoders for all MySQL charsets. +// A charset not in this map is unsupported. +// A trivial encoding (e.g. utf8) has a `nil` encoder +var CharacterSetEncoding = map[string]encoding.Encoding{ + "cp850": charmap.CodePage850, + "koi8r": charmap.KOI8R, + "latin1": charmap.Windows1252, + "latin2": charmap.ISO8859_2, + "ascii": nil, + "hebrew": charmap.ISO8859_8, + "greek": charmap.ISO8859_7, + "cp1250": charmap.Windows1250, + "gbk": simplifiedchinese.GBK, + "latin5": charmap.ISO8859_9, + "utf8": nil, + "cp866": charmap.CodePage866, + "cp852": charmap.CodePage852, + "latin7": charmap.ISO8859_13, + "utf8mb4": nil, + "cp1251": charmap.Windows1251, + "cp1256": charmap.Windows1256, + "cp1257": charmap.Windows1257, + "binary": nil, +} + // ReverseCharacterSetMap maps a charset integer code to charset name var ReverseCharacterSetMap = map[uint8]string{} diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql similarity index 50% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql index c55c793ee1d..6f97756291b 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql @@ -5,10 +5,14 @@ create table onlineddl_test ( t2 varchar(128) charset latin1 collate latin1_swedish_ci, tutf8 varchar(128) charset utf8, tutf8mb4 varchar(128) charset utf8mb4, - random_value varchar(128) charset ascii, + tlatin1 varchar(128) charset latin1 collate latin1_swedish_ci, primary key(id) ) auto_increment=1; +insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); +insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting', 'átesting'); +insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀', 'átesting'); + drop event if exists onlineddl_test; delimiter ;; create event onlineddl_test @@ -20,9 +24,6 @@ create event onlineddl_test do begin insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting', md5(rand())); - insert into onlineddl_test values (null, 'átesting_del', 'átesting', 'átesting', 'átesting', md5(rand())); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀', md5(rand())); - update onlineddl_test set t1='átesting2' where t1='átesting' order by id desc limit 1; - delete from onlineddl_test where t1='átesting_del' order by id desc limit 1; + insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); + insert into onlineddl_test values (null, 'testátest-binlog', 'testátest-binlog', 'testátest-binlog', '🍻😀', 'átesting-binlog'); end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions new file mode 100644 index 00000000000..0790a1e68fd --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/ignore_versions @@ -0,0 +1 @@ +(5.5|5.6|5.7) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/alter-charset-all-dml/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql similarity index 57% rename from go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql index 9db84563248..d0d19253449 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql @@ -5,9 +5,13 @@ create table onlineddl_test ( t2 varchar(128) charset latin1 collate latin1_swedish_ci, tutf8 varchar(128) charset utf8, tutf8mb4 varchar(128) charset utf8mb4, + tlatin1 varchar(128) charset latin1 collate latin1_swedish_ci, primary key(id) ) auto_increment=1; +insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); +insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting', 'átesting'); + drop event if exists onlineddl_test; delimiter ;; create event onlineddl_test @@ -18,7 +22,6 @@ create event onlineddl_test enable do begin - insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); + insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); + insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions new file mode 100644 index 00000000000..b6de5f8d9f5 --- /dev/null +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/ignore_versions @@ -0,0 +1 @@ +(5.5|5.6) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure deleted file mode 100644 index 925d0d81ded..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/tmptestdata/fail-alter-charset-non-utf8/__expect_failure +++ /dev/null @@ -1 +0,0 @@ -Vitess does not support charset diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index af9c9f9580c..4f58f679bd1 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -366,7 +366,7 @@ func (x Filter_FieldEventMode) Number() protoreflect.EnumNumber { // Deprecated: Use Filter_FieldEventMode.Descriptor instead. func (Filter_FieldEventMode) EnumDescriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{7, 0} + return file_binlogdata_proto_rawDescGZIP(), []int{8, 0} } // Charset is the per-statement charset info from a QUERY_EVENT binlog entry. @@ -725,6 +725,64 @@ func (x *StreamTablesResponse) GetBinlogTransaction() *BinlogTransaction { return nil } +// CharsetConversion represent a conversion of text from one charset to another +type CharsetConversion struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // FromCharset is the charset name from which we convert the text (e.g. latin1) + FromCharset string `protobuf:"bytes,1,opt,name=from_charset,json=fromCharset,proto3" json:"from_charset,omitempty"` + // ToCharset is the charset name to which we convert the text (e.g. utf8mb4) + ToCharset string `protobuf:"bytes,2,opt,name=to_charset,json=toCharset,proto3" json:"to_charset,omitempty"` +} + +func (x *CharsetConversion) Reset() { + *x = CharsetConversion{} + if protoimpl.UnsafeEnabled { + mi := &file_binlogdata_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CharsetConversion) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CharsetConversion) ProtoMessage() {} + +func (x *CharsetConversion) ProtoReflect() protoreflect.Message { + mi := &file_binlogdata_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CharsetConversion.ProtoReflect.Descriptor instead. +func (*CharsetConversion) Descriptor() ([]byte, []int) { + return file_binlogdata_proto_rawDescGZIP(), []int{6} +} + +func (x *CharsetConversion) GetFromCharset() string { + if x != nil { + return x.FromCharset + } + return "" +} + +func (x *CharsetConversion) GetToCharset() string { + if x != nil { + return x.ToCharset + } + return "" +} + // Rule represents one rule in a Filter. type Rule struct { state protoimpl.MessageState @@ -751,13 +809,14 @@ type Rule struct { // "exclude" value, which will cause the matched tables // to be excluded. // TODO(sougou): support this on vstreamer side also. - Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` + ConvertCharset map[string]*CharsetConversion `protobuf:"bytes,3,rep,name=convert_charset,json=convertCharset,proto3" json:"convert_charset,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Rule) Reset() { *x = Rule{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[6] + mi := &file_binlogdata_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -770,7 +829,7 @@ func (x *Rule) String() string { func (*Rule) ProtoMessage() {} func (x *Rule) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[6] + mi := &file_binlogdata_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -783,7 +842,7 @@ func (x *Rule) ProtoReflect() protoreflect.Message { // Deprecated: Use Rule.ProtoReflect.Descriptor instead. func (*Rule) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{6} + return file_binlogdata_proto_rawDescGZIP(), []int{7} } func (x *Rule) GetMatch() string { @@ -800,6 +859,13 @@ func (x *Rule) GetFilter() string { return "" } +func (x *Rule) GetConvertCharset() map[string]*CharsetConversion { + if x != nil { + return x.ConvertCharset + } + return nil +} + // Filter represents a list of ordered rules. The first // match wins. type Filter struct { @@ -822,7 +888,7 @@ type Filter struct { func (x *Filter) Reset() { *x = Filter{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[7] + mi := &file_binlogdata_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -835,7 +901,7 @@ func (x *Filter) String() string { func (*Filter) ProtoMessage() {} func (x *Filter) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[7] + mi := &file_binlogdata_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -848,7 +914,7 @@ func (x *Filter) ProtoReflect() protoreflect.Message { // Deprecated: Use Filter.ProtoReflect.Descriptor instead. func (*Filter) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{7} + return file_binlogdata_proto_rawDescGZIP(), []int{8} } func (x *Filter) GetRules() []*Rule { @@ -902,7 +968,7 @@ type BinlogSource struct { func (x *BinlogSource) Reset() { *x = BinlogSource{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[8] + mi := &file_binlogdata_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -915,7 +981,7 @@ func (x *BinlogSource) String() string { func (*BinlogSource) ProtoMessage() {} func (x *BinlogSource) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[8] + mi := &file_binlogdata_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -928,7 +994,7 @@ func (x *BinlogSource) ProtoReflect() protoreflect.Message { // Deprecated: Use BinlogSource.ProtoReflect.Descriptor instead. func (*BinlogSource) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{8} + return file_binlogdata_proto_rawDescGZIP(), []int{9} } func (x *BinlogSource) GetKeyspace() string { @@ -1017,7 +1083,7 @@ type RowChange struct { func (x *RowChange) Reset() { *x = RowChange{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[9] + mi := &file_binlogdata_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1030,7 +1096,7 @@ func (x *RowChange) String() string { func (*RowChange) ProtoMessage() {} func (x *RowChange) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[9] + mi := &file_binlogdata_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1043,7 +1109,7 @@ func (x *RowChange) ProtoReflect() protoreflect.Message { // Deprecated: Use RowChange.ProtoReflect.Descriptor instead. func (*RowChange) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{9} + return file_binlogdata_proto_rawDescGZIP(), []int{10} } func (x *RowChange) GetBefore() *query.Row { @@ -1073,7 +1139,7 @@ type RowEvent struct { func (x *RowEvent) Reset() { *x = RowEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[10] + mi := &file_binlogdata_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1086,7 +1152,7 @@ func (x *RowEvent) String() string { func (*RowEvent) ProtoMessage() {} func (x *RowEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[10] + mi := &file_binlogdata_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1099,7 +1165,7 @@ func (x *RowEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use RowEvent.ProtoReflect.Descriptor instead. func (*RowEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{10} + return file_binlogdata_proto_rawDescGZIP(), []int{11} } func (x *RowEvent) GetTableName() string { @@ -1129,7 +1195,7 @@ type FieldEvent struct { func (x *FieldEvent) Reset() { *x = FieldEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[11] + mi := &file_binlogdata_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1142,7 +1208,7 @@ func (x *FieldEvent) String() string { func (*FieldEvent) ProtoMessage() {} func (x *FieldEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[11] + mi := &file_binlogdata_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1155,7 +1221,7 @@ func (x *FieldEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use FieldEvent.ProtoReflect.Descriptor instead. func (*FieldEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{11} + return file_binlogdata_proto_rawDescGZIP(), []int{12} } func (x *FieldEvent) GetTableName() string { @@ -1191,7 +1257,7 @@ type ShardGtid struct { func (x *ShardGtid) Reset() { *x = ShardGtid{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[12] + mi := &file_binlogdata_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1204,7 +1270,7 @@ func (x *ShardGtid) String() string { func (*ShardGtid) ProtoMessage() {} func (x *ShardGtid) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[12] + mi := &file_binlogdata_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1217,7 +1283,7 @@ func (x *ShardGtid) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardGtid.ProtoReflect.Descriptor instead. func (*ShardGtid) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{12} + return file_binlogdata_proto_rawDescGZIP(), []int{13} } func (x *ShardGtid) GetKeyspace() string { @@ -1260,7 +1326,7 @@ type VGtid struct { func (x *VGtid) Reset() { *x = VGtid{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[13] + mi := &file_binlogdata_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1273,7 +1339,7 @@ func (x *VGtid) String() string { func (*VGtid) ProtoMessage() {} func (x *VGtid) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[13] + mi := &file_binlogdata_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1286,7 +1352,7 @@ func (x *VGtid) ProtoReflect() protoreflect.Message { // Deprecated: Use VGtid.ProtoReflect.Descriptor instead. func (*VGtid) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{13} + return file_binlogdata_proto_rawDescGZIP(), []int{14} } func (x *VGtid) GetShardGtids() []*ShardGtid { @@ -1309,7 +1375,7 @@ type KeyspaceShard struct { func (x *KeyspaceShard) Reset() { *x = KeyspaceShard{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[14] + mi := &file_binlogdata_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1322,7 +1388,7 @@ func (x *KeyspaceShard) String() string { func (*KeyspaceShard) ProtoMessage() {} func (x *KeyspaceShard) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[14] + mi := &file_binlogdata_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1335,7 +1401,7 @@ func (x *KeyspaceShard) ProtoReflect() protoreflect.Message { // Deprecated: Use KeyspaceShard.ProtoReflect.Descriptor instead. func (*KeyspaceShard) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{14} + return file_binlogdata_proto_rawDescGZIP(), []int{15} } func (x *KeyspaceShard) GetKeyspace() string { @@ -1387,7 +1453,7 @@ type Journal struct { func (x *Journal) Reset() { *x = Journal{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[15] + mi := &file_binlogdata_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1400,7 +1466,7 @@ func (x *Journal) String() string { func (*Journal) ProtoMessage() {} func (x *Journal) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[15] + mi := &file_binlogdata_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1413,7 +1479,7 @@ func (x *Journal) ProtoReflect() protoreflect.Message { // Deprecated: Use Journal.ProtoReflect.Descriptor instead. func (*Journal) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{15} + return file_binlogdata_proto_rawDescGZIP(), []int{16} } func (x *Journal) GetId() int64 { @@ -1507,7 +1573,7 @@ type VEvent struct { func (x *VEvent) Reset() { *x = VEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[16] + mi := &file_binlogdata_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1520,7 +1586,7 @@ func (x *VEvent) String() string { func (*VEvent) ProtoMessage() {} func (x *VEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[16] + mi := &file_binlogdata_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1533,7 +1599,7 @@ func (x *VEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use VEvent.ProtoReflect.Descriptor instead. func (*VEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{16} + return file_binlogdata_proto_rawDescGZIP(), []int{17} } func (x *VEvent) GetType() VEventType { @@ -1626,7 +1692,7 @@ type MinimalTable struct { func (x *MinimalTable) Reset() { *x = MinimalTable{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[17] + mi := &file_binlogdata_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1639,7 +1705,7 @@ func (x *MinimalTable) String() string { func (*MinimalTable) ProtoMessage() {} func (x *MinimalTable) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[17] + mi := &file_binlogdata_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1652,7 +1718,7 @@ func (x *MinimalTable) ProtoReflect() protoreflect.Message { // Deprecated: Use MinimalTable.ProtoReflect.Descriptor instead. func (*MinimalTable) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{17} + return file_binlogdata_proto_rawDescGZIP(), []int{18} } func (x *MinimalTable) GetName() string { @@ -1687,7 +1753,7 @@ type MinimalSchema struct { func (x *MinimalSchema) Reset() { *x = MinimalSchema{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[18] + mi := &file_binlogdata_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1700,7 +1766,7 @@ func (x *MinimalSchema) String() string { func (*MinimalSchema) ProtoMessage() {} func (x *MinimalSchema) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[18] + mi := &file_binlogdata_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1713,7 +1779,7 @@ func (x *MinimalSchema) ProtoReflect() protoreflect.Message { // Deprecated: Use MinimalSchema.ProtoReflect.Descriptor instead. func (*MinimalSchema) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{18} + return file_binlogdata_proto_rawDescGZIP(), []int{19} } func (x *MinimalSchema) GetTables() []*MinimalTable { @@ -1740,7 +1806,7 @@ type VStreamRequest struct { func (x *VStreamRequest) Reset() { *x = VStreamRequest{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[19] + mi := &file_binlogdata_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1753,7 +1819,7 @@ func (x *VStreamRequest) String() string { func (*VStreamRequest) ProtoMessage() {} func (x *VStreamRequest) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[19] + mi := &file_binlogdata_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1766,7 +1832,7 @@ func (x *VStreamRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamRequest.ProtoReflect.Descriptor instead. func (*VStreamRequest) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{19} + return file_binlogdata_proto_rawDescGZIP(), []int{20} } func (x *VStreamRequest) GetEffectiveCallerId() *vtrpc.CallerID { @@ -1823,7 +1889,7 @@ type VStreamResponse struct { func (x *VStreamResponse) Reset() { *x = VStreamResponse{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[20] + mi := &file_binlogdata_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1836,7 +1902,7 @@ func (x *VStreamResponse) String() string { func (*VStreamResponse) ProtoMessage() {} func (x *VStreamResponse) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[20] + mi := &file_binlogdata_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1849,7 +1915,7 @@ func (x *VStreamResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamResponse.ProtoReflect.Descriptor instead. func (*VStreamResponse) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{20} + return file_binlogdata_proto_rawDescGZIP(), []int{21} } func (x *VStreamResponse) GetEvents() []*VEvent { @@ -1875,7 +1941,7 @@ type VStreamRowsRequest struct { func (x *VStreamRowsRequest) Reset() { *x = VStreamRowsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[21] + mi := &file_binlogdata_proto_msgTypes[22] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1888,7 +1954,7 @@ func (x *VStreamRowsRequest) String() string { func (*VStreamRowsRequest) ProtoMessage() {} func (x *VStreamRowsRequest) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[21] + mi := &file_binlogdata_proto_msgTypes[22] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1901,7 +1967,7 @@ func (x *VStreamRowsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamRowsRequest.ProtoReflect.Descriptor instead. func (*VStreamRowsRequest) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{21} + return file_binlogdata_proto_rawDescGZIP(), []int{22} } func (x *VStreamRowsRequest) GetEffectiveCallerId() *vtrpc.CallerID { @@ -1955,7 +2021,7 @@ type VStreamRowsResponse struct { func (x *VStreamRowsResponse) Reset() { *x = VStreamRowsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[22] + mi := &file_binlogdata_proto_msgTypes[23] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1968,7 +2034,7 @@ func (x *VStreamRowsResponse) String() string { func (*VStreamRowsResponse) ProtoMessage() {} func (x *VStreamRowsResponse) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[22] + mi := &file_binlogdata_proto_msgTypes[23] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1981,7 +2047,7 @@ func (x *VStreamRowsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamRowsResponse.ProtoReflect.Descriptor instead. func (*VStreamRowsResponse) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{22} + return file_binlogdata_proto_rawDescGZIP(), []int{23} } func (x *VStreamRowsResponse) GetFields() []*query.Field { @@ -2031,7 +2097,7 @@ type LastPKEvent struct { func (x *LastPKEvent) Reset() { *x = LastPKEvent{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[23] + mi := &file_binlogdata_proto_msgTypes[24] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2044,7 +2110,7 @@ func (x *LastPKEvent) String() string { func (*LastPKEvent) ProtoMessage() {} func (x *LastPKEvent) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[23] + mi := &file_binlogdata_proto_msgTypes[24] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2057,7 +2123,7 @@ func (x *LastPKEvent) ProtoReflect() protoreflect.Message { // Deprecated: Use LastPKEvent.ProtoReflect.Descriptor instead. func (*LastPKEvent) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{23} + return file_binlogdata_proto_rawDescGZIP(), []int{24} } func (x *LastPKEvent) GetTableLastPK() *TableLastPK { @@ -2086,7 +2152,7 @@ type TableLastPK struct { func (x *TableLastPK) Reset() { *x = TableLastPK{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[24] + mi := &file_binlogdata_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2099,7 +2165,7 @@ func (x *TableLastPK) String() string { func (*TableLastPK) ProtoMessage() {} func (x *TableLastPK) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[24] + mi := &file_binlogdata_proto_msgTypes[25] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2112,7 +2178,7 @@ func (x *TableLastPK) ProtoReflect() protoreflect.Message { // Deprecated: Use TableLastPK.ProtoReflect.Descriptor instead. func (*TableLastPK) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{24} + return file_binlogdata_proto_rawDescGZIP(), []int{25} } func (x *TableLastPK) GetTableName() string { @@ -2146,7 +2212,7 @@ type VStreamResultsRequest struct { func (x *VStreamResultsRequest) Reset() { *x = VStreamResultsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[25] + mi := &file_binlogdata_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2159,7 +2225,7 @@ func (x *VStreamResultsRequest) String() string { func (*VStreamResultsRequest) ProtoMessage() {} func (x *VStreamResultsRequest) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[25] + mi := &file_binlogdata_proto_msgTypes[26] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2172,7 +2238,7 @@ func (x *VStreamResultsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamResultsRequest.ProtoReflect.Descriptor instead. func (*VStreamResultsRequest) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{25} + return file_binlogdata_proto_rawDescGZIP(), []int{26} } func (x *VStreamResultsRequest) GetEffectiveCallerId() *vtrpc.CallerID { @@ -2218,7 +2284,7 @@ type VStreamResultsResponse struct { func (x *VStreamResultsResponse) Reset() { *x = VStreamResultsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[26] + mi := &file_binlogdata_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2231,7 +2297,7 @@ func (x *VStreamResultsResponse) String() string { func (*VStreamResultsResponse) ProtoMessage() {} func (x *VStreamResultsResponse) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[26] + mi := &file_binlogdata_proto_msgTypes[27] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2244,7 +2310,7 @@ func (x *VStreamResultsResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use VStreamResultsResponse.ProtoReflect.Descriptor instead. func (*VStreamResultsResponse) Descriptor() ([]byte, []int) { - return file_binlogdata_proto_rawDescGZIP(), []int{26} + return file_binlogdata_proto_rawDescGZIP(), []int{27} } func (x *VStreamResultsResponse) GetFields() []*query.Field { @@ -2284,7 +2350,7 @@ type BinlogTransaction_Statement struct { func (x *BinlogTransaction_Statement) Reset() { *x = BinlogTransaction_Statement{} if protoimpl.UnsafeEnabled { - mi := &file_binlogdata_proto_msgTypes[27] + mi := &file_binlogdata_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2297,7 +2363,7 @@ func (x *BinlogTransaction_Statement) String() string { func (*BinlogTransaction_Statement) ProtoMessage() {} func (x *BinlogTransaction_Statement) ProtoReflect() protoreflect.Message { - mi := &file_binlogdata_proto_msgTypes[27] + mi := &file_binlogdata_proto_msgTypes[28] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2406,252 +2472,268 @@ var file_binlogdata_proto_rawDesc = []byte{ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x34, 0x0a, - 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x22, 0xb3, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, - 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, - 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, - 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, - 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, - 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, - 0x64, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, - 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, - 0x70, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, - 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x22, 0x51, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, - 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, - 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, - 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, - 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, - 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, - 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, - 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, - 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, - 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, - 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, - 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, - 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, - 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, - 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, - 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, - 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, - 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, - 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, - 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, - 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, - 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, - 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, - 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, - 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, - 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, - 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, - 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, - 0x0a, 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, - 0x0a, 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, - 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, - 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, - 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, - 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, - 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, - 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, - 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, + 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x55, 0x0a, + 0x11, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x72, 0x6f, 0x6d, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x73, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x5f, 0x63, 0x68, 0x61, 0x72, + 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x6f, 0x43, 0x68, 0x61, + 0x72, 0x73, 0x65, 0x74, 0x22, 0xe5, 0x01, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0f, 0x63, + 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x43, 0x68, + 0x61, 0x72, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x1a, 0x60, 0x0a, 0x13, 0x43, 0x6f, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x43, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, 0x01, 0x0a, + 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, + 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, + 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, + 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x09, + 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, + 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, + 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x79, + 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, + 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, + 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x09, 0x52, + 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, + 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, + 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, - 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, - 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, - 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, - 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, - 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, - 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, - 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, - 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, - 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, - 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, - 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, - 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, - 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, - 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, - 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, - 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, - 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, - 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, - 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, - 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, - 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, - 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, - 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, - 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, - 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, - 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, - 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, - 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, - 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, - 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, + 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, + 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, + 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, 0x22, + 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, + 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, 0x77, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, 0x2d, + 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, 0x75, + 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, 0x0a, + 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, 0x12, + 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, + 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, + 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4d, 0x69, + 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0xc7, 0x02, + 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, + 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, + 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, + 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, + 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, 0x0a, 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, + 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xbd, + 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, + 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, + 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, + 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, + 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, + 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, + 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, + 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, + 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, + 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, + 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, + 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, + 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, + 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, + 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, + 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, + 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, + 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, + 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, + 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, + 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, + 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, + 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, + 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, + 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, + 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, + 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, + 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, + 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, + 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, + 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, + 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, + 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, + 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2667,7 +2749,7 @@ func file_binlogdata_proto_rawDescGZIP() []byte { } var file_binlogdata_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_binlogdata_proto_msgTypes = make([]protoimpl.MessageInfo, 28) +var file_binlogdata_proto_msgTypes = make([]protoimpl.MessageInfo, 30) var file_binlogdata_proto_goTypes = []interface{}{ (OnDDLAction)(0), // 0: binlogdata.OnDDLAction (VEventType)(0), // 1: binlogdata.VEventType @@ -2680,97 +2762,101 @@ var file_binlogdata_proto_goTypes = []interface{}{ (*StreamKeyRangeResponse)(nil), // 8: binlogdata.StreamKeyRangeResponse (*StreamTablesRequest)(nil), // 9: binlogdata.StreamTablesRequest (*StreamTablesResponse)(nil), // 10: binlogdata.StreamTablesResponse - (*Rule)(nil), // 11: binlogdata.Rule - (*Filter)(nil), // 12: binlogdata.Filter - (*BinlogSource)(nil), // 13: binlogdata.BinlogSource - (*RowChange)(nil), // 14: binlogdata.RowChange - (*RowEvent)(nil), // 15: binlogdata.RowEvent - (*FieldEvent)(nil), // 16: binlogdata.FieldEvent - (*ShardGtid)(nil), // 17: binlogdata.ShardGtid - (*VGtid)(nil), // 18: binlogdata.VGtid - (*KeyspaceShard)(nil), // 19: binlogdata.KeyspaceShard - (*Journal)(nil), // 20: binlogdata.Journal - (*VEvent)(nil), // 21: binlogdata.VEvent - (*MinimalTable)(nil), // 22: binlogdata.MinimalTable - (*MinimalSchema)(nil), // 23: binlogdata.MinimalSchema - (*VStreamRequest)(nil), // 24: binlogdata.VStreamRequest - (*VStreamResponse)(nil), // 25: binlogdata.VStreamResponse - (*VStreamRowsRequest)(nil), // 26: binlogdata.VStreamRowsRequest - (*VStreamRowsResponse)(nil), // 27: binlogdata.VStreamRowsResponse - (*LastPKEvent)(nil), // 28: binlogdata.LastPKEvent - (*TableLastPK)(nil), // 29: binlogdata.TableLastPK - (*VStreamResultsRequest)(nil), // 30: binlogdata.VStreamResultsRequest - (*VStreamResultsResponse)(nil), // 31: binlogdata.VStreamResultsResponse - (*BinlogTransaction_Statement)(nil), // 32: binlogdata.BinlogTransaction.Statement - (*query.EventToken)(nil), // 33: query.EventToken - (*topodata.KeyRange)(nil), // 34: topodata.KeyRange - (topodata.TabletType)(0), // 35: topodata.TabletType - (*query.Row)(nil), // 36: query.Row - (*query.Field)(nil), // 37: query.Field - (*vtrpc.CallerID)(nil), // 38: vtrpc.CallerID - (*query.VTGateCallerID)(nil), // 39: query.VTGateCallerID - (*query.Target)(nil), // 40: query.Target - (*query.QueryResult)(nil), // 41: query.QueryResult + (*CharsetConversion)(nil), // 11: binlogdata.CharsetConversion + (*Rule)(nil), // 12: binlogdata.Rule + (*Filter)(nil), // 13: binlogdata.Filter + (*BinlogSource)(nil), // 14: binlogdata.BinlogSource + (*RowChange)(nil), // 15: binlogdata.RowChange + (*RowEvent)(nil), // 16: binlogdata.RowEvent + (*FieldEvent)(nil), // 17: binlogdata.FieldEvent + (*ShardGtid)(nil), // 18: binlogdata.ShardGtid + (*VGtid)(nil), // 19: binlogdata.VGtid + (*KeyspaceShard)(nil), // 20: binlogdata.KeyspaceShard + (*Journal)(nil), // 21: binlogdata.Journal + (*VEvent)(nil), // 22: binlogdata.VEvent + (*MinimalTable)(nil), // 23: binlogdata.MinimalTable + (*MinimalSchema)(nil), // 24: binlogdata.MinimalSchema + (*VStreamRequest)(nil), // 25: binlogdata.VStreamRequest + (*VStreamResponse)(nil), // 26: binlogdata.VStreamResponse + (*VStreamRowsRequest)(nil), // 27: binlogdata.VStreamRowsRequest + (*VStreamRowsResponse)(nil), // 28: binlogdata.VStreamRowsResponse + (*LastPKEvent)(nil), // 29: binlogdata.LastPKEvent + (*TableLastPK)(nil), // 30: binlogdata.TableLastPK + (*VStreamResultsRequest)(nil), // 31: binlogdata.VStreamResultsRequest + (*VStreamResultsResponse)(nil), // 32: binlogdata.VStreamResultsResponse + (*BinlogTransaction_Statement)(nil), // 33: binlogdata.BinlogTransaction.Statement + nil, // 34: binlogdata.Rule.ConvertCharsetEntry + (*query.EventToken)(nil), // 35: query.EventToken + (*topodata.KeyRange)(nil), // 36: topodata.KeyRange + (topodata.TabletType)(0), // 37: topodata.TabletType + (*query.Row)(nil), // 38: query.Row + (*query.Field)(nil), // 39: query.Field + (*vtrpc.CallerID)(nil), // 40: vtrpc.CallerID + (*query.VTGateCallerID)(nil), // 41: query.VTGateCallerID + (*query.Target)(nil), // 42: query.Target + (*query.QueryResult)(nil), // 43: query.QueryResult } var file_binlogdata_proto_depIdxs = []int32{ - 32, // 0: binlogdata.BinlogTransaction.statements:type_name -> binlogdata.BinlogTransaction.Statement - 33, // 1: binlogdata.BinlogTransaction.event_token:type_name -> query.EventToken - 34, // 2: binlogdata.StreamKeyRangeRequest.key_range:type_name -> topodata.KeyRange + 33, // 0: binlogdata.BinlogTransaction.statements:type_name -> binlogdata.BinlogTransaction.Statement + 35, // 1: binlogdata.BinlogTransaction.event_token:type_name -> query.EventToken + 36, // 2: binlogdata.StreamKeyRangeRequest.key_range:type_name -> topodata.KeyRange 5, // 3: binlogdata.StreamKeyRangeRequest.charset:type_name -> binlogdata.Charset 6, // 4: binlogdata.StreamKeyRangeResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction 5, // 5: binlogdata.StreamTablesRequest.charset:type_name -> binlogdata.Charset 6, // 6: binlogdata.StreamTablesResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction - 11, // 7: binlogdata.Filter.rules:type_name -> binlogdata.Rule - 4, // 8: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode - 35, // 9: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType - 34, // 10: binlogdata.BinlogSource.key_range:type_name -> topodata.KeyRange - 12, // 11: binlogdata.BinlogSource.filter:type_name -> binlogdata.Filter - 0, // 12: binlogdata.BinlogSource.on_ddl:type_name -> binlogdata.OnDDLAction - 36, // 13: binlogdata.RowChange.before:type_name -> query.Row - 36, // 14: binlogdata.RowChange.after:type_name -> query.Row - 14, // 15: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange - 37, // 16: binlogdata.FieldEvent.fields:type_name -> query.Field - 29, // 17: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK - 17, // 18: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid - 2, // 19: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType - 17, // 20: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid - 19, // 21: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard - 1, // 22: binlogdata.VEvent.type:type_name -> binlogdata.VEventType - 15, // 23: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent - 16, // 24: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent - 18, // 25: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid - 20, // 26: binlogdata.VEvent.journal:type_name -> binlogdata.Journal - 28, // 27: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent - 37, // 28: binlogdata.MinimalTable.fields:type_name -> query.Field - 22, // 29: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable - 38, // 30: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 31: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 32: binlogdata.VStreamRequest.target:type_name -> query.Target - 12, // 33: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter - 29, // 34: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK - 21, // 35: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent - 38, // 36: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 37: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 38: binlogdata.VStreamRowsRequest.target:type_name -> query.Target - 41, // 39: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult - 37, // 40: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field - 37, // 41: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field - 36, // 42: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row - 36, // 43: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row - 29, // 44: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK - 41, // 45: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult - 38, // 46: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID - 39, // 47: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID - 40, // 48: binlogdata.VStreamResultsRequest.target:type_name -> query.Target - 37, // 49: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field - 36, // 50: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row - 3, // 51: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category - 5, // 52: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset - 53, // [53:53] is the sub-list for method output_type - 53, // [53:53] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 34, // 7: binlogdata.Rule.convert_charset:type_name -> binlogdata.Rule.ConvertCharsetEntry + 12, // 8: binlogdata.Filter.rules:type_name -> binlogdata.Rule + 4, // 9: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode + 37, // 10: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType + 36, // 11: binlogdata.BinlogSource.key_range:type_name -> topodata.KeyRange + 13, // 12: binlogdata.BinlogSource.filter:type_name -> binlogdata.Filter + 0, // 13: binlogdata.BinlogSource.on_ddl:type_name -> binlogdata.OnDDLAction + 38, // 14: binlogdata.RowChange.before:type_name -> query.Row + 38, // 15: binlogdata.RowChange.after:type_name -> query.Row + 15, // 16: binlogdata.RowEvent.row_changes:type_name -> binlogdata.RowChange + 39, // 17: binlogdata.FieldEvent.fields:type_name -> query.Field + 30, // 18: binlogdata.ShardGtid.table_p_ks:type_name -> binlogdata.TableLastPK + 18, // 19: binlogdata.VGtid.shard_gtids:type_name -> binlogdata.ShardGtid + 2, // 20: binlogdata.Journal.migration_type:type_name -> binlogdata.MigrationType + 18, // 21: binlogdata.Journal.shard_gtids:type_name -> binlogdata.ShardGtid + 20, // 22: binlogdata.Journal.participants:type_name -> binlogdata.KeyspaceShard + 1, // 23: binlogdata.VEvent.type:type_name -> binlogdata.VEventType + 16, // 24: binlogdata.VEvent.row_event:type_name -> binlogdata.RowEvent + 17, // 25: binlogdata.VEvent.field_event:type_name -> binlogdata.FieldEvent + 19, // 26: binlogdata.VEvent.vgtid:type_name -> binlogdata.VGtid + 21, // 27: binlogdata.VEvent.journal:type_name -> binlogdata.Journal + 29, // 28: binlogdata.VEvent.last_p_k_event:type_name -> binlogdata.LastPKEvent + 39, // 29: binlogdata.MinimalTable.fields:type_name -> query.Field + 23, // 30: binlogdata.MinimalSchema.tables:type_name -> binlogdata.MinimalTable + 40, // 31: binlogdata.VStreamRequest.effective_caller_id:type_name -> vtrpc.CallerID + 41, // 32: binlogdata.VStreamRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 42, // 33: binlogdata.VStreamRequest.target:type_name -> query.Target + 13, // 34: binlogdata.VStreamRequest.filter:type_name -> binlogdata.Filter + 30, // 35: binlogdata.VStreamRequest.table_last_p_ks:type_name -> binlogdata.TableLastPK + 22, // 36: binlogdata.VStreamResponse.events:type_name -> binlogdata.VEvent + 40, // 37: binlogdata.VStreamRowsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 41, // 38: binlogdata.VStreamRowsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 42, // 39: binlogdata.VStreamRowsRequest.target:type_name -> query.Target + 43, // 40: binlogdata.VStreamRowsRequest.lastpk:type_name -> query.QueryResult + 39, // 41: binlogdata.VStreamRowsResponse.fields:type_name -> query.Field + 39, // 42: binlogdata.VStreamRowsResponse.pkfields:type_name -> query.Field + 38, // 43: binlogdata.VStreamRowsResponse.rows:type_name -> query.Row + 38, // 44: binlogdata.VStreamRowsResponse.lastpk:type_name -> query.Row + 30, // 45: binlogdata.LastPKEvent.table_last_p_k:type_name -> binlogdata.TableLastPK + 43, // 46: binlogdata.TableLastPK.lastpk:type_name -> query.QueryResult + 40, // 47: binlogdata.VStreamResultsRequest.effective_caller_id:type_name -> vtrpc.CallerID + 41, // 48: binlogdata.VStreamResultsRequest.immediate_caller_id:type_name -> query.VTGateCallerID + 42, // 49: binlogdata.VStreamResultsRequest.target:type_name -> query.Target + 39, // 50: binlogdata.VStreamResultsResponse.fields:type_name -> query.Field + 38, // 51: binlogdata.VStreamResultsResponse.rows:type_name -> query.Row + 3, // 52: binlogdata.BinlogTransaction.Statement.category:type_name -> binlogdata.BinlogTransaction.Statement.Category + 5, // 53: binlogdata.BinlogTransaction.Statement.charset:type_name -> binlogdata.Charset + 11, // 54: binlogdata.Rule.ConvertCharsetEntry.value:type_name -> binlogdata.CharsetConversion + 55, // [55:55] is the sub-list for method output_type + 55, // [55:55] is the sub-list for method input_type + 55, // [55:55] is the sub-list for extension type_name + 55, // [55:55] is the sub-list for extension extendee + 0, // [0:55] is the sub-list for field type_name } func init() { file_binlogdata_proto_init() } @@ -2852,7 +2938,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Rule); i { + switch v := v.(*CharsetConversion); i { case 0: return &v.state case 1: @@ -2864,7 +2950,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Filter); i { + switch v := v.(*Rule); i { case 0: return &v.state case 1: @@ -2876,7 +2962,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BinlogSource); i { + switch v := v.(*Filter); i { case 0: return &v.state case 1: @@ -2888,7 +2974,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RowChange); i { + switch v := v.(*BinlogSource); i { case 0: return &v.state case 1: @@ -2900,7 +2986,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RowEvent); i { + switch v := v.(*RowChange); i { case 0: return &v.state case 1: @@ -2912,7 +2998,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FieldEvent); i { + switch v := v.(*RowEvent); i { case 0: return &v.state case 1: @@ -2924,7 +3010,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShardGtid); i { + switch v := v.(*FieldEvent); i { case 0: return &v.state case 1: @@ -2936,7 +3022,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VGtid); i { + switch v := v.(*ShardGtid); i { case 0: return &v.state case 1: @@ -2948,7 +3034,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyspaceShard); i { + switch v := v.(*VGtid); i { case 0: return &v.state case 1: @@ -2960,7 +3046,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Journal); i { + switch v := v.(*KeyspaceShard); i { case 0: return &v.state case 1: @@ -2972,7 +3058,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VEvent); i { + switch v := v.(*Journal); i { case 0: return &v.state case 1: @@ -2984,7 +3070,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MinimalTable); i { + switch v := v.(*VEvent); i { case 0: return &v.state case 1: @@ -2996,7 +3082,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MinimalSchema); i { + switch v := v.(*MinimalTable); i { case 0: return &v.state case 1: @@ -3008,7 +3094,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamRequest); i { + switch v := v.(*MinimalSchema); i { case 0: return &v.state case 1: @@ -3020,7 +3106,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamResponse); i { + switch v := v.(*VStreamRequest); i { case 0: return &v.state case 1: @@ -3032,7 +3118,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamRowsRequest); i { + switch v := v.(*VStreamResponse); i { case 0: return &v.state case 1: @@ -3044,7 +3130,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamRowsResponse); i { + switch v := v.(*VStreamRowsRequest); i { case 0: return &v.state case 1: @@ -3056,7 +3142,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LastPKEvent); i { + switch v := v.(*VStreamRowsResponse); i { case 0: return &v.state case 1: @@ -3068,7 +3154,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TableLastPK); i { + switch v := v.(*LastPKEvent); i { case 0: return &v.state case 1: @@ -3080,7 +3166,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamResultsRequest); i { + switch v := v.(*TableLastPK); i { case 0: return &v.state case 1: @@ -3092,7 +3178,7 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VStreamResultsResponse); i { + switch v := v.(*VStreamResultsRequest); i { case 0: return &v.state case 1: @@ -3104,6 +3190,18 @@ func file_binlogdata_proto_init() { } } file_binlogdata_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VStreamResultsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_binlogdata_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BinlogTransaction_Statement); i { case 0: return &v.state @@ -3122,7 +3220,7 @@ func file_binlogdata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_binlogdata_proto_rawDesc, NumEnums: 5, - NumMessages: 28, + NumMessages: 30, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go index 194ce30aaf9..acf8fd4269a 100644 --- a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go +++ b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go @@ -401,6 +401,53 @@ func (m *StreamTablesResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *CharsetConversion) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CharsetConversion) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *CharsetConversion) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.ToCharset) > 0 { + i -= len(m.ToCharset) + copy(dAtA[i:], m.ToCharset) + i = encodeVarint(dAtA, i, uint64(len(m.ToCharset))) + i-- + dAtA[i] = 0x12 + } + if len(m.FromCharset) > 0 { + i -= len(m.FromCharset) + copy(dAtA[i:], m.FromCharset) + i = encodeVarint(dAtA, i, uint64(len(m.FromCharset))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + func (m *Rule) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -431,6 +478,30 @@ func (m *Rule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.ConvertCharset) > 0 { + for k := range m.ConvertCharset { + v := m.ConvertCharset[k] + baseI := i + { + size, err := v.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = encodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = encodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } if len(m.Filter) > 0 { i -= len(m.Filter) copy(dAtA[i:], m.Filter) @@ -2062,6 +2133,26 @@ func (m *StreamTablesResponse) SizeVT() (n int) { return n } +func (m *CharsetConversion) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.FromCharset) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.ToCharset) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + func (m *Rule) SizeVT() (n int) { if m == nil { return 0 @@ -2076,6 +2167,19 @@ func (m *Rule) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + if len(m.ConvertCharset) > 0 { + for k, v := range m.ConvertCharset { + _ = k + _ = v + l = 0 + if v != nil { + l = v.SizeVT() + } + l += 1 + sov(uint64(l)) + mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + l + n += mapEntrySize + 1 + sov(uint64(mapEntrySize)) + } + } if m.unknownFields != nil { n += len(m.unknownFields) } @@ -3508,6 +3612,121 @@ func (m *StreamTablesResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *CharsetConversion) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CharsetConversion: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CharsetConversion: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromCharset", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromCharset = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ToCharset", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ToCharset = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Rule) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -3601,6 +3820,135 @@ func (m *Rule) UnmarshalVT(dAtA []byte) error { } m.Filter = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConvertCharset", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ConvertCharset == nil { + m.ConvertCharset = make(map[string]*CharsetConversion) + } + var mapkey string + var mapvalue *CharsetConversion + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return ErrInvalidLength + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &CharsetConversion{} + if err := mapvalue.UnmarshalVT(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.ConvertCharset[mapkey] = mapvalue + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index ecbf42aec96..7cefafbf4ea 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -30,6 +30,7 @@ import ( "strconv" "strings" + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/dbconnpool" @@ -76,19 +77,22 @@ type VRepl struct { bls *binlogdatapb.BinlogSource parser *vrepl.AlterTableParser + + convertCharset map[string](*binlogdatapb.CharsetConversion) } // NewVRepl creates a VReplication handler for Online DDL func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alterOptions string) *VRepl { return &VRepl{ - workflow: workflow, - keyspace: keyspace, - shard: shard, - dbName: dbName, - sourceTable: sourceTable, - targetTable: targetTable, - alterOptions: alterOptions, - parser: vrepl.NewAlterTableParser(), + workflow: workflow, + keyspace: keyspace, + shard: shard, + dbName: dbName, + sourceTable: sourceTable, + targetTable: targetTable, + alterOptions: alterOptions, + parser: vrepl.NewAlterTableParser(), + convertCharset: map[string](*binlogdatapb.CharsetConversion){}, } } @@ -384,14 +388,14 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } var sb strings.Builder sb.WriteString("select ") - for i, col := range v.sourceSharedColumns.Columns() { - name := col.Name + for i, sourceCol := range v.sourceSharedColumns.Columns() { + name := sourceCol.Name targetName := v.sharedColumnsMap[name] if i > 0 { sb.WriteString(", ") } - switch col.Type { + switch sourceCol.Type { case vrepl.JSONColumnType: sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) case vrepl.StringColumnType: @@ -399,15 +403,52 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { if targetCol == nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) } - if col.Collation != targetCol.Collation { - fmt.Printf("============ collcation change: %s => %s\n", col.Collation, targetCol.Collation) - if strings.HasPrefix(targetCol.Charset, "utf8") { + if true || sourceCol.Collation != targetCol.Collation { + // sourceEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] + // if !ok { + // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) + // } + fromEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] + if !ok { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) + } + toEncoding, ok := mysql.CharacterSetEncoding[targetCol.Charset] + if !ok { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", targetCol.Charset, targetCol.Name) + } + if fromEncoding != nil || toEncoding != nil { + // encoding can be nil for trivial charsets, like utf8, ascii, binary, etc. + v.convertCharset[targetName] = &binlogdatapb.CharsetConversion{ + FromCharset: sourceCol.Charset, + ToCharset: targetCol.Charset, + } + fmt.Printf("============ v.convertCharset[targetName]: %v, %v\n", targetName, v.convertCharset[targetName]) + } + fmt.Printf("============ collcation change: %s => %s\n", sourceCol.Collation, targetCol.Collation) + if strings.HasPrefix(sourceCol.Charset, "utf8") { + // sb.WriteString(escapeName(name)) + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) + } else { // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - } else { - sb.WriteString(fmt.Sprintf("convert(%s, char character set %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) } + // if strings.HasPrefix(targetCol.Charset, "utf8") { + // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) + // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // } else if strings.HasPrefix(sourceCol.Charset, "utf8") { + // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // } else { + // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) + // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) + // } } else { sb.WriteString(escapeName(name)) } @@ -435,6 +476,9 @@ func (v *VRepl) analyzeBinlogSource(ctx context.Context) { Match: v.targetTable, Filter: v.filterQuery, } + if len(v.convertCharset) > 0 { + rule.ConvertCharset = v.convertCharset + } bls.Filter.Rules = append(bls.Filter.Rules, rule) v.bls = bls } diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 9558533decd..92352495f47 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -25,15 +25,15 @@ import ( "google.golang.org/protobuf/proto" "vitess.io/vitess/go/bytes2" - - "vitess.io/vitess/go/vt/binlog/binlogplayer" - "vitess.io/vitess/go/vt/vtgate/evalengine" - + "vitess.io/vitess/go/mysql" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/sqlparser" - + "vitess.io/vitess/go/vt/binlog/binlogplayer" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" querypb "vitess.io/vitess/go/vt/proto/query" + 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/evalengine" ) // ReplicatorPlan is the execution plan for the replicator. It contains @@ -194,9 +194,10 @@ type TablePlan struct { Fields []*querypb.Field // PKReferences is used to check if an event changed // a primary key column (row move). - PKReferences []string - Stats *binlogplayer.Stats - FieldsToSkip map[string]bool + PKReferences []string + Stats *binlogplayer.Stats + FieldsToSkip map[string]bool + ConvertCharset map[string](*binlogdatapb.CharsetConversion) } // MarshalJSON performs a custom JSON Marshalling. @@ -303,7 +304,47 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun after = true vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + bindVal := func() (err error) { + if conversion, ok := tp.ConvertCharset[field.Name]; ok { + valString := vals[i].ToString() + fmt.Printf("=========== ConvertCharset[field.Name]: %v, %v \n", field.Name, conversion) + fmt.Printf("=========== s0: %v \n", valString) + + fromEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.FromCharset] + if !encodingOK { + return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.FromCharset, field.Name) + } + if fromEncoding != nil { + fmt.Printf("=========== ConvertCharset fromEncoding: %v, %v \n", field.Name, fromEncoding) + valString, err = fromEncoding.NewDecoder().String(valString) + if err != nil { + return err + } + fmt.Printf("=========== s1: %v \n", valString) + } + + // // There is a request to encode given charset + // toEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.ToCharset] + // if !encodingOK { + // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.ToCharset, field.Name) + // } + // if toEncoding != nil { + // fmt.Printf("=========== ConvertCharset toEncoding: %v, %v \n", field.Name, toEncoding) + // valString, err = toEncoding.NewEncoder().String(valString) + // if err != nil { + // return err + // } + // fmt.Printf("=========== s2: %v \n", valString) + // } + bindvars["a_"+field.Name] = sqltypes.StringBindVariable(valString) + return nil + } + bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + return nil + } + if err := bindVal(); err != nil { + return nil, err + } } } switch { diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 3108c4a0a2a..529d1028ac5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -144,7 +144,7 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, colInfoMap map[string][]*C if rule == nil { continue } - tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, stats) + tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, rule.ConvertCharset, stats) if err != nil { return nil, err } @@ -183,7 +183,7 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru return nil, nil } -func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, stats *binlogplayer.Stats) (*TablePlan, error) { +func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, convertCharset map[string](*binlogdatapb.CharsetConversion), stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. fmt.Printf("============ filter: %v\n", filter) @@ -218,10 +218,11 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf } sendRule.Filter = query tablePlan := &TablePlan{ - TargetName: tableName, - SendRule: sendRule, - Lastpk: lastpk, - Stats: stats, + TargetName: tableName, + SendRule: sendRule, + Lastpk: lastpk, + Stats: stats, + ConvertCharset: convertCharset, } return tablePlan, nil } @@ -278,6 +279,7 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf tablePlan := tpb.generate() tablePlan.SendRule = sendRule + tablePlan.ConvertCharset = convertCharset return tablePlan, nil } @@ -382,7 +384,7 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr if expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok { fmt.Printf("============ ConvertUsingExpr: %v\n", sqlparser.String(expr)) selExpr := &sqlparser.ConvertUsingExpr{ - Type: "binary", + Type: "utf8mb4", Expr: &sqlparser.ColName{Name: as}, } fmt.Printf("============ ConvertUsingExpr generated: %v\n", sqlparser.String(selExpr)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index f7be38644e2..e934fb51ac6 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -174,7 +174,7 @@ func (rs *rowStreamer) buildSelect() (string, error) { if rs.plan.convertToBinary[col.Name] { // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) - buf.Myprintf("%sconvert(%v using utf8)", prefix, sqlparser.NewColIdent(col.Name)) + buf.Myprintf("%sconvert(%v using utf8mb4)", prefix, sqlparser.NewColIdent(col.Name)) // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } else { buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) From abd0f269bae8900cdd8d8b324e170ec80b692b70 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:35:45 +0300 Subject: [PATCH 248/310] testdata path Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vrepl_suite/onlineddl_vrepl_suite_test.go | 2 +- .../fail-alter-charset-non-utf8/alter | 1 - .../fail-alter-charset-non-utf8/create.sql | 24 ------------------- .../expect_failure | 1 - 4 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure diff --git a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go index 68f71c8d683..d96cfcfff22 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go +++ b/go/test/endtoend/onlineddl/vrepl_suite/onlineddl_vrepl_suite_test.go @@ -60,7 +60,7 @@ var ( ) const ( - testDataPath = "tmptestdata" + testDataPath = "testdata" defaultSQLMode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" ) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter deleted file mode 100644 index b5ec82b1a8b..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/alter +++ /dev/null @@ -1 +0,0 @@ -MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql deleted file mode 100644 index 9db84563248..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/create.sql +++ /dev/null @@ -1,24 +0,0 @@ -drop table if exists onlineddl_test; -create table onlineddl_test ( - id int auto_increment, - t1 varchar(128) charset latin1 collate latin1_swedish_ci, - t2 varchar(128) charset latin1 collate latin1_swedish_ci, - tutf8 varchar(128) charset utf8, - tutf8mb4 varchar(128) charset utf8mb4, - primary key(id) -) auto_increment=1; - -drop event if exists onlineddl_test; -delimiter ;; -create event onlineddl_test - on schedule every 1 second - starts current_timestamp - ends current_timestamp + interval 60 second - on completion not preserve - enable - do -begin - insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); -end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure deleted file mode 100644 index 925d0d81ded..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/fail-alter-charset-non-utf8/expect_failure +++ /dev/null @@ -1 +0,0 @@ -Vitess does not support charset From 90488dea2466907137a554a9e33238c545d8aafe Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:36:03 +0300 Subject: [PATCH 249/310] proto change Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- proto/binlogdata.proto | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 777affe1766..220ef41c5df 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -115,6 +115,14 @@ message StreamTablesResponse { BinlogTransaction binlog_transaction = 1; } +// CharsetConversion represent a conversion of text from one charset to another +message CharsetConversion { + // FromCharset is the charset name from which we convert the text (e.g. latin1) + string from_charset = 1; + // ToCharset is the charset name to which we convert the text (e.g. utf8mb4) + string to_charset = 2; +} + // Rule represents one rule in a Filter. message Rule { // Match can be a table name or a regular expression. @@ -138,6 +146,8 @@ message Rule { // to be excluded. // TODO(sougou): support this on vstreamer side also. string filter = 2; + + map convert_charset = 3; } // Filter represents a list of ordered rules. The first From 95a3d11e09a2aaceb44778fc832750cd8db17075 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 17:44:22 +0300 Subject: [PATCH 250/310] removed test from untestdata Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../fail-alter-charset-non-utf8/alter | 1 - .../fail-alter-charset-non-utf8/create.sql | 24 ------------------- .../expect_failure | 1 - 3 files changed, 26 deletions(-) delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql delete mode 100644 go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter deleted file mode 100644 index b5ec82b1a8b..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/alter +++ /dev/null @@ -1 +0,0 @@ -MODIFY `t1` varchar(128) CHARACTER SET utf8mb4 NOT NULL, MODIFY `t2` varchar(128) CHARACTER SET latin2 NOT NULL, MODIFY `tutf8` varchar(128) CHARACTER SET latin1 NOT NULL diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql deleted file mode 100644 index 9db84563248..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/create.sql +++ /dev/null @@ -1,24 +0,0 @@ -drop table if exists onlineddl_test; -create table onlineddl_test ( - id int auto_increment, - t1 varchar(128) charset latin1 collate latin1_swedish_ci, - t2 varchar(128) charset latin1 collate latin1_swedish_ci, - tutf8 varchar(128) charset utf8, - tutf8mb4 varchar(128) charset utf8mb4, - primary key(id) -) auto_increment=1; - -drop event if exists onlineddl_test; -delimiter ;; -create event onlineddl_test - on schedule every 1 second - starts current_timestamp - ends current_timestamp + interval 60 second - on completion not preserve - enable - do -begin - insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand())); - insert into onlineddl_test values (null, 'átesting', 'átesting', 'átesting', 'átesting'); - insert into onlineddl_test values (null, 'testátest', 'testátest', 'testátest', '🍻😀'); -end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure b/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure deleted file mode 100644 index 925d0d81ded..00000000000 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/fail-alter-charset-non-utf8/expect_failure +++ /dev/null @@ -1 +0,0 @@ -Vitess does not support charset From e46c122ba17a0d8d56e2cda9bb3072ca64dcc802 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Sun, 13 Jun 2021 18:35:56 +0300 Subject: [PATCH 251/310] don't convert NULL strings Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vttablet/tabletmanager/vreplication/replicator_plan.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 92352495f47..3e9eb11f814 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -304,9 +304,10 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun after = true vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { + val := &vals[i] bindVal := func() (err error) { - if conversion, ok := tp.ConvertCharset[field.Name]; ok { - valString := vals[i].ToString() + if conversion, ok := tp.ConvertCharset[field.Name]; ok && !val.IsNull() { + valString := val.ToString() fmt.Printf("=========== ConvertCharset[field.Name]: %v, %v \n", field.Name, conversion) fmt.Printf("=========== s0: %v \n", valString) @@ -339,7 +340,7 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun bindvars["a_"+field.Name] = sqltypes.StringBindVariable(valString) return nil } - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(*val) return nil } if err := bindVal(); err != nil { From 25ee2a12b91c33ee98c783b479e585d6844c9de5 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Wed, 2 Jun 2021 19:51:49 -0400 Subject: [PATCH 252/310] Promote `vexec.QueryPlan` to an interface The intention here is that, for `vreplication_log` queries, we will want to have different `stream_id` bindvars for each target tablet in the query. Therefore in the next set of changes, we'll provided a second implementation of `QueryPlan` that allows a different query (with different bind vars) to be run on each target. Signed-off-by: Andrew Mason --- go/vt/vtctl/workflow/vexec/query_plan.go | 29 +++++++++++++------ go/vt/vtctl/workflow/vexec/query_plan_test.go | 18 ++++++------ go/vt/vtctl/workflow/vexec/query_planner.go | 16 +++++----- .../workflow/vexec/query_planner_test.go | 13 +++++++-- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/go/vt/vtctl/workflow/vexec/query_plan.go b/go/vt/vtctl/workflow/vexec/query_plan.go index b6e3f0a561f..26cbc515fc6 100644 --- a/go/vt/vtctl/workflow/vexec/query_plan.go +++ b/go/vt/vtctl/workflow/vexec/query_plan.go @@ -31,17 +31,28 @@ import ( querypb "vitess.io/vitess/go/vt/proto/query" ) -// QueryPlan wraps a planned query produced by a QueryPlanner. It is safe to -// execute a QueryPlan repeatedly and in multiple goroutines. -type QueryPlan struct { +// QueryPlan defines the interface to executing a preprared vexec query on one +// or more tablets. Implementations should ensure that it is safe to call the +// various Execute* methods repeatedly and in multiple goroutines. +type QueryPlan interface { + // Execute executes the planned query on a single target. + Execute(ctx context.Context, target *topo.TabletInfo) (*querypb.QueryResult, error) + // ExecuteScatter executes the planned query on the specified targets concurrently, + // returning a mapping of the target tablet to a querypb.QueryResult. + ExecuteScatter(ctx context.Context, targets ...*topo.TabletInfo) (map[*topo.TabletInfo]*querypb.QueryResult, error) +} + +// FixedQueryPlan wraps a planned query produced by a QueryPlanner. It executes +// the same query with the same bind vals, regardless of the target. +type FixedQueryPlan struct { ParsedQuery *sqlparser.ParsedQuery workflow string tmc tmclient.TabletManagerClient } -// Execute executes a QueryPlan on a single target. -func (qp *QueryPlan) Execute(ctx context.Context, target *topo.TabletInfo) (qr *querypb.QueryResult, err error) { +// Execute is part of the QueryPlan interface. +func (qp *FixedQueryPlan) Execute(ctx context.Context, target *topo.TabletInfo) (qr *querypb.QueryResult, err error) { if qp.ParsedQuery == nil { return nil, fmt.Errorf("%w: call PlanQuery on a query planner first", ErrUnpreparedQuery) } @@ -62,10 +73,10 @@ func (qp *QueryPlan) Execute(ctx context.Context, target *topo.TabletInfo) (qr * return qr, nil } -// ExecuteScatter executes a QueryPlan on multiple targets concurrently, -// returning a mapping of target tablet to querypb.QueryResult. Errors from -// individual targets are aggregated into a singular error. -func (qp *QueryPlan) ExecuteScatter(ctx context.Context, targets ...*topo.TabletInfo) (map[*topo.TabletInfo]*querypb.QueryResult, error) { +// ExecuteScatter is part of the QueryPlan interface. For a FixedQueryPlan, the +// exact same query is executed on each target, and errors from individual +// targets are aggregated into a singular error. +func (qp *FixedQueryPlan) ExecuteScatter(ctx context.Context, targets ...*topo.TabletInfo) (map[*topo.TabletInfo]*querypb.QueryResult, error) { if qp.ParsedQuery == nil { // This check is an "optimization" on error handling. We check here, // even though we will check this during the individual Execute calls, diff --git a/go/vt/vtctl/workflow/vexec/query_plan_test.go b/go/vt/vtctl/workflow/vexec/query_plan_test.go index 1bc9868ae9e..2899b9a3107 100644 --- a/go/vt/vtctl/workflow/vexec/query_plan_test.go +++ b/go/vt/vtctl/workflow/vexec/query_plan_test.go @@ -38,7 +38,7 @@ func TestQueryPlanExecute(t *testing.T) { tests := []struct { name string - plan QueryPlan + plan FixedQueryPlan target *topo.TabletInfo expected *querypb.QueryResult shouldErr bool @@ -46,7 +46,7 @@ func TestQueryPlanExecute(t *testing.T) { }{ { name: "success", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: &sqlparser.ParsedQuery{ Query: "SELECT id FROM _vt.vreplication", }, @@ -80,7 +80,7 @@ func TestQueryPlanExecute(t *testing.T) { }, { name: "no rows affected", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: &sqlparser.ParsedQuery{ Query: "SELECT id FROM _vt.vreplication", }, @@ -114,7 +114,7 @@ func TestQueryPlanExecute(t *testing.T) { }, { name: "error", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: &sqlparser.ParsedQuery{ Query: "SELECT id FROM _vt.vreplication", }, @@ -144,7 +144,7 @@ func TestQueryPlanExecute(t *testing.T) { }, { name: "unprepared query", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: nil, }, shouldErr: true, @@ -182,7 +182,7 @@ func TestQueryPlanExecuteScatter(t *testing.T) { tests := []struct { name string - plan QueryPlan + plan FixedQueryPlan targets []*topo.TabletInfo // This is different from our actual return type because guaranteeing // exact pointers in this table-driven style is a bit tough. @@ -192,7 +192,7 @@ func TestQueryPlanExecuteScatter(t *testing.T) { }{ { name: "success", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: &sqlparser.ParsedQuery{ Query: "SELECT id FROM _vt.vreplication", }, @@ -248,7 +248,7 @@ func TestQueryPlanExecuteScatter(t *testing.T) { }, { name: "some targets fail", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: &sqlparser.ParsedQuery{ Query: "SELECT id FROM _vt.vreplication", }, @@ -294,7 +294,7 @@ func TestQueryPlanExecuteScatter(t *testing.T) { }, { name: "unprepared query", - plan: QueryPlan{ + plan: FixedQueryPlan{ ParsedQuery: nil, }, shouldErr: true, diff --git a/go/vt/vtctl/workflow/vexec/query_planner.go b/go/vt/vtctl/workflow/vexec/query_planner.go index e562c7fc806..88dff55e9ae 100644 --- a/go/vt/vtctl/workflow/vexec/query_planner.go +++ b/go/vt/vtctl/workflow/vexec/query_planner.go @@ -62,7 +62,7 @@ type QueryPlanner interface { // PlanQuery constructs and returns a QueryPlan for a given statement. The // resulting QueryPlan is suitable for repeated, concurrent use. - PlanQuery(stmt sqlparser.Statement) (*QueryPlan, error) + PlanQuery(stmt sqlparser.Statement) (QueryPlan, error) // QueryParams returns a struct of column parameters the QueryPlanner uses. // It is used primarily to abstract the adding of default WHERE clauses to // queries by a private function of this package, and may be removed from @@ -116,7 +116,7 @@ func NewVReplicationQueryPlanner(tmc tmclient.TabletManagerClient, workflow stri // // For DELETE queries, USING, PARTITION, ORDER BY, and LIMIT clauses are not // supported. -func (planner *VReplicationQueryPlanner) PlanQuery(stmt sqlparser.Statement) (plan *QueryPlan, err error) { +func (planner *VReplicationQueryPlanner) PlanQuery(stmt sqlparser.Statement) (plan QueryPlan, err error) { switch stmt := stmt.(type) { case *sqlparser.Select: plan, err = planner.planSelect(stmt) @@ -152,7 +152,7 @@ func (planner *VReplicationQueryPlanner) QueryParams() QueryParams { } } -func (planner *VReplicationQueryPlanner) planDelete(del *sqlparser.Delete) (*QueryPlan, error) { +func (planner *VReplicationQueryPlanner) planDelete(del *sqlparser.Delete) (*FixedQueryPlan, error) { if del.Targets != nil { return nil, fmt.Errorf( "%w: DELETE must not have USING clause (have: %v): %v", @@ -186,27 +186,27 @@ func (planner *VReplicationQueryPlanner) planDelete(del *sqlparser.Delete) (*Que buf := sqlparser.NewTrackedBuffer(nil) buf.Myprintf("%v", del) - return &QueryPlan{ + return &FixedQueryPlan{ ParsedQuery: buf.ParsedQuery(), workflow: planner.workflow, tmc: planner.tmc, }, nil } -func (planner *VReplicationQueryPlanner) planSelect(sel *sqlparser.Select) (*QueryPlan, error) { +func (planner *VReplicationQueryPlanner) planSelect(sel *sqlparser.Select) (*FixedQueryPlan, error) { sel.Where = addDefaultWheres(planner, sel.Where) buf := sqlparser.NewTrackedBuffer(nil) buf.Myprintf("%v", sel) - return &QueryPlan{ + return &FixedQueryPlan{ ParsedQuery: buf.ParsedQuery(), workflow: planner.workflow, tmc: planner.tmc, }, nil } -func (planner *VReplicationQueryPlanner) planUpdate(upd *sqlparser.Update) (*QueryPlan, error) { +func (planner *VReplicationQueryPlanner) planUpdate(upd *sqlparser.Update) (*FixedQueryPlan, error) { if upd.OrderBy != nil || upd.Limit != nil { return nil, fmt.Errorf( "%w: UPDATE must not have explicit ordering (have: %v) or limit clauses (have: %v): %v", @@ -235,7 +235,7 @@ func (planner *VReplicationQueryPlanner) planUpdate(upd *sqlparser.Update) (*Que buf := sqlparser.NewTrackedBuffer(nil) buf.Myprintf("%v", upd) - return &QueryPlan{ + return &FixedQueryPlan{ ParsedQuery: buf.ParsedQuery(), workflow: planner.workflow, tmc: planner.tmc, diff --git a/go/vt/vtctl/workflow/vexec/query_planner_test.go b/go/vt/vtctl/workflow/vexec/query_planner_test.go index a63fbb96a65..ecb86758cfa 100644 --- a/go/vt/vtctl/workflow/vexec/query_planner_test.go +++ b/go/vt/vtctl/workflow/vexec/query_planner_test.go @@ -21,6 +21,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "vitess.io/vitess/go/vt/vtctl/workflow/vexec/testutil" ) @@ -122,7 +123,9 @@ func TestVReplicationQueryPlanner_planSelect(t *testing.T) { qp, err := planner.PlanQuery(stmt) assert.NoError(t, err) - assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), qp.ParsedQuery) + fixedqp, ok := qp.(*FixedQueryPlan) + require.True(t, ok, "VReplicationQueryPlanner should always return a FixedQueryPlan from PlanQuery, got %T", qp) + assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), fixedqp.ParsedQuery) }) } } @@ -179,7 +182,9 @@ func TestVReplicationQueryPlanner_planUpdate(t *testing.T) { return } - assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), qp.ParsedQuery) + fixedqp, ok := qp.(*FixedQueryPlan) + require.True(t, ok, "VReplicationQueryPlanner should always return a FixedQueryPlan from PlanQuery, got %T", qp) + assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), fixedqp.ParsedQuery) }) } } @@ -238,7 +243,9 @@ func TestVReplicationQueryPlanner_planDelete(t *testing.T) { return } - assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), qp.ParsedQuery) + fixedqp, ok := qp.(*FixedQueryPlan) + require.True(t, ok, "VReplicationQueryPlanner should always return a FixedQueryPlan from PlanQuery, got %T", qp) + assert.Equal(t, testutil.ParsedQueryFromString(t, tt.expectedPlannedQuery), fixedqp.ParsedQuery) }) } } From 0cd7233f4d10f480c584898167898f0a5eda772b Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Wed, 2 Jun 2021 20:13:22 -0400 Subject: [PATCH 253/310] Add FixedQueryPlan implementation of QueryPlan Signed-off-by: Andrew Mason --- go/vt/vtctl/workflow/vexec/query_plan.go | 85 ++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/go/vt/vtctl/workflow/vexec/query_plan.go b/go/vt/vtctl/workflow/vexec/query_plan.go index 26cbc515fc6..e6a9cb3a54d 100644 --- a/go/vt/vtctl/workflow/vexec/query_plan.go +++ b/go/vt/vtctl/workflow/vexec/query_plan.go @@ -116,3 +116,88 @@ func (qp *FixedQueryPlan) ExecuteScatter(ctx context.Context, targets ...*topo.T return results, rec.AggrError(vterrors.Aggregate) } + +// PerTargetQueryPlan implements the QueryPlan interface. Unlike FixedQueryPlan, +// this implementation implements different queries, keyed by tablet alias, on +// different targets. +// +// It is the callers responsibility to ensure that the shape of the QueryResult +// (i.e. fields returned) is consistent for each target's planned query, but +// this is not enforced. +type PerTargetQueryPlan struct { + ParsedQueries map[string]*sqlparser.ParsedQuery + + tmc tmclient.TabletManagerClient +} + +// Execute is part of the QueryPlan interface. +// +// It returns ErrUnpreparedQuery if there is no ParsedQuery for the target's +// tablet alias. +func (qp *PerTargetQueryPlan) Execute(ctx context.Context, target *topo.TabletInfo) (qr *querypb.QueryResult, err error) { + if qp.ParsedQueries == nil { + return nil, fmt.Errorf("%w: call PlanQuery on a query planner first", ErrUnpreparedQuery) + } + + targetAliasStr := target.AliasString() + query, ok := qp.ParsedQueries[targetAliasStr] + if !ok { + return nil, fmt.Errorf("%w: no prepared query for target %s", ErrUnpreparedQuery, targetAliasStr) + } + + defer func() { + if err != nil { + log.Warningf("Result on %v: %v", targetAliasStr, err) + return + } + }() + + qr, err = qp.tmc.VReplicationExec(ctx, target.Tablet, query.Query) + if err != nil { + return nil, err + } + + return qr, nil +} + +// ExecuteScatter is part of the QueryPlan interface. +func (qp *PerTargetQueryPlan) ExecuteScatter(ctx context.Context, targets ...*topo.TabletInfo) (map[*topo.TabletInfo]*querypb.QueryResult, error) { + if qp.ParsedQueries == nil { + // This check is an "optimization" on error handling. We check here, + // even though we will check this during the individual Execute calls, + // so that we return one error, rather than the same error aggregated + // len(targets) times. + return nil, fmt.Errorf("%w: call PlanQuery on a query planner first", ErrUnpreparedQuery) + } + + var ( + m sync.Mutex + wg sync.WaitGroup + rec concurrency.AllErrorRecorder + results = make(map[*topo.TabletInfo]*querypb.QueryResult, len(targets)) + ) + + for _, target := range targets { + wg.Add(1) + + go func(ctx context.Context, target *topo.TabletInfo) { + defer wg.Done() + + qr, err := qp.Execute(ctx, target) + if err != nil { + rec.RecordError(err) + + return + } + + m.Lock() + defer m.Unlock() + + results[target] = qr + }(ctx, target) + } + + wg.Wait() + + return results, rec.AggrError(vterrors.Aggregate) +} From 9a833eb9886735fdb32a1df1dc9f9361ea22b796 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Thu, 3 Jun 2021 10:47:30 -0400 Subject: [PATCH 254/310] Implement QueryPlanner for `vreplication_log` table queries Signed-off-by: Andrew Mason --- go/vt/vtctl/workflow/vexec/query_planner.go | 132 ++++++++++++++++++ .../workflow/vexec/query_planner_test.go | 132 ++++++++++++++++++ 2 files changed, 264 insertions(+) diff --git a/go/vt/vtctl/workflow/vexec/query_planner.go b/go/vt/vtctl/workflow/vexec/query_planner.go index 88dff55e9ae..770d7637bd4 100644 --- a/go/vt/vtctl/workflow/vexec/query_planner.go +++ b/go/vt/vtctl/workflow/vexec/query_planner.go @@ -242,6 +242,138 @@ func (planner *VReplicationQueryPlanner) planUpdate(upd *sqlparser.Update) (*Fix }, nil } +// VReplicationLogQueryPlanner implements the QueryPlanner interface for queries +// on the _vt.vreplication_log table. +type VReplicationLogQueryPlanner struct { + tmc tmclient.TabletManagerClient + tabletStreamIDs map[string][]int64 +} + +// NewVReplicationLogQueryPlanner returns a new VReplicationLogQueryPlanner. The +// tabletStreamIDs map determines what stream_ids are expected to have vrep_log +// rows, keyed by tablet alias string. +func NewVReplicationLogQueryPlanner(tmc tmclient.TabletManagerClient, tabletStreamIDs map[string][]int64) *VReplicationLogQueryPlanner { + return &VReplicationLogQueryPlanner{ + tmc: tmc, + tabletStreamIDs: tabletStreamIDs, + } +} + +// PlanQuery is part of the QueryPlanner interface. +// +// For vreplication_log query planners, only SELECT queries are supported. +func (planner *VReplicationLogQueryPlanner) PlanQuery(stmt sqlparser.Statement) (plan QueryPlan, err error) { + switch stmt := stmt.(type) { + case *sqlparser.Select: + plan, err = planner.planSelect(stmt) + case *sqlparser.Insert: + err = ErrUnsupportedQuery + case *sqlparser.Update: + err = ErrUnsupportedQuery + case *sqlparser.Delete: + err = ErrUnsupportedQuery + default: + err = ErrUnsupportedQuery + } + + if err != nil { + return nil, fmt.Errorf("%w: %s", err, sqlparser.String(stmt)) + } + + return plan, nil +} + +// QueryParams is part of the QueryPlanner interface. +func (planner *VReplicationLogQueryPlanner) QueryParams() QueryParams { + return QueryParams{} +} + +func (planner *VReplicationLogQueryPlanner) planSelect(sel *sqlparser.Select) (QueryPlan, error) { + where := sel.Where + cols := extractWhereComparisonColumns(where) + hasVReplIDCol := false + + for _, col := range cols { + if col == "vrepl_id" { + hasVReplIDCol = true + } + } + + if hasVReplIDCol { // we're not injecting per-target parameters, return a Fixed plan + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", sel) + + return &FixedQueryPlan{ + ParsedQuery: buf.ParsedQuery(), + tmc: planner.tmc, + }, nil + } + + // Construct a where clause to filter by vrepl_id, parameterized by target + // streamIDs. + queriesByTarget := make(map[string]*sqlparser.ParsedQuery, len(planner.tabletStreamIDs)) + for target, streamIDs := range planner.tabletStreamIDs { + targetWhere := &sqlparser.Where{ + Type: sqlparser.WhereClause, + } + + var expr sqlparser.Expr + switch len(streamIDs) { + case 0: // WHERE vreplication_log.vrepl_id IN () => WHERE 1 != 1 + one := sqlparser.NewIntLiteral("1") + expr = &sqlparser.ComparisonExpr{ + Operator: sqlparser.NotEqualOp, + Left: one, + Right: one, + } + case 1: // WHERE vreplication_log.vrepl_id = ? + expr = &sqlparser.ComparisonExpr{ + Operator: sqlparser.EqualOp, + Left: &sqlparser.ColName{ + Name: sqlparser.NewColIdent("vrepl_id"), + }, + Right: sqlparser.NewIntLiteral(fmt.Sprintf("%d", streamIDs[0])), + } + default: // WHERE vreplication_log.vrepl_id IN (?) + vals := []sqlparser.Expr{} + for _, streamID := range streamIDs { + vals = append(vals, sqlparser.NewIntLiteral(fmt.Sprintf("%d", streamID))) + } + + var tuple sqlparser.ValTuple = vals + expr = &sqlparser.ComparisonExpr{ + Operator: sqlparser.InOp, + Left: &sqlparser.ColName{ + Name: sqlparser.NewColIdent("vrepl_id"), + }, + Right: tuple, + } + } + + switch where { + case nil: + targetWhere.Expr = expr + default: + targetWhere.Expr = &sqlparser.AndExpr{ + Left: expr, + Right: where.Expr, + } + } + + sel.Where = targetWhere + + buf := sqlparser.NewTrackedBuffer(nil) + buf.Myprintf("%v", sel) + + queriesByTarget[target] = buf.ParsedQuery() + } + + return &PerTargetQueryPlan{ + ParsedQueries: queriesByTarget, + tmc: planner.tmc, + }, nil +} + func addDefaultWheres(planner QueryPlanner, where *sqlparser.Where) *sqlparser.Where { cols := extractWhereComparisonColumns(where) diff --git a/go/vt/vtctl/workflow/vexec/query_planner_test.go b/go/vt/vtctl/workflow/vexec/query_planner_test.go index ecb86758cfa..99d44f470ea 100644 --- a/go/vt/vtctl/workflow/vexec/query_planner_test.go +++ b/go/vt/vtctl/workflow/vexec/query_planner_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vtctl/workflow/vexec/testutil" ) @@ -249,3 +250,134 @@ func TestVReplicationQueryPlanner_planDelete(t *testing.T) { }) } } + +func TestVReplicationLogQueryPlanner(t *testing.T) { + t.Parallel() + + t.Run("planSelect", func(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + targetStreamIDs map[string][]int64 + query string + assertion func(t *testing.T, plan QueryPlan) + shouldErr bool + }{ + { + targetStreamIDs: map[string][]int64{ + "a": {1, 2}, + }, + query: "select * from _vt.vreplication_log", + assertion: func(t *testing.T, plan QueryPlan) { + t.Helper() + qp, ok := plan.(*PerTargetQueryPlan) + if !ok { + require.FailNow(t, "failed type check", "expected plan to be PerTargetQueryPlan, got %T: %v", plan, plan) + } + + expected := map[string]string{ + "a": "select * from _vt.vreplication_log where vrepl_id in (1, 2)", + } + assertQueryMapsMatch(t, expected, qp.ParsedQueries) + }, + }, + { + targetStreamIDs: map[string][]int64{ + "a": nil, + }, + query: "select * from _vt.vreplication_log", + assertion: func(t *testing.T, plan QueryPlan) { + t.Helper() + qp, ok := plan.(*PerTargetQueryPlan) + if !ok { + require.FailNow(t, "failed type check", "expected plan to be PerTargetQueryPlan, got %T: %v", plan, plan) + } + + expected := map[string]string{ + "a": "select * from _vt.vreplication_log where 1 != 1", + } + assertQueryMapsMatch(t, expected, qp.ParsedQueries) + }, + }, + { + targetStreamIDs: map[string][]int64{ + "a": {1}, + }, + query: "select * from _vt.vreplication_log", + assertion: func(t *testing.T, plan QueryPlan) { + t.Helper() + qp, ok := plan.(*PerTargetQueryPlan) + if !ok { + require.FailNow(t, "failed type check", "expected plan to be PerTargetQueryPlan, got %T: %v", plan, plan) + } + + expected := map[string]string{ + "a": "select * from _vt.vreplication_log where vrepl_id = 1", + } + assertQueryMapsMatch(t, expected, qp.ParsedQueries) + }, + }, + { + query: "select * from _vt.vreplication_log where vrepl_id = 1", + assertion: func(t *testing.T, plan QueryPlan) { + t.Helper() + qp, ok := plan.(*FixedQueryPlan) + if !ok { + require.FailNow(t, "failed type check", "expected plan to be FixedQueryPlan, got %T: %v", plan, plan) + } + + assert.Equal(t, "select * from _vt.vreplication_log where vrepl_id = 1", qp.ParsedQuery.Query) + }, + }, + { + targetStreamIDs: map[string][]int64{ + "a": {1, 2}, + }, + query: "select * from _vt.vreplication_log where foo = 'bar'", + assertion: func(t *testing.T, plan QueryPlan) { + t.Helper() + qp, ok := plan.(*PerTargetQueryPlan) + if !ok { + require.FailNow(t, "failed type check", "expected plan to be PerTargetQueryPlan, got %T: %v", plan, plan) + } + + expected := map[string]string{ + "a": "select * from _vt.vreplication_log where vrepl_id in (1, 2) and foo = 'bar'", + } + assertQueryMapsMatch(t, expected, qp.ParsedQueries) + }, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + planner := NewVReplicationLogQueryPlanner(nil, tt.targetStreamIDs) + stmt, err := sqlparser.Parse(tt.query) + require.NoError(t, err, "could not parse query %q", tt.query) + qp, err := planner.planSelect(stmt.(*sqlparser.Select)) + if tt.shouldErr { + assert.Error(t, err) + return + } + + tt.assertion(t, qp) + }) + } + }) +} + +func assertQueryMapsMatch(t *testing.T, expected map[string]string, actual map[string]*sqlparser.ParsedQuery, msgAndArgs ...interface{}) { + t.Helper() + + actualQueryMap := make(map[string]string, len(actual)) + for k, v := range actual { + actualQueryMap[k] = v.Query + } + + assert.Equal(t, expected, actualQueryMap, msgAndArgs...) +} From c08a1ca9e2ab00fb1de266205ad5b70183890e53 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Thu, 3 Jun 2021 19:29:19 -0400 Subject: [PATCH 255/310] Add Stream_Log to workflow protos Signed-off-by: Andrew Mason --- go/vt/proto/vtctldata/vtctldata.pb.go | 1409 +++++++++-------- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 507 ++++++ proto/vtctldata.proto | 21 + web/vtadmin/src/proto/vtadmin.d.ts | 354 +++++ web/vtadmin/src/proto/vtadmin.js | 974 +++++++++++- 5 files changed, 2641 insertions(+), 624 deletions(-) diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index d5b740efead..17eed3a9e0b 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -5061,6 +5061,16 @@ type Workflow_Stream struct { TimeUpdated *vttime.Time `protobuf:"bytes,10,opt,name=time_updated,json=timeUpdated,proto3" json:"time_updated,omitempty"` Message string `protobuf:"bytes,11,opt,name=message,proto3" json:"message,omitempty"` CopyStates []*Workflow_Stream_CopyState `protobuf:"bytes,12,rep,name=copy_states,json=copyStates,proto3" json:"copy_states,omitempty"` + Logs []*Workflow_Stream_Log `protobuf:"bytes,13,rep,name=logs,proto3" json:"logs,omitempty"` + // LogFetchError is set if we fail to fetch some logs for this stream. We + // will never fail to fetch workflows because we cannot fetch the logs, but + // we will still forward log-fetch errors to the caller, should that be + // relevant to the context in which they are fetching workflows. + // + // Note that this field being set does not necessarily mean that Logs is nil; + // if there are N logs that exist for the stream, and we fail to fetch the + // ith log, we will still return logs in [0, i) + (i, N]. + LogFetchError string `protobuf:"bytes,14,opt,name=log_fetch_error,json=logFetchError,proto3" json:"log_fetch_error,omitempty"` } func (x *Workflow_Stream) Reset() { @@ -5179,6 +5189,20 @@ func (x *Workflow_Stream) GetCopyStates() []*Workflow_Stream_CopyState { return nil } +func (x *Workflow_Stream) GetLogs() []*Workflow_Stream_Log { + if x != nil { + return x.Logs + } + return nil +} + +func (x *Workflow_Stream) GetLogFetchError() string { + if x != nil { + return x.LogFetchError + } + return "" +} + type Workflow_Stream_CopyState struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -5234,6 +5258,109 @@ func (x *Workflow_Stream_CopyState) GetLastPk() string { return "" } +type Workflow_Stream_Log struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + StreamId int64 `protobuf:"varint,2,opt,name=stream_id,json=streamId,proto3" json:"stream_id,omitempty"` + Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` + State string `protobuf:"bytes,4,opt,name=state,proto3" json:"state,omitempty"` + CreatedAt *vttime.Time `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + UpdatedAt *vttime.Time `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + Message string `protobuf:"bytes,7,opt,name=message,proto3" json:"message,omitempty"` + Count int64 `protobuf:"varint,8,opt,name=count,proto3" json:"count,omitempty"` +} + +func (x *Workflow_Stream_Log) Reset() { + *x = Workflow_Stream_Log{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[92] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Workflow_Stream_Log) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Workflow_Stream_Log) ProtoMessage() {} + +func (x *Workflow_Stream_Log) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[92] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Workflow_Stream_Log.ProtoReflect.Descriptor instead. +func (*Workflow_Stream_Log) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{6, 3, 1} +} + +func (x *Workflow_Stream_Log) GetId() int64 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Workflow_Stream_Log) GetStreamId() int64 { + if x != nil { + return x.StreamId + } + return 0 +} + +func (x *Workflow_Stream_Log) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Workflow_Stream_Log) GetState() string { + if x != nil { + return x.State + } + return "" +} + +func (x *Workflow_Stream_Log) GetCreatedAt() *vttime.Time { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *Workflow_Stream_Log) GetUpdatedAt() *vttime.Time { + if x != nil { + return x.UpdatedAt + } + return nil +} + +func (x *Workflow_Stream_Log) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Workflow_Stream_Log) GetCount() int64 { + if x != nil { + return x.Count + } + return 0 +} + var File_vtctldata_proto protoreflect.FileDescriptor var file_vtctldata_proto_rawDesc = []byte{ @@ -5299,7 +5426,7 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x22, 0xa8, 0x09, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, + 0x22, 0xed, 0x0b, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3f, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, @@ -5339,7 +5466,7 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x61, 0x62, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x1a, 0x9d, 0x04, 0x0a, 0x06, + 0x6d, 0x61, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x1a, 0xe2, 0x06, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2d, 0x0a, 0x06, @@ -5369,539 +5496,559 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x1a, - 0x3a, 0x0a, 0x09, 0x43, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x22, 0x59, 0x0a, 0x12, 0x41, - 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, - 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x15, 0x0a, 0x13, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, - 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x40, 0x0a, - 0x14, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, - 0x17, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x18, 0x41, 0x70, 0x70, - 0x6c, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, - 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, - 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, - 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x62, - 0x75, 0x69, 0x6c, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x62, - 0x75, 0x69, 0x6c, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x41, 0x70, 0x70, - 0x6c, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, 0x41, 0x70, 0x70, 0x6c, 0x79, - 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6b, - 0x69, 0x70, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x17, 0x0a, - 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, - 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x2c, 0x0a, 0x08, - 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, - 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x71, - 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x71, 0x6c, 0x22, 0x44, 0x0a, 0x14, - 0x41, 0x70, 0x70, 0x6c, 0x79, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x22, 0x9b, 0x01, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2d, 0x0a, 0x07, 0x64, 0x62, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, - 0x06, 0x64, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, - 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, - 0x22, 0xa6, 0x01, 0x0a, 0x18, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, - 0x0d, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x0c, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x0b, 0x61, 0x66, - 0x74, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x77, 0x61, 0x73, - 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x77, 0x61, 0x73, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xb6, 0x03, 0x0a, 0x15, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x2f, 0x0a, - 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x5f, 0x76, 0x5f, 0x73, - 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, - 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, - 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x4a, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6c, - 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x49, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x12, 0x73, 0x68, 0x61, 0x72, 0x64, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x40, 0x0a, 0x0c, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, 0x73, 0x18, 0x06, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, - 0x6d, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x73, 0x12, 0x2a, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x62, 0x61, - 0x73, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x31, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x54, 0x69, - 0x6d, 0x65, 0x22, 0x49, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x8c, 0x01, - 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x22, 0xa0, 0x01, 0x0a, - 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x30, 0x0a, - 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, - 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, - 0x41, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x73, 0x12, + 0x32, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, + 0x6f, 0x67, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6c, 0x6f, 0x67, 0x5f, 0x66, 0x65, 0x74, 0x63, 0x68, + 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, + 0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x3a, 0x0a, 0x09, 0x43, + 0x6f, 0x70, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x17, + 0x0a, 0x07, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x6b, 0x1a, 0xe6, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, + 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, + 0x1b, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x08, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x41, 0x74, 0x12, 0x2b, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, + 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0x59, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, + 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x15, 0x0a, 0x13, 0x41, + 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x40, 0x0a, 0x14, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9e, 0x01, + 0x0a, 0x18, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, + 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, + 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, + 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x72, + 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x6b, + 0x69, 0x70, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x0c, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1b, + 0x0a, 0x19, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xc3, 0x01, 0x0a, 0x13, + 0x41, 0x70, 0x70, 0x6c, 0x79, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x21, 0x0a, 0x0c, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x73, 0x6b, 0x69, 0x70, 0x52, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, + 0x10, 0x0a, 0x03, 0x73, 0x71, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x73, 0x71, + 0x6c, 0x22, 0x44, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, + 0x76, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x9b, 0x01, 0x0a, 0x17, 0x43, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2d, 0x0a, + 0x07, 0x64, 0x62, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x64, 0x62, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x07, + 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, + 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xa6, 0x01, 0x0a, 0x18, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0d, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x5f, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x0c, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x33, 0x0a, 0x0c, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x52, 0x0b, 0x61, 0x66, 0x74, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x1e, + 0x0a, 0x0b, 0x77, 0x61, 0x73, 0x5f, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x77, 0x61, 0x73, 0x44, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x22, 0xb6, + 0x03, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x0a, 0x17, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x1a, 0x0a, 0x18, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x63, 0x65, 0x12, 0x2f, 0x0a, 0x14, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x65, 0x6d, 0x70, 0x74, + 0x79, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x11, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x56, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x5f, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x12, 0x73, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4a, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, + 0x67, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x12, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x40, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x5f, 0x66, 0x72, 0x6f, 0x6d, + 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x46, 0x72, 0x6f, 0x6d, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x46, 0x72, + 0x6f, 0x6d, 0x73, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x16, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x62, 0x61, 0x73, 0x65, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x0d, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, + 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, + 0x68, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x49, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x22, 0x8c, 0x01, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x22, 0xa0, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x61, 0x6c, 0x72, 0x65, + 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x12, 0x73, 0x68, 0x61, 0x72, 0x64, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, + 0x69, 0x73, 0x74, 0x73, 0x22, 0x41, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x2d, 0x0a, 0x17, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x22, 0x1a, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x51, 0x0a, 0x15, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, + 0x18, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, 0x01, 0x0a, 0x13, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x28, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, + 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x76, 0x65, + 0x6e, 0x5f, 0x69, 0x66, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0d, 0x65, 0x76, 0x65, 0x6e, 0x49, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, + 0x67, 0x22, 0x16, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x14, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, + 0x23, 0x0a, 0x0d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8f, 0x02, + 0x0a, 0x1d, 0x45, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, + 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3e, 0x0a, 0x0f, 0x69, 0x67, 0x6e, + 0x6f, 0x72, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x04, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0e, 0x69, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, + 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, + 0xbc, 0x01, 0x0a, 0x1e, 0x45, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, + 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3c, + 0x0a, 0x1e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, + 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, - 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, - 0x73, 0x69, 0x76, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x76, 0x65, 0x6e, 0x5f, 0x69, 0x66, 0x5f, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x65, - 0x76, 0x65, 0x6e, 0x49, 0x66, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x22, 0x16, 0x0a, 0x14, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x79, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0e, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x6c, - 0x6c, 0x6f, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0c, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, - 0x17, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x8f, 0x02, 0x0a, 0x1d, 0x45, 0x6d, 0x65, - 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, - 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3e, 0x0a, 0x0f, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0e, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x73, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xbc, 0x01, 0x0a, 0x1e, 0x45, - 0x6d, 0x65, 0x72, 0x67, 0x65, 0x6e, 0x63, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xbe, 0x01, 0x0a, + 0x1f, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x4e, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x36, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6e, + 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, + 0x1a, 0x4b, 0x0a, 0x0b, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x45, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, + 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x62, 0x61, + 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x79, + 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, + 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x19, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x30, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, + 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x49, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x15, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x30, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x55, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, + 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, + 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, + 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, + 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, + 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, + 0x22, 0x50, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x22, 0x4c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, + 0x22, 0x3a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x4a, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, + 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, + 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0c, 0x73, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, + 0x56, 0x0a, 0x11, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, + 0x65, 0x6c, 0x6c, 0x22, 0x4e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, + 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, + 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0a, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x22, 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, + 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x53, 0x0a, 0x10, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, + 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x3d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3c, 0x0a, 0x1e, 0x46, 0x69, 0x6e, - 0x64, 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xbe, 0x01, 0x0a, 0x1f, 0x46, 0x69, 0x6e, 0x64, - 0x41, 0x6c, 0x6c, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x06, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x49, 0x6e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x64, 0x73, 0x1a, 0x4b, 0x0a, 0x0b, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x45, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x42, - 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x12, 0x3c, 0x0a, + 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x2f, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x42, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x22, 0x52, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, + 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, + 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, + 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, - 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, - 0x6c, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, - 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, - 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, - 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x30, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, - 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, - 0x61, 0x6d, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb6, - 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x61, 0x6c, - 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x61, 0x6c, - 0x69, 0x61, 0x73, 0x65, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x15, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, - 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x30, 0x0a, 0x12, 0x47, 0x65, 0x74, - 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x46, 0x0a, 0x13, 0x47, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, - 0x17, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, - 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, - 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, - 0x75, 0x6c, 0x65, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, - 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, - 0x65, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x6c, - 0x79, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, - 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x50, 0x0a, 0x11, 0x47, - 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x23, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x44, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x4c, 0x0a, - 0x0f, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, + 0x52, 0x0a, 0x1a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x17, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, + 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, + 0x42, 0x0a, 0x18, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, + 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x22, 0x89, 0x02, 0x0a, 0x1b, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3a, 0x0a, + 0x0d, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0c, 0x61, 0x76, 0x6f, + 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, + 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, + 0xba, 0x01, 0x0a, 0x1c, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x0a, 0x10, 0x47, - 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, - 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x59, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x72, - 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x56, 0x0a, 0x11, 0x53, 0x72, - 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x4b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, - 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x4e, - 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x72, 0x76, 0x5f, 0x76, - 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x52, 0x0a, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x2d, - 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xc5, 0x01, - 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, - 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, - 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x1a, 0x53, 0x0a, 0x10, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, - 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0x3d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x32, 0x0a, 0x1a, + 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x7f, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, + 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, + 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, + 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, + 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x2f, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x42, 0x0a, 0x12, 0x47, 0x65, 0x74, - 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x52, 0x0a, - 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, - 0x79, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x77, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, - 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xfb, 0x01, 0x0a, - 0x17, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x52, 0x0a, 0x1a, 0x70, 0x72, - 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x17, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x45, 0x6c, - 0x65, 0x63, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, - 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, - 0x6f, 0x72, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x42, 0x0a, 0x18, 0x49, 0x6e, - 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, - 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x89, - 0x02, 0x0a, 0x1b, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, - 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, - 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, - 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x0d, 0x61, 0x76, 0x6f, 0x69, - 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0c, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x1c, 0x50, - 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, - 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, - 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, - 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x32, 0x0a, 0x1a, 0x52, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x52, - 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, - 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7f, 0x0a, 0x19, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, - 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, - 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, - 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, - 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, - 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x46, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0x7b, 0x0a, 0x16, 0x52, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x20, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xaa, 0x03, - 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, - 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x5a, 0x0a, - 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, - 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, 0x0a, 0x18, 0x52, 0x65, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4e, 0x0a, 0x0e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x52, 0x0a, 0x21, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0xc6, - 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, + 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, + 0x7b, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, - 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, + 0x69, 0x61, 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x20, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x22, 0xaa, 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, + 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, + 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, + 0x4e, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x52, 0x0a, 0x21, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6f, 0x6c, 0x64, - 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, - 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, - 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, - 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, - 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x65, 0x0a, 0x18, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, - 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, + 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x12, 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0a, 0x6f, 0x6c, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, + 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, + 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, + 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, + 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, + 0x65, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, + 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5916,7 +6063,7 @@ func file_vtctldata_proto_rawDescGZIP() []byte { return file_vtctldata_proto_rawDescData } -var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 98) +var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 99) var file_vtctldata_proto_goTypes = []interface{}{ (*ExecuteVtctlCommandRequest)(nil), // 0: vtctldata.ExecuteVtctlCommandRequest (*ExecuteVtctlCommandResponse)(nil), // 1: vtctldata.ExecuteVtctlCommandResponse @@ -6010,122 +6157,126 @@ var file_vtctldata_proto_goTypes = []interface{}{ (*Workflow_ShardStream)(nil), // 89: vtctldata.Workflow.ShardStream (*Workflow_Stream)(nil), // 90: vtctldata.Workflow.Stream (*Workflow_Stream_CopyState)(nil), // 91: vtctldata.Workflow.Stream.CopyState - nil, // 92: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - nil, // 93: vtctldata.GetCellsAliasesResponse.AliasesEntry - nil, // 94: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - nil, // 95: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - nil, // 96: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - nil, // 97: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - (*logutil.Event)(nil), // 98: logutil.Event - (*topodata.Keyspace)(nil), // 99: topodata.Keyspace - (*topodata.Shard)(nil), // 100: topodata.Shard - (*topodata.CellInfo)(nil), // 101: topodata.CellInfo - (*vschema.RoutingRules)(nil), // 102: vschema.RoutingRules - (*vschema.Keyspace)(nil), // 103: vschema.Keyspace - (*topodata.TabletAlias)(nil), // 104: topodata.TabletAlias - (topodata.TabletType)(0), // 105: topodata.TabletType - (*topodata.Tablet)(nil), // 106: topodata.Tablet - (topodata.KeyspaceIdType)(0), // 107: topodata.KeyspaceIdType - (*topodata.Keyspace_ServedFrom)(nil), // 108: topodata.Keyspace.ServedFrom - (topodata.KeyspaceType)(0), // 109: topodata.KeyspaceType - (*vttime.Time)(nil), // 110: vttime.Time - (*vttime.Duration)(nil), // 111: vttime.Duration - (*mysqlctl.BackupInfo)(nil), // 112: mysqlctl.BackupInfo - (*tabletmanagerdata.SchemaDefinition)(nil), // 113: tabletmanagerdata.SchemaDefinition - (*vschema.SrvVSchema)(nil), // 114: vschema.SrvVSchema - (*topodata.CellsAlias)(nil), // 115: topodata.CellsAlias - (*topodata.Shard_TabletControl)(nil), // 116: topodata.Shard.TabletControl - (*binlogdata.BinlogSource)(nil), // 117: binlogdata.BinlogSource - (*topodata.SrvKeyspace)(nil), // 118: topodata.SrvKeyspace - (*replicationdata.Status)(nil), // 119: replicationdata.Status + (*Workflow_Stream_Log)(nil), // 92: vtctldata.Workflow.Stream.Log + nil, // 93: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + nil, // 94: vtctldata.GetCellsAliasesResponse.AliasesEntry + nil, // 95: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + nil, // 96: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + nil, // 97: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + nil, // 98: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + (*logutil.Event)(nil), // 99: logutil.Event + (*topodata.Keyspace)(nil), // 100: topodata.Keyspace + (*topodata.Shard)(nil), // 101: topodata.Shard + (*topodata.CellInfo)(nil), // 102: topodata.CellInfo + (*vschema.RoutingRules)(nil), // 103: vschema.RoutingRules + (*vschema.Keyspace)(nil), // 104: vschema.Keyspace + (*topodata.TabletAlias)(nil), // 105: topodata.TabletAlias + (topodata.TabletType)(0), // 106: topodata.TabletType + (*topodata.Tablet)(nil), // 107: topodata.Tablet + (topodata.KeyspaceIdType)(0), // 108: topodata.KeyspaceIdType + (*topodata.Keyspace_ServedFrom)(nil), // 109: topodata.Keyspace.ServedFrom + (topodata.KeyspaceType)(0), // 110: topodata.KeyspaceType + (*vttime.Time)(nil), // 111: vttime.Time + (*vttime.Duration)(nil), // 112: vttime.Duration + (*mysqlctl.BackupInfo)(nil), // 113: mysqlctl.BackupInfo + (*tabletmanagerdata.SchemaDefinition)(nil), // 114: tabletmanagerdata.SchemaDefinition + (*vschema.SrvVSchema)(nil), // 115: vschema.SrvVSchema + (*topodata.CellsAlias)(nil), // 116: topodata.CellsAlias + (*topodata.Shard_TabletControl)(nil), // 117: topodata.Shard.TabletControl + (*binlogdata.BinlogSource)(nil), // 118: binlogdata.BinlogSource + (*topodata.SrvKeyspace)(nil), // 119: topodata.SrvKeyspace + (*replicationdata.Status)(nil), // 120: replicationdata.Status } var file_vtctldata_proto_depIdxs = []int32{ - 98, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event + 99, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 2, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings - 99, // 2: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace - 100, // 3: vtctldata.Shard.shard:type_name -> topodata.Shard + 100, // 2: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 101, // 3: vtctldata.Shard.shard:type_name -> topodata.Shard 88, // 4: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation 88, // 5: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation 87, // 6: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry - 101, // 7: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 102, // 8: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 103, // 9: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 103, // 10: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 104, // 11: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 105, // 12: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 106, // 13: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 106, // 14: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 107, // 15: vtctldata.CreateKeyspaceRequest.sharding_column_type:type_name -> topodata.KeyspaceIdType - 108, // 16: vtctldata.CreateKeyspaceRequest.served_froms:type_name -> topodata.Keyspace.ServedFrom - 109, // 17: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 110, // 18: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 102, // 7: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 103, // 8: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 104, // 9: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 104, // 10: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 105, // 11: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 106, // 12: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 107, // 13: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 107, // 14: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 108, // 15: vtctldata.CreateKeyspaceRequest.sharding_column_type:type_name -> topodata.KeyspaceIdType + 109, // 16: vtctldata.CreateKeyspaceRequest.served_froms:type_name -> topodata.Keyspace.ServedFrom + 110, // 17: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 111, // 18: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time 4, // 19: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace 4, // 20: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace 5, // 21: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard 5, // 22: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 104, // 23: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 104, // 24: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 104, // 25: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 111, // 26: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 104, // 27: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 98, // 28: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 92, // 29: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 112, // 30: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 101, // 31: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 93, // 32: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 105, // 23: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 105, // 24: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 105, // 25: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 112, // 26: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 105, // 27: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 99, // 28: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 93, // 29: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 113, // 30: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 102, // 31: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 94, // 32: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry 4, // 33: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace 4, // 34: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 102, // 35: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 104, // 36: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 113, // 37: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 103, // 35: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 105, // 36: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 114, // 37: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition 5, // 38: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 94, // 39: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 114, // 40: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 95, // 41: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 104, // 42: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 106, // 43: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 104, // 44: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 106, // 45: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet - 103, // 46: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 95, // 39: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 115, // 40: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 96, // 41: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 105, // 42: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 107, // 43: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 105, // 44: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 107, // 45: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 104, // 46: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace 6, // 47: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 104, // 48: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 111, // 49: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 98, // 50: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 104, // 51: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 104, // 52: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 111, // 53: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 104, // 54: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 98, // 55: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 104, // 56: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 104, // 57: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 96, // 58: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 97, // 59: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 104, // 60: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 104, // 61: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 104, // 62: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 101, // 63: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 101, // 64: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 115, // 65: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 115, // 66: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 105, // 48: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 112, // 49: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 99, // 50: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 105, // 51: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 105, // 52: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 112, // 53: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 105, // 54: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 99, // 55: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 105, // 56: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 105, // 57: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 97, // 58: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 98, // 59: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 105, // 60: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 105, // 61: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 105, // 62: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 102, // 63: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 102, // 64: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 116, // 65: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 116, // 66: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias 89, // 67: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream 90, // 68: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 116, // 69: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 104, // 70: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 117, // 71: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 110, // 72: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 110, // 73: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 117, // 69: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 105, // 70: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 118, // 71: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 111, // 72: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 111, // 73: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time 91, // 74: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 5, // 75: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 115, // 76: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 118, // 77: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 114, // 78: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 119, // 79: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 106, // 80: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 81, // [81:81] is the sub-list for method output_type - 81, // [81:81] is the sub-list for method input_type - 81, // [81:81] is the sub-list for extension type_name - 81, // [81:81] is the sub-list for extension extendee - 0, // [0:81] is the sub-list for field type_name + 92, // 75: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 111, // 76: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 111, // 77: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 5, // 78: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 116, // 79: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 119, // 80: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 115, // 81: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 120, // 82: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 107, // 83: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 84, // [84:84] is the sub-list for method output_type + 84, // [84:84] is the sub-list for method input_type + 84, // [84:84] is the sub-list for extension type_name + 84, // [84:84] is the sub-list for extension extendee + 0, // [0:84] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -7226,6 +7377,18 @@ func file_vtctldata_proto_init() { return nil } } + file_vtctldata_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_Stream_Log); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -7233,7 +7396,7 @@ func file_vtctldata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 0, - NumMessages: 98, + NumMessages: 99, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index 19110ed7d6c..abd998d99d4 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -549,6 +549,99 @@ func (m *Workflow_Stream_CopyState) MarshalToSizedBufferVT(dAtA []byte) (int, er return len(dAtA) - i, nil } +func (m *Workflow_Stream_Log) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Workflow_Stream_Log) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Workflow_Stream_Log) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Count != 0 { + i = encodeVarint(dAtA, i, uint64(m.Count)) + i-- + dAtA[i] = 0x40 + } + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = encodeVarint(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x3a + } + if m.UpdatedAt != nil { + { + size, err := m.UpdatedAt.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.CreatedAt != nil { + { + size, err := m.CreatedAt.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.State) > 0 { + i -= len(m.State) + copy(dAtA[i:], m.State) + i = encodeVarint(dAtA, i, uint64(len(m.State))) + i-- + dAtA[i] = 0x22 + } + if len(m.Type) > 0 { + i -= len(m.Type) + copy(dAtA[i:], m.Type) + i = encodeVarint(dAtA, i, uint64(len(m.Type))) + i-- + dAtA[i] = 0x1a + } + if m.StreamId != 0 { + i = encodeVarint(dAtA, i, uint64(m.StreamId)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarint(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *Workflow_Stream) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -579,6 +672,27 @@ func (m *Workflow_Stream) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if len(m.LogFetchError) > 0 { + i -= len(m.LogFetchError) + copy(dAtA[i:], m.LogFetchError) + i = encodeVarint(dAtA, i, uint64(len(m.LogFetchError))) + i-- + dAtA[i] = 0x72 + } + if len(m.Logs) > 0 { + for iNdEx := len(m.Logs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Logs[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6a + } + } if len(m.CopyStates) > 0 { for iNdEx := len(m.CopyStates) - 1; iNdEx >= 0; iNdEx-- { { @@ -5139,6 +5253,47 @@ func (m *Workflow_Stream_CopyState) SizeVT() (n int) { return n } +func (m *Workflow_Stream_Log) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sov(uint64(m.Id)) + } + if m.StreamId != 0 { + n += 1 + sov(uint64(m.StreamId)) + } + l = len(m.Type) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.State) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.CreatedAt != nil { + l = m.CreatedAt.SizeVT() + n += 1 + l + sov(uint64(l)) + } + if m.UpdatedAt != nil { + l = m.UpdatedAt.SizeVT() + n += 1 + l + sov(uint64(l)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.Count != 0 { + n += 1 + sov(uint64(m.Count)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + func (m *Workflow_Stream) SizeVT() (n int) { if m == nil { return 0 @@ -5194,6 +5349,16 @@ func (m *Workflow_Stream) SizeVT() (n int) { n += 1 + l + sov(uint64(l)) } } + if len(m.Logs) > 0 { + for _, e := range m.Logs { + l = e.SizeVT() + n += 1 + l + sov(uint64(l)) + } + } + l = len(m.LogFetchError) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } if m.unknownFields != nil { n += len(m.unknownFields) } @@ -8128,6 +8293,282 @@ func (m *Workflow_Stream_CopyState) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *Workflow_Stream_Log) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Workflow_Stream_Log: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Workflow_Stream_Log: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StreamId", wireType) + } + m.StreamId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StreamId |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Type = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field State", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.State = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreatedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CreatedAt == nil { + m.CreatedAt = &vttime.Time{} + } + if err := m.CreatedAt.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UpdatedAt", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.UpdatedAt == nil { + m.UpdatedAt = &vttime.Time{} + } + if err := m.UpdatedAt.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Workflow_Stream) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -8546,6 +8987,72 @@ func (m *Workflow_Stream) UnmarshalVT(dAtA []byte) error { return err } iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Logs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Logs = append(m.Logs, &Workflow_Stream_Log{}) + if err := m.Logs[len(m.Logs)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LogFetchError", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LogFetchError = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 746f34c4cbc..c7fecd9d2b2 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -117,11 +117,32 @@ message Workflow { vttime.Time time_updated = 10; string message = 11; repeated CopyState copy_states = 12; + repeated Log logs = 13; + // LogFetchError is set if we fail to fetch some logs for this stream. We + // will never fail to fetch workflows because we cannot fetch the logs, but + // we will still forward log-fetch errors to the caller, should that be + // relevant to the context in which they are fetching workflows. + // + // Note that this field being set does not necessarily mean that Logs is nil; + // if there are N logs that exist for the stream, and we fail to fetch the + // ith log, we will still return logs in [0, i) + (i, N]. + string log_fetch_error = 14; message CopyState { string table = 1; string last_pk = 2; } + + message Log { + int64 id = 1; + int64 stream_id = 2; + string type = 3; + string state = 4; + vttime.Time created_at = 5; + vttime.Time updated_at = 6; + string message = 7; + int64 count = 8; + } } } diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 2856941d9be..c37d43b41f2 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -24307,6 +24307,12 @@ export namespace vtctldata { /** Stream copy_states */ copy_states?: (vtctldata.Workflow.Stream.ICopyState[]|null); + + /** Stream logs */ + logs?: (vtctldata.Workflow.Stream.ILog[]|null); + + /** Stream log_fetch_error */ + log_fetch_error?: (string|null); } /** Represents a Stream. */ @@ -24354,6 +24360,12 @@ export namespace vtctldata { /** Stream copy_states. */ public copy_states: vtctldata.Workflow.Stream.ICopyState[]; + /** Stream logs. */ + public logs: vtctldata.Workflow.Stream.ILog[]; + + /** Stream log_fetch_error. */ + public log_fetch_error: string; + /** * Creates a new Stream instance using the specified properties. * @param [properties] Properties to set @@ -24522,6 +24534,138 @@ export namespace vtctldata { */ public toJSON(): { [k: string]: any }; } + + /** Properties of a Log. */ + interface ILog { + + /** Log id */ + id?: (number|Long|null); + + /** Log stream_id */ + stream_id?: (number|Long|null); + + /** Log type */ + type?: (string|null); + + /** Log state */ + state?: (string|null); + + /** Log created_at */ + created_at?: (vttime.ITime|null); + + /** Log updated_at */ + updated_at?: (vttime.ITime|null); + + /** Log message */ + message?: (string|null); + + /** Log count */ + count?: (number|Long|null); + } + + /** Represents a Log. */ + class Log implements ILog { + + /** + * Constructs a new Log. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.Workflow.Stream.ILog); + + /** Log id. */ + public id: (number|Long); + + /** Log stream_id. */ + public stream_id: (number|Long); + + /** Log type. */ + public type: string; + + /** Log state. */ + public state: string; + + /** Log created_at. */ + public created_at?: (vttime.ITime|null); + + /** Log updated_at. */ + public updated_at?: (vttime.ITime|null); + + /** Log message. */ + public message: string; + + /** Log count. */ + public count: (number|Long); + + /** + * Creates a new Log instance using the specified properties. + * @param [properties] Properties to set + * @returns Log instance + */ + public static create(properties?: vtctldata.Workflow.Stream.ILog): vtctldata.Workflow.Stream.Log; + + /** + * Encodes the specified Log message. Does not implicitly {@link vtctldata.Workflow.Stream.Log.verify|verify} messages. + * @param message Log message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.Workflow.Stream.ILog, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified Log message, length delimited. Does not implicitly {@link vtctldata.Workflow.Stream.Log.verify|verify} messages. + * @param message Log message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.Workflow.Stream.ILog, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a Log message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns Log + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.Workflow.Stream.Log; + + /** + * Decodes a Log message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns Log + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.Workflow.Stream.Log; + + /** + * Verifies a Log message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a Log message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns Log + */ + public static fromObject(object: { [k: string]: any }): vtctldata.Workflow.Stream.Log; + + /** + * Creates a plain object from a Log message. Also converts values to other types if specified. + * @param message Log + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.Workflow.Stream.Log, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this Log to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } } } @@ -25071,6 +25215,216 @@ export namespace vtctldata { public toJSON(): { [k: string]: any }; } + /** Properties of an ApplyVSchemaRequest. */ + interface IApplyVSchemaRequest { + + /** ApplyVSchemaRequest keyspace */ + keyspace?: (string|null); + + /** ApplyVSchemaRequest skip_rebuild */ + skip_rebuild?: (boolean|null); + + /** ApplyVSchemaRequest dry_run */ + dry_run?: (boolean|null); + + /** ApplyVSchemaRequest cells */ + cells?: (string[]|null); + + /** ApplyVSchemaRequest v_schema */ + v_schema?: (vschema.IKeyspace|null); + + /** ApplyVSchemaRequest sql */ + sql?: (string|null); + } + + /** Represents an ApplyVSchemaRequest. */ + class ApplyVSchemaRequest implements IApplyVSchemaRequest { + + /** + * Constructs a new ApplyVSchemaRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IApplyVSchemaRequest); + + /** ApplyVSchemaRequest keyspace. */ + public keyspace: string; + + /** ApplyVSchemaRequest skip_rebuild. */ + public skip_rebuild: boolean; + + /** ApplyVSchemaRequest dry_run. */ + public dry_run: boolean; + + /** ApplyVSchemaRequest cells. */ + public cells: string[]; + + /** ApplyVSchemaRequest v_schema. */ + public v_schema?: (vschema.IKeyspace|null); + + /** ApplyVSchemaRequest sql. */ + public sql: string; + + /** + * Creates a new ApplyVSchemaRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns ApplyVSchemaRequest instance + */ + public static create(properties?: vtctldata.IApplyVSchemaRequest): vtctldata.ApplyVSchemaRequest; + + /** + * Encodes the specified ApplyVSchemaRequest message. Does not implicitly {@link vtctldata.ApplyVSchemaRequest.verify|verify} messages. + * @param message ApplyVSchemaRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IApplyVSchemaRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ApplyVSchemaRequest message, length delimited. Does not implicitly {@link vtctldata.ApplyVSchemaRequest.verify|verify} messages. + * @param message ApplyVSchemaRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IApplyVSchemaRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ApplyVSchemaRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ApplyVSchemaRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ApplyVSchemaRequest; + + /** + * Decodes an ApplyVSchemaRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ApplyVSchemaRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ApplyVSchemaRequest; + + /** + * Verifies an ApplyVSchemaRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ApplyVSchemaRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ApplyVSchemaRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ApplyVSchemaRequest; + + /** + * Creates a plain object from an ApplyVSchemaRequest message. Also converts values to other types if specified. + * @param message ApplyVSchemaRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ApplyVSchemaRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ApplyVSchemaRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of an ApplyVSchemaResponse. */ + interface IApplyVSchemaResponse { + + /** ApplyVSchemaResponse v_schema */ + v_schema?: (vschema.IKeyspace|null); + } + + /** Represents an ApplyVSchemaResponse. */ + class ApplyVSchemaResponse implements IApplyVSchemaResponse { + + /** + * Constructs a new ApplyVSchemaResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IApplyVSchemaResponse); + + /** ApplyVSchemaResponse v_schema. */ + public v_schema?: (vschema.IKeyspace|null); + + /** + * Creates a new ApplyVSchemaResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns ApplyVSchemaResponse instance + */ + public static create(properties?: vtctldata.IApplyVSchemaResponse): vtctldata.ApplyVSchemaResponse; + + /** + * Encodes the specified ApplyVSchemaResponse message. Does not implicitly {@link vtctldata.ApplyVSchemaResponse.verify|verify} messages. + * @param message ApplyVSchemaResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IApplyVSchemaResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified ApplyVSchemaResponse message, length delimited. Does not implicitly {@link vtctldata.ApplyVSchemaResponse.verify|verify} messages. + * @param message ApplyVSchemaResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IApplyVSchemaResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes an ApplyVSchemaResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns ApplyVSchemaResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.ApplyVSchemaResponse; + + /** + * Decodes an ApplyVSchemaResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns ApplyVSchemaResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.ApplyVSchemaResponse; + + /** + * Verifies an ApplyVSchemaResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates an ApplyVSchemaResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns ApplyVSchemaResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.ApplyVSchemaResponse; + + /** + * Creates a plain object from an ApplyVSchemaResponse message. Also converts values to other types if specified. + * @param message ApplyVSchemaResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.ApplyVSchemaResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this ApplyVSchemaResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a ChangeTabletTypeRequest. */ interface IChangeTabletTypeRequest { diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 3927af67ddd..1628750744b 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -58372,6 +58372,8 @@ $root.vtctldata = (function() { * @property {vttime.ITime|null} [time_updated] Stream time_updated * @property {string|null} [message] Stream message * @property {Array.|null} [copy_states] Stream copy_states + * @property {Array.|null} [logs] Stream logs + * @property {string|null} [log_fetch_error] Stream log_fetch_error */ /** @@ -58384,6 +58386,7 @@ $root.vtctldata = (function() { */ function Stream(properties) { this.copy_states = []; + this.logs = []; if (properties) for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) if (properties[keys[i]] != null) @@ -58486,6 +58489,22 @@ $root.vtctldata = (function() { */ Stream.prototype.copy_states = $util.emptyArray; + /** + * Stream logs. + * @member {Array.} logs + * @memberof vtctldata.Workflow.Stream + * @instance + */ + Stream.prototype.logs = $util.emptyArray; + + /** + * Stream log_fetch_error. + * @member {string} log_fetch_error + * @memberof vtctldata.Workflow.Stream + * @instance + */ + Stream.prototype.log_fetch_error = ""; + /** * Creates a new Stream instance using the specified properties. * @function create @@ -58535,6 +58554,11 @@ $root.vtctldata = (function() { if (message.copy_states != null && message.copy_states.length) for (var i = 0; i < message.copy_states.length; ++i) $root.vtctldata.Workflow.Stream.CopyState.encode(message.copy_states[i], writer.uint32(/* id 12, wireType 2 =*/98).fork()).ldelim(); + if (message.logs != null && message.logs.length) + for (var i = 0; i < message.logs.length; ++i) + $root.vtctldata.Workflow.Stream.Log.encode(message.logs[i], writer.uint32(/* id 13, wireType 2 =*/106).fork()).ldelim(); + if (message.log_fetch_error != null && Object.hasOwnProperty.call(message, "log_fetch_error")) + writer.uint32(/* id 14, wireType 2 =*/114).string(message.log_fetch_error); return writer; }; @@ -58607,6 +58631,14 @@ $root.vtctldata = (function() { message.copy_states = []; message.copy_states.push($root.vtctldata.Workflow.Stream.CopyState.decode(reader, reader.uint32())); break; + case 13: + if (!(message.logs && message.logs.length)) + message.logs = []; + message.logs.push($root.vtctldata.Workflow.Stream.Log.decode(reader, reader.uint32())); + break; + case 14: + message.log_fetch_error = reader.string(); + break; default: reader.skipType(tag & 7); break; @@ -58692,6 +58724,18 @@ $root.vtctldata = (function() { return "copy_states." + error; } } + if (message.logs != null && message.hasOwnProperty("logs")) { + if (!Array.isArray(message.logs)) + return "logs: array expected"; + for (var i = 0; i < message.logs.length; ++i) { + var error = $root.vtctldata.Workflow.Stream.Log.verify(message.logs[i]); + if (error) + return "logs." + error; + } + } + if (message.log_fetch_error != null && message.hasOwnProperty("log_fetch_error")) + if (!$util.isString(message.log_fetch_error)) + return "log_fetch_error: string expected"; return null; }; @@ -58758,6 +58802,18 @@ $root.vtctldata = (function() { message.copy_states[i] = $root.vtctldata.Workflow.Stream.CopyState.fromObject(object.copy_states[i]); } } + if (object.logs) { + if (!Array.isArray(object.logs)) + throw TypeError(".vtctldata.Workflow.Stream.logs: array expected"); + message.logs = []; + for (var i = 0; i < object.logs.length; ++i) { + if (typeof object.logs[i] !== "object") + throw TypeError(".vtctldata.Workflow.Stream.logs: object expected"); + message.logs[i] = $root.vtctldata.Workflow.Stream.Log.fromObject(object.logs[i]); + } + } + if (object.log_fetch_error != null) + message.log_fetch_error = String(object.log_fetch_error); return message; }; @@ -58774,8 +58830,10 @@ $root.vtctldata = (function() { if (!options) options = {}; var object = {}; - if (options.arrays || options.defaults) + if (options.arrays || options.defaults) { object.copy_states = []; + object.logs = []; + } if (options.defaults) { if ($util.Long) { var long = new $util.Long(0, 0, false); @@ -58792,6 +58850,7 @@ $root.vtctldata = (function() { object.transaction_timestamp = null; object.time_updated = null; object.message = ""; + object.log_fetch_error = ""; } if (message.id != null && message.hasOwnProperty("id")) if (typeof message.id === "number") @@ -58823,6 +58882,13 @@ $root.vtctldata = (function() { for (var j = 0; j < message.copy_states.length; ++j) object.copy_states[j] = $root.vtctldata.Workflow.Stream.CopyState.toObject(message.copy_states[j], options); } + if (message.logs && message.logs.length) { + object.logs = []; + for (var j = 0; j < message.logs.length; ++j) + object.logs[j] = $root.vtctldata.Workflow.Stream.Log.toObject(message.logs[j], options); + } + if (message.log_fetch_error != null && message.hasOwnProperty("log_fetch_error")) + object.log_fetch_error = message.log_fetch_error; return object; }; @@ -59047,6 +59113,400 @@ $root.vtctldata = (function() { return CopyState; })(); + Stream.Log = (function() { + + /** + * Properties of a Log. + * @memberof vtctldata.Workflow.Stream + * @interface ILog + * @property {number|Long|null} [id] Log id + * @property {number|Long|null} [stream_id] Log stream_id + * @property {string|null} [type] Log type + * @property {string|null} [state] Log state + * @property {vttime.ITime|null} [created_at] Log created_at + * @property {vttime.ITime|null} [updated_at] Log updated_at + * @property {string|null} [message] Log message + * @property {number|Long|null} [count] Log count + */ + + /** + * Constructs a new Log. + * @memberof vtctldata.Workflow.Stream + * @classdesc Represents a Log. + * @implements ILog + * @constructor + * @param {vtctldata.Workflow.Stream.ILog=} [properties] Properties to set + */ + function Log(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Log id. + * @member {number|Long} id + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.id = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Log stream_id. + * @member {number|Long} stream_id + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.stream_id = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Log type. + * @member {string} type + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.type = ""; + + /** + * Log state. + * @member {string} state + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.state = ""; + + /** + * Log created_at. + * @member {vttime.ITime|null|undefined} created_at + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.created_at = null; + + /** + * Log updated_at. + * @member {vttime.ITime|null|undefined} updated_at + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.updated_at = null; + + /** + * Log message. + * @member {string} message + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.message = ""; + + /** + * Log count. + * @member {number|Long} count + * @memberof vtctldata.Workflow.Stream.Log + * @instance + */ + Log.prototype.count = $util.Long ? $util.Long.fromBits(0,0,false) : 0; + + /** + * Creates a new Log instance using the specified properties. + * @function create + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {vtctldata.Workflow.Stream.ILog=} [properties] Properties to set + * @returns {vtctldata.Workflow.Stream.Log} Log instance + */ + Log.create = function create(properties) { + return new Log(properties); + }; + + /** + * Encodes the specified Log message. Does not implicitly {@link vtctldata.Workflow.Stream.Log.verify|verify} messages. + * @function encode + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {vtctldata.Workflow.Stream.ILog} message Log message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Log.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.id != null && Object.hasOwnProperty.call(message, "id")) + writer.uint32(/* id 1, wireType 0 =*/8).int64(message.id); + if (message.stream_id != null && Object.hasOwnProperty.call(message, "stream_id")) + writer.uint32(/* id 2, wireType 0 =*/16).int64(message.stream_id); + if (message.type != null && Object.hasOwnProperty.call(message, "type")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.type); + if (message.state != null && Object.hasOwnProperty.call(message, "state")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.state); + if (message.created_at != null && Object.hasOwnProperty.call(message, "created_at")) + $root.vttime.Time.encode(message.created_at, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.updated_at != null && Object.hasOwnProperty.call(message, "updated_at")) + $root.vttime.Time.encode(message.updated_at, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.message != null && Object.hasOwnProperty.call(message, "message")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.message); + if (message.count != null && Object.hasOwnProperty.call(message, "count")) + writer.uint32(/* id 8, wireType 0 =*/64).int64(message.count); + return writer; + }; + + /** + * Encodes the specified Log message, length delimited. Does not implicitly {@link vtctldata.Workflow.Stream.Log.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {vtctldata.Workflow.Stream.ILog} message Log message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + Log.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a Log message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.Workflow.Stream.Log} Log + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Log.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.Workflow.Stream.Log(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.int64(); + break; + case 2: + message.stream_id = reader.int64(); + break; + case 3: + message.type = reader.string(); + break; + case 4: + message.state = reader.string(); + break; + case 5: + message.created_at = $root.vttime.Time.decode(reader, reader.uint32()); + break; + case 6: + message.updated_at = $root.vttime.Time.decode(reader, reader.uint32()); + break; + case 7: + message.message = reader.string(); + break; + case 8: + message.count = reader.int64(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a Log message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.Workflow.Stream.Log} Log + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + Log.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a Log message. + * @function verify + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + Log.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.id != null && message.hasOwnProperty("id")) + if (!$util.isInteger(message.id) && !(message.id && $util.isInteger(message.id.low) && $util.isInteger(message.id.high))) + return "id: integer|Long expected"; + if (message.stream_id != null && message.hasOwnProperty("stream_id")) + if (!$util.isInteger(message.stream_id) && !(message.stream_id && $util.isInteger(message.stream_id.low) && $util.isInteger(message.stream_id.high))) + return "stream_id: integer|Long expected"; + if (message.type != null && message.hasOwnProperty("type")) + if (!$util.isString(message.type)) + return "type: string expected"; + if (message.state != null && message.hasOwnProperty("state")) + if (!$util.isString(message.state)) + return "state: string expected"; + if (message.created_at != null && message.hasOwnProperty("created_at")) { + var error = $root.vttime.Time.verify(message.created_at); + if (error) + return "created_at." + error; + } + if (message.updated_at != null && message.hasOwnProperty("updated_at")) { + var error = $root.vttime.Time.verify(message.updated_at); + if (error) + return "updated_at." + error; + } + if (message.message != null && message.hasOwnProperty("message")) + if (!$util.isString(message.message)) + return "message: string expected"; + if (message.count != null && message.hasOwnProperty("count")) + if (!$util.isInteger(message.count) && !(message.count && $util.isInteger(message.count.low) && $util.isInteger(message.count.high))) + return "count: integer|Long expected"; + return null; + }; + + /** + * Creates a Log message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.Workflow.Stream.Log} Log + */ + Log.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.Workflow.Stream.Log) + return object; + var message = new $root.vtctldata.Workflow.Stream.Log(); + if (object.id != null) + if ($util.Long) + (message.id = $util.Long.fromValue(object.id)).unsigned = false; + else if (typeof object.id === "string") + message.id = parseInt(object.id, 10); + else if (typeof object.id === "number") + message.id = object.id; + else if (typeof object.id === "object") + message.id = new $util.LongBits(object.id.low >>> 0, object.id.high >>> 0).toNumber(); + if (object.stream_id != null) + if ($util.Long) + (message.stream_id = $util.Long.fromValue(object.stream_id)).unsigned = false; + else if (typeof object.stream_id === "string") + message.stream_id = parseInt(object.stream_id, 10); + else if (typeof object.stream_id === "number") + message.stream_id = object.stream_id; + else if (typeof object.stream_id === "object") + message.stream_id = new $util.LongBits(object.stream_id.low >>> 0, object.stream_id.high >>> 0).toNumber(); + if (object.type != null) + message.type = String(object.type); + if (object.state != null) + message.state = String(object.state); + if (object.created_at != null) { + if (typeof object.created_at !== "object") + throw TypeError(".vtctldata.Workflow.Stream.Log.created_at: object expected"); + message.created_at = $root.vttime.Time.fromObject(object.created_at); + } + if (object.updated_at != null) { + if (typeof object.updated_at !== "object") + throw TypeError(".vtctldata.Workflow.Stream.Log.updated_at: object expected"); + message.updated_at = $root.vttime.Time.fromObject(object.updated_at); + } + if (object.message != null) + message.message = String(object.message); + if (object.count != null) + if ($util.Long) + (message.count = $util.Long.fromValue(object.count)).unsigned = false; + else if (typeof object.count === "string") + message.count = parseInt(object.count, 10); + else if (typeof object.count === "number") + message.count = object.count; + else if (typeof object.count === "object") + message.count = new $util.LongBits(object.count.low >>> 0, object.count.high >>> 0).toNumber(); + return message; + }; + + /** + * Creates a plain object from a Log message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.Workflow.Stream.Log + * @static + * @param {vtctldata.Workflow.Stream.Log} message Log + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + Log.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) { + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.id = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.id = options.longs === String ? "0" : 0; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.stream_id = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.stream_id = options.longs === String ? "0" : 0; + object.type = ""; + object.state = ""; + object.created_at = null; + object.updated_at = null; + object.message = ""; + if ($util.Long) { + var long = new $util.Long(0, 0, false); + object.count = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long; + } else + object.count = options.longs === String ? "0" : 0; + } + if (message.id != null && message.hasOwnProperty("id")) + if (typeof message.id === "number") + object.id = options.longs === String ? String(message.id) : message.id; + else + object.id = options.longs === String ? $util.Long.prototype.toString.call(message.id) : options.longs === Number ? new $util.LongBits(message.id.low >>> 0, message.id.high >>> 0).toNumber() : message.id; + if (message.stream_id != null && message.hasOwnProperty("stream_id")) + if (typeof message.stream_id === "number") + object.stream_id = options.longs === String ? String(message.stream_id) : message.stream_id; + else + object.stream_id = options.longs === String ? $util.Long.prototype.toString.call(message.stream_id) : options.longs === Number ? new $util.LongBits(message.stream_id.low >>> 0, message.stream_id.high >>> 0).toNumber() : message.stream_id; + if (message.type != null && message.hasOwnProperty("type")) + object.type = message.type; + if (message.state != null && message.hasOwnProperty("state")) + object.state = message.state; + if (message.created_at != null && message.hasOwnProperty("created_at")) + object.created_at = $root.vttime.Time.toObject(message.created_at, options); + if (message.updated_at != null && message.hasOwnProperty("updated_at")) + object.updated_at = $root.vttime.Time.toObject(message.updated_at, options); + if (message.message != null && message.hasOwnProperty("message")) + object.message = message.message; + if (message.count != null && message.hasOwnProperty("count")) + if (typeof message.count === "number") + object.count = options.longs === String ? String(message.count) : message.count; + else + object.count = options.longs === String ? $util.Long.prototype.toString.call(message.count) : options.longs === Number ? new $util.LongBits(message.count.low >>> 0, message.count.high >>> 0).toNumber() : message.count; + return object; + }; + + /** + * Converts this Log to JSON. + * @function toJSON + * @memberof vtctldata.Workflow.Stream.Log + * @instance + * @returns {Object.} JSON object + */ + Log.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return Log; + })(); + return Stream; })(); @@ -60228,6 +60688,518 @@ $root.vtctldata = (function() { return ApplyRoutingRulesResponse; })(); + vtctldata.ApplyVSchemaRequest = (function() { + + /** + * Properties of an ApplyVSchemaRequest. + * @memberof vtctldata + * @interface IApplyVSchemaRequest + * @property {string|null} [keyspace] ApplyVSchemaRequest keyspace + * @property {boolean|null} [skip_rebuild] ApplyVSchemaRequest skip_rebuild + * @property {boolean|null} [dry_run] ApplyVSchemaRequest dry_run + * @property {Array.|null} [cells] ApplyVSchemaRequest cells + * @property {vschema.IKeyspace|null} [v_schema] ApplyVSchemaRequest v_schema + * @property {string|null} [sql] ApplyVSchemaRequest sql + */ + + /** + * Constructs a new ApplyVSchemaRequest. + * @memberof vtctldata + * @classdesc Represents an ApplyVSchemaRequest. + * @implements IApplyVSchemaRequest + * @constructor + * @param {vtctldata.IApplyVSchemaRequest=} [properties] Properties to set + */ + function ApplyVSchemaRequest(properties) { + this.cells = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ApplyVSchemaRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + */ + ApplyVSchemaRequest.prototype.keyspace = ""; + + /** + * ApplyVSchemaRequest skip_rebuild. + * @member {boolean} skip_rebuild + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + */ + ApplyVSchemaRequest.prototype.skip_rebuild = false; + + /** + * ApplyVSchemaRequest dry_run. + * @member {boolean} dry_run + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + */ + ApplyVSchemaRequest.prototype.dry_run = false; + + /** + * ApplyVSchemaRequest cells. + * @member {Array.} cells + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + */ + ApplyVSchemaRequest.prototype.cells = $util.emptyArray; + + /** + * ApplyVSchemaRequest v_schema. + * @member {vschema.IKeyspace|null|undefined} v_schema + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + */ + ApplyVSchemaRequest.prototype.v_schema = null; + + /** + * ApplyVSchemaRequest sql. + * @member {string} sql + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + */ + ApplyVSchemaRequest.prototype.sql = ""; + + /** + * Creates a new ApplyVSchemaRequest instance using the specified properties. + * @function create + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {vtctldata.IApplyVSchemaRequest=} [properties] Properties to set + * @returns {vtctldata.ApplyVSchemaRequest} ApplyVSchemaRequest instance + */ + ApplyVSchemaRequest.create = function create(properties) { + return new ApplyVSchemaRequest(properties); + }; + + /** + * Encodes the specified ApplyVSchemaRequest message. Does not implicitly {@link vtctldata.ApplyVSchemaRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {vtctldata.IApplyVSchemaRequest} message ApplyVSchemaRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyVSchemaRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); + if (message.skip_rebuild != null && Object.hasOwnProperty.call(message, "skip_rebuild")) + writer.uint32(/* id 2, wireType 0 =*/16).bool(message.skip_rebuild); + if (message.dry_run != null && Object.hasOwnProperty.call(message, "dry_run")) + writer.uint32(/* id 3, wireType 0 =*/24).bool(message.dry_run); + if (message.cells != null && message.cells.length) + for (var i = 0; i < message.cells.length; ++i) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.cells[i]); + if (message.v_schema != null && Object.hasOwnProperty.call(message, "v_schema")) + $root.vschema.Keyspace.encode(message.v_schema, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.sql != null && Object.hasOwnProperty.call(message, "sql")) + writer.uint32(/* id 6, wireType 2 =*/50).string(message.sql); + return writer; + }; + + /** + * Encodes the specified ApplyVSchemaRequest message, length delimited. Does not implicitly {@link vtctldata.ApplyVSchemaRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {vtctldata.IApplyVSchemaRequest} message ApplyVSchemaRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyVSchemaRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ApplyVSchemaRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ApplyVSchemaRequest} ApplyVSchemaRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyVSchemaRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ApplyVSchemaRequest(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.keyspace = reader.string(); + break; + case 2: + message.skip_rebuild = reader.bool(); + break; + case 3: + message.dry_run = reader.bool(); + break; + case 4: + if (!(message.cells && message.cells.length)) + message.cells = []; + message.cells.push(reader.string()); + break; + case 5: + message.v_schema = $root.vschema.Keyspace.decode(reader, reader.uint32()); + break; + case 6: + message.sql = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ApplyVSchemaRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ApplyVSchemaRequest} ApplyVSchemaRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyVSchemaRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ApplyVSchemaRequest message. + * @function verify + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ApplyVSchemaRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.skip_rebuild != null && message.hasOwnProperty("skip_rebuild")) + if (typeof message.skip_rebuild !== "boolean") + return "skip_rebuild: boolean expected"; + if (message.dry_run != null && message.hasOwnProperty("dry_run")) + if (typeof message.dry_run !== "boolean") + return "dry_run: boolean expected"; + if (message.cells != null && message.hasOwnProperty("cells")) { + if (!Array.isArray(message.cells)) + return "cells: array expected"; + for (var i = 0; i < message.cells.length; ++i) + if (!$util.isString(message.cells[i])) + return "cells: string[] expected"; + } + if (message.v_schema != null && message.hasOwnProperty("v_schema")) { + var error = $root.vschema.Keyspace.verify(message.v_schema); + if (error) + return "v_schema." + error; + } + if (message.sql != null && message.hasOwnProperty("sql")) + if (!$util.isString(message.sql)) + return "sql: string expected"; + return null; + }; + + /** + * Creates an ApplyVSchemaRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ApplyVSchemaRequest} ApplyVSchemaRequest + */ + ApplyVSchemaRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ApplyVSchemaRequest) + return object; + var message = new $root.vtctldata.ApplyVSchemaRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.skip_rebuild != null) + message.skip_rebuild = Boolean(object.skip_rebuild); + if (object.dry_run != null) + message.dry_run = Boolean(object.dry_run); + if (object.cells) { + if (!Array.isArray(object.cells)) + throw TypeError(".vtctldata.ApplyVSchemaRequest.cells: array expected"); + message.cells = []; + for (var i = 0; i < object.cells.length; ++i) + message.cells[i] = String(object.cells[i]); + } + if (object.v_schema != null) { + if (typeof object.v_schema !== "object") + throw TypeError(".vtctldata.ApplyVSchemaRequest.v_schema: object expected"); + message.v_schema = $root.vschema.Keyspace.fromObject(object.v_schema); + } + if (object.sql != null) + message.sql = String(object.sql); + return message; + }; + + /** + * Creates a plain object from an ApplyVSchemaRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ApplyVSchemaRequest + * @static + * @param {vtctldata.ApplyVSchemaRequest} message ApplyVSchemaRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ApplyVSchemaRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.cells = []; + if (options.defaults) { + object.keyspace = ""; + object.skip_rebuild = false; + object.dry_run = false; + object.v_schema = null; + object.sql = ""; + } + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.skip_rebuild != null && message.hasOwnProperty("skip_rebuild")) + object.skip_rebuild = message.skip_rebuild; + if (message.dry_run != null && message.hasOwnProperty("dry_run")) + object.dry_run = message.dry_run; + if (message.cells && message.cells.length) { + object.cells = []; + for (var j = 0; j < message.cells.length; ++j) + object.cells[j] = message.cells[j]; + } + if (message.v_schema != null && message.hasOwnProperty("v_schema")) + object.v_schema = $root.vschema.Keyspace.toObject(message.v_schema, options); + if (message.sql != null && message.hasOwnProperty("sql")) + object.sql = message.sql; + return object; + }; + + /** + * Converts this ApplyVSchemaRequest to JSON. + * @function toJSON + * @memberof vtctldata.ApplyVSchemaRequest + * @instance + * @returns {Object.} JSON object + */ + ApplyVSchemaRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ApplyVSchemaRequest; + })(); + + vtctldata.ApplyVSchemaResponse = (function() { + + /** + * Properties of an ApplyVSchemaResponse. + * @memberof vtctldata + * @interface IApplyVSchemaResponse + * @property {vschema.IKeyspace|null} [v_schema] ApplyVSchemaResponse v_schema + */ + + /** + * Constructs a new ApplyVSchemaResponse. + * @memberof vtctldata + * @classdesc Represents an ApplyVSchemaResponse. + * @implements IApplyVSchemaResponse + * @constructor + * @param {vtctldata.IApplyVSchemaResponse=} [properties] Properties to set + */ + function ApplyVSchemaResponse(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * ApplyVSchemaResponse v_schema. + * @member {vschema.IKeyspace|null|undefined} v_schema + * @memberof vtctldata.ApplyVSchemaResponse + * @instance + */ + ApplyVSchemaResponse.prototype.v_schema = null; + + /** + * Creates a new ApplyVSchemaResponse instance using the specified properties. + * @function create + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {vtctldata.IApplyVSchemaResponse=} [properties] Properties to set + * @returns {vtctldata.ApplyVSchemaResponse} ApplyVSchemaResponse instance + */ + ApplyVSchemaResponse.create = function create(properties) { + return new ApplyVSchemaResponse(properties); + }; + + /** + * Encodes the specified ApplyVSchemaResponse message. Does not implicitly {@link vtctldata.ApplyVSchemaResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {vtctldata.IApplyVSchemaResponse} message ApplyVSchemaResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyVSchemaResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.v_schema != null && Object.hasOwnProperty.call(message, "v_schema")) + $root.vschema.Keyspace.encode(message.v_schema, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified ApplyVSchemaResponse message, length delimited. Does not implicitly {@link vtctldata.ApplyVSchemaResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {vtctldata.IApplyVSchemaResponse} message ApplyVSchemaResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + ApplyVSchemaResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes an ApplyVSchemaResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.ApplyVSchemaResponse} ApplyVSchemaResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyVSchemaResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.ApplyVSchemaResponse(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.v_schema = $root.vschema.Keyspace.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes an ApplyVSchemaResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.ApplyVSchemaResponse} ApplyVSchemaResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + ApplyVSchemaResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies an ApplyVSchemaResponse message. + * @function verify + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + ApplyVSchemaResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.v_schema != null && message.hasOwnProperty("v_schema")) { + var error = $root.vschema.Keyspace.verify(message.v_schema); + if (error) + return "v_schema." + error; + } + return null; + }; + + /** + * Creates an ApplyVSchemaResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.ApplyVSchemaResponse} ApplyVSchemaResponse + */ + ApplyVSchemaResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.ApplyVSchemaResponse) + return object; + var message = new $root.vtctldata.ApplyVSchemaResponse(); + if (object.v_schema != null) { + if (typeof object.v_schema !== "object") + throw TypeError(".vtctldata.ApplyVSchemaResponse.v_schema: object expected"); + message.v_schema = $root.vschema.Keyspace.fromObject(object.v_schema); + } + return message; + }; + + /** + * Creates a plain object from an ApplyVSchemaResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.ApplyVSchemaResponse + * @static + * @param {vtctldata.ApplyVSchemaResponse} message ApplyVSchemaResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + ApplyVSchemaResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.v_schema = null; + if (message.v_schema != null && message.hasOwnProperty("v_schema")) + object.v_schema = $root.vschema.Keyspace.toObject(message.v_schema, options); + return object; + }; + + /** + * Converts this ApplyVSchemaResponse to JSON. + * @function toJSON + * @memberof vtctldata.ApplyVSchemaResponse + * @instance + * @returns {Object.} JSON object + */ + ApplyVSchemaResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return ApplyVSchemaResponse; + })(); + vtctldata.ChangeTabletTypeRequest = (function() { /** From 80bce00ca271268566e8c0e2ad3e8616e8f1622a Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Thu, 3 Jun 2021 19:35:55 -0400 Subject: [PATCH 256/310] Add support for querying _vt.vreplication_log in vexec Signed-off-by: Andrew Mason --- go/vt/vtctl/workflow/vexec/vexec.go | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/go/vt/vtctl/workflow/vexec/vexec.go b/go/vt/vtctl/workflow/vexec/vexec.go index d61bd16ab31..93c5359d068 100644 --- a/go/vt/vtctl/workflow/vexec/vexec.go +++ b/go/vt/vtctl/workflow/vexec/vexec.go @@ -21,9 +21,11 @@ import ( "errors" "fmt" + "vitess.io/vitess/go/sqltypes" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/topo/topoproto" + "vitess.io/vitess/go/vt/vtgate/evalengine" "vitess.io/vitess/go/vt/vttablet/tmclient" querypb "vitess.io/vitess/go/vt/proto/query" @@ -37,6 +39,9 @@ const ( // SchemaMigrationsTableName is the unqualified name of the schema // migrations table supported by vexec. SchemaMigrationsTableName = "schema_migrations" + // VReplicationLogTableName is the unqualified name of the vreplication_log + // table supported by vexec. + VReplicationLogTableName = "vreplication_log" // VReplicationTableName is the unqualified name of the vreplication table // supported by vexec. VReplicationTableName = "vreplication" @@ -208,6 +213,30 @@ func (vx *VExec) GetPlanner(ctx context.Context, table string) (QueryPlanner, er switch table { case qualifiedTableName(VReplicationTableName): return NewVReplicationQueryPlanner(vx.tmc, vx.workflow, vx.primaries[0].DbName()), nil + case qualifiedTableName(VReplicationLogTableName): + results, err := vx.QueryContext(ctx, "select id from _vt.vreplication") + if err != nil { + return nil, err + } + + tabletStreamIDMap := make(map[string][]int64, len(results)) + + for tablet, p3qr := range results { + qr := sqltypes.Proto3ToResult(p3qr) + aliasStr := tablet.AliasString() + tabletStreamIDMap[aliasStr] = make([]int64, len(qr.Rows)) + + for i, row := range qr.Rows { + id, err := evalengine.ToInt64(row[0]) + if err != nil { + return nil, err + } + + tabletStreamIDMap[aliasStr][i] = id + } + } + + return NewVReplicationLogQueryPlanner(vx.tmc, tabletStreamIDMap), nil case qualifiedTableName(SchemaMigrationsTableName): return nil, errors.New("Schema Migrations not yet supported in new workflow package") default: @@ -215,6 +244,18 @@ func (vx *VExec) GetPlanner(ctx context.Context, table string) (QueryPlanner, er } } +// WithWorkflow returns a copy of VExec with the Workflow field updated. Used so +// callers to reuse a VExec's primaries list without needing to initialize a new +// VExec instance. +func (vx *VExec) WithWorkflow(workflow string) *VExec { + return &VExec{ + ts: vx.ts, + tmc: vx.tmc, + primaries: vx.primaries, + workflow: workflow, + } +} + func extractTableName(stmt sqlparser.Statement) (string, error) { switch stmt := stmt.(type) { case *sqlparser.Update: From 24b84a4ec2efc507f8d4c1fc0f1dce61c4454c95 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Thu, 3 Jun 2021 19:48:26 -0400 Subject: [PATCH 257/310] [workflow] Optionally fetch all vreplication_logs for each stream Signed-off-by: Andrew Mason --- go/vt/vtctl/workflow/server.go | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 397f9d30e75..460a7884090 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -20,7 +20,9 @@ import ( "context" "errors" "fmt" + "sort" "strings" + "sync" "time" "google.golang.org/protobuf/encoding/prototext" @@ -465,6 +467,147 @@ func (s *Server) GetWorkflows(ctx context.Context, req *vtctldatapb.GetWorkflows if err := scanWorkflow(ctx, workflow, row, tablet); err != nil { return nil, err } + + // Sort shard streams by stream_id ASC, to support an optimization + // in fetchStreamLogs below. + for _, shardStreams := range workflow.ShardStreams { + sort.Slice(shardStreams.Streams, func(i, j int) bool { + return shardStreams.Streams[i].Id < shardStreams.Streams[j].Id + }) + } + } + } + + var ( + wg sync.WaitGroup + vrepLogQuery = strings.TrimSpace(` +SELECT + id, + vrepl_id, + type, + state, + message, + created_at, + updated_at, + count +FROM + _vt.vreplication_log +ORDER BY + vrepl_id ASC, + id ASC +`) + ) + + fetchStreamLogs := func(ctx context.Context, workflow *vtctldatapb.Workflow) { + defer wg.Done() + + results, err := vx.WithWorkflow(workflow.Name).QueryContext(ctx, vrepLogQuery) + if err != nil { + // Note that we do not return here. If there are any query results + // in the map (i.e. some tablets returned successfully), we will + // still try to read log rows from them on a best-effort basis. But, + // we will also pre-emptively record the top-level fetch error on + // every stream in every shard in the workflow. Further processing + // below may override the error message for certain streams. + for _, streams := range workflow.ShardStreams { + for _, stream := range streams.Streams { + stream.LogFetchError = err.Error() + } + } + } + + for target, p3qr := range results { + qr := sqltypes.Proto3ToResult(p3qr) + shardStreamKey := fmt.Sprintf("%s/%s", target.Shard, target.AliasString()) + + ss, ok := workflow.ShardStreams[shardStreamKey] + if !ok || ss == nil { + continue + } + + streams := ss.Streams + streamIdx := 0 + markErrors := func(err error) { + if streamIdx >= len(streams) { + return + } + + streams[streamIdx].LogFetchError = err.Error() + } + + for _, row := range qr.Rows { + id, err := evalengine.ToInt64(row[0]) + if err != nil { + markErrors(err) + continue + } + + streamID, err := evalengine.ToInt64(row[1]) + if err != nil { + markErrors(err) + continue + } + + typ := row[2].ToString() + state := row[3].ToString() + message := row[4].ToString() + + createdAt, err := time.Parse("2006-01-02 15:04:05", row[5].ToString()) + if err != nil { + markErrors(err) + continue + } + + updatedAt, err := time.Parse("2006-01-02 15:04:05", row[6].ToString()) + if err != nil { + markErrors(err) + continue + } + + count, err := evalengine.ToInt64(row[7]) + if err != nil { + markErrors(err) + continue + } + + streamLog := &vtctldatapb.Workflow_Stream_Log{ + Id: id, + StreamId: streamID, + Type: typ, + State: state, + CreatedAt: &vttime.Time{ + Seconds: createdAt.Unix(), + }, + UpdatedAt: &vttime.Time{ + Seconds: updatedAt.Unix(), + }, + Message: message, + Count: count, + } + + // Earlier, in the main loop where we called scanWorkflow for + // each _vt.vreplication row, we also sorted each ShardStreams + // slice by ascending id, and our _vt.vreplication_log query + // ordered by (stream_id ASC, id ASC), so we can walk the + // streams in index order in O(n) amortized over all the rows + // for this tablet. + for streamIdx < len(streams) { + stream := streams[streamIdx] + if stream.Id < streamLog.StreamId { + streamIdx++ + continue + } + + if stream.Id > streamLog.StreamId { + log.Warningf("Found stream log for nonexistent stream: %+v", streamLog) + break + } + + // stream.Id == streamLog.StreamId + stream.Logs = append(stream.Logs, streamLog) + break + } + } } } @@ -508,9 +651,16 @@ func (s *Server) GetWorkflows(ctx context.Context, req *vtctldatapb.GetWorkflows workflow.MaxVReplicationLag = int64(maxVReplicationLag) + // Fetch logs for all streams associated with this workflow in the background. + wg.Add(1) + go fetchStreamLogs(ctx, workflow) + workflows = append(workflows, workflow) } + // Wait for all the log fetchers to finish. + wg.Wait() + return &vtctldatapb.GetWorkflowsResponse{ Workflows: workflows, }, nil From 98d3cd4e510d201de3cc1349d365c13569426406 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 1 Jun 2021 16:34:54 -0400 Subject: [PATCH 258/310] Add rpcs, run generators for `RefreshState(ByShard)?` methods Signed-off-by: Andrew Mason --- go/vt/proto/vtctldata/vtctldata.pb.go | 882 ++++++++++++------ go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 602 ++++++++++++ go/vt/proto/vtctlservice/vtctlservice.pb.go | 310 +++--- .../vtctlservice/vtctlservice_grpc.pb.go | 76 ++ go/vt/vtctl/grpcvtctldclient/client_gen.go | 18 + go/vt/vtctl/grpcvtctldserver/server.go | 10 + proto/vtctldata.proto | 17 + proto/vtctlservice.proto | 4 + web/vtadmin/src/proto/vtadmin.d.ts | 366 ++++++++ web/vtadmin/src/proto/vtadmin.js | 788 ++++++++++++++++ 10 files changed, 2620 insertions(+), 453 deletions(-) diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index 17eed3a9e0b..c7430f821c5 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -4121,6 +4121,201 @@ func (*RebuildVSchemaGraphResponse) Descriptor() ([]byte, []int) { return file_vtctldata_proto_rawDescGZIP(), []int{72} } +type RefreshStateRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TabletAlias *topodata.TabletAlias `protobuf:"bytes,1,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` +} + +func (x *RefreshStateRequest) Reset() { + *x = RefreshStateRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshStateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshStateRequest) ProtoMessage() {} + +func (x *RefreshStateRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshStateRequest.ProtoReflect.Descriptor instead. +func (*RefreshStateRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{73} +} + +func (x *RefreshStateRequest) GetTabletAlias() *topodata.TabletAlias { + if x != nil { + return x.TabletAlias + } + return nil +} + +type RefreshStateResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *RefreshStateResponse) Reset() { + *x = RefreshStateResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshStateResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshStateResponse) ProtoMessage() {} + +func (x *RefreshStateResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[74] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshStateResponse.ProtoReflect.Descriptor instead. +func (*RefreshStateResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{74} +} + +type RefreshStateByShardRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + Cells []string `protobuf:"bytes,3,rep,name=cells,proto3" json:"cells,omitempty"` +} + +func (x *RefreshStateByShardRequest) Reset() { + *x = RefreshStateByShardRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshStateByShardRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshStateByShardRequest) ProtoMessage() {} + +func (x *RefreshStateByShardRequest) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[75] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshStateByShardRequest.ProtoReflect.Descriptor instead. +func (*RefreshStateByShardRequest) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{75} +} + +func (x *RefreshStateByShardRequest) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *RefreshStateByShardRequest) GetShard() string { + if x != nil { + return x.Shard + } + return "" +} + +func (x *RefreshStateByShardRequest) GetCells() []string { + if x != nil { + return x.Cells + } + return nil +} + +type RefreshStateByShardResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + IsPartialRefresh bool `protobuf:"varint,1,opt,name=is_partial_refresh,json=isPartialRefresh,proto3" json:"is_partial_refresh,omitempty"` +} + +func (x *RefreshStateByShardResponse) Reset() { + *x = RefreshStateByShardResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_vtctldata_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshStateByShardResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshStateByShardResponse) ProtoMessage() {} + +func (x *RefreshStateByShardResponse) ProtoReflect() protoreflect.Message { + mi := &file_vtctldata_proto_msgTypes[76] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshStateByShardResponse.ProtoReflect.Descriptor instead. +func (*RefreshStateByShardResponse) Descriptor() ([]byte, []int) { + return file_vtctldata_proto_rawDescGZIP(), []int{76} +} + +func (x *RefreshStateByShardResponse) GetIsPartialRefresh() bool { + if x != nil { + return x.IsPartialRefresh + } + return false +} + type RemoveKeyspaceCellRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4140,7 +4335,7 @@ type RemoveKeyspaceCellRequest struct { func (x *RemoveKeyspaceCellRequest) Reset() { *x = RemoveKeyspaceCellRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[73] + mi := &file_vtctldata_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4153,7 +4348,7 @@ func (x *RemoveKeyspaceCellRequest) String() string { func (*RemoveKeyspaceCellRequest) ProtoMessage() {} func (x *RemoveKeyspaceCellRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[73] + mi := &file_vtctldata_proto_msgTypes[77] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4166,7 +4361,7 @@ func (x *RemoveKeyspaceCellRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveKeyspaceCellRequest.ProtoReflect.Descriptor instead. func (*RemoveKeyspaceCellRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{73} + return file_vtctldata_proto_rawDescGZIP(), []int{77} } func (x *RemoveKeyspaceCellRequest) GetKeyspace() string { @@ -4206,7 +4401,7 @@ type RemoveKeyspaceCellResponse struct { func (x *RemoveKeyspaceCellResponse) Reset() { *x = RemoveKeyspaceCellResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[74] + mi := &file_vtctldata_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4219,7 +4414,7 @@ func (x *RemoveKeyspaceCellResponse) String() string { func (*RemoveKeyspaceCellResponse) ProtoMessage() {} func (x *RemoveKeyspaceCellResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[74] + mi := &file_vtctldata_proto_msgTypes[78] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4232,7 +4427,7 @@ func (x *RemoveKeyspaceCellResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveKeyspaceCellResponse.ProtoReflect.Descriptor instead. func (*RemoveKeyspaceCellResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{74} + return file_vtctldata_proto_rawDescGZIP(), []int{78} } type RemoveShardCellRequest struct { @@ -4255,7 +4450,7 @@ type RemoveShardCellRequest struct { func (x *RemoveShardCellRequest) Reset() { *x = RemoveShardCellRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[75] + mi := &file_vtctldata_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4268,7 +4463,7 @@ func (x *RemoveShardCellRequest) String() string { func (*RemoveShardCellRequest) ProtoMessage() {} func (x *RemoveShardCellRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[75] + mi := &file_vtctldata_proto_msgTypes[79] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4281,7 +4476,7 @@ func (x *RemoveShardCellRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveShardCellRequest.ProtoReflect.Descriptor instead. func (*RemoveShardCellRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{75} + return file_vtctldata_proto_rawDescGZIP(), []int{79} } func (x *RemoveShardCellRequest) GetKeyspace() string { @@ -4328,7 +4523,7 @@ type RemoveShardCellResponse struct { func (x *RemoveShardCellResponse) Reset() { *x = RemoveShardCellResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[76] + mi := &file_vtctldata_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4341,7 +4536,7 @@ func (x *RemoveShardCellResponse) String() string { func (*RemoveShardCellResponse) ProtoMessage() {} func (x *RemoveShardCellResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[76] + mi := &file_vtctldata_proto_msgTypes[80] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4354,7 +4549,7 @@ func (x *RemoveShardCellResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RemoveShardCellResponse.ProtoReflect.Descriptor instead. func (*RemoveShardCellResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{76} + return file_vtctldata_proto_rawDescGZIP(), []int{80} } type ReparentTabletRequest struct { @@ -4370,7 +4565,7 @@ type ReparentTabletRequest struct { func (x *ReparentTabletRequest) Reset() { *x = ReparentTabletRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[77] + mi := &file_vtctldata_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4383,7 +4578,7 @@ func (x *ReparentTabletRequest) String() string { func (*ReparentTabletRequest) ProtoMessage() {} func (x *ReparentTabletRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[77] + mi := &file_vtctldata_proto_msgTypes[81] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4396,7 +4591,7 @@ func (x *ReparentTabletRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReparentTabletRequest.ProtoReflect.Descriptor instead. func (*ReparentTabletRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{77} + return file_vtctldata_proto_rawDescGZIP(), []int{81} } func (x *ReparentTabletRequest) GetTablet() *topodata.TabletAlias { @@ -4422,7 +4617,7 @@ type ReparentTabletResponse struct { func (x *ReparentTabletResponse) Reset() { *x = ReparentTabletResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[78] + mi := &file_vtctldata_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4435,7 +4630,7 @@ func (x *ReparentTabletResponse) String() string { func (*ReparentTabletResponse) ProtoMessage() {} func (x *ReparentTabletResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[78] + mi := &file_vtctldata_proto_msgTypes[82] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4448,7 +4643,7 @@ func (x *ReparentTabletResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReparentTabletResponse.ProtoReflect.Descriptor instead. func (*ReparentTabletResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{78} + return file_vtctldata_proto_rawDescGZIP(), []int{82} } func (x *ReparentTabletResponse) GetKeyspace() string { @@ -4484,7 +4679,7 @@ type ShardReplicationPositionsRequest struct { func (x *ShardReplicationPositionsRequest) Reset() { *x = ShardReplicationPositionsRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[79] + mi := &file_vtctldata_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4497,7 +4692,7 @@ func (x *ShardReplicationPositionsRequest) String() string { func (*ShardReplicationPositionsRequest) ProtoMessage() {} func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[79] + mi := &file_vtctldata_proto_msgTypes[83] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4510,7 +4705,7 @@ func (x *ShardReplicationPositionsRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ShardReplicationPositionsRequest.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{79} + return file_vtctldata_proto_rawDescGZIP(), []int{83} } func (x *ShardReplicationPositionsRequest) GetKeyspace() string { @@ -4543,7 +4738,7 @@ type ShardReplicationPositionsResponse struct { func (x *ShardReplicationPositionsResponse) Reset() { *x = ShardReplicationPositionsResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[80] + mi := &file_vtctldata_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4556,7 +4751,7 @@ func (x *ShardReplicationPositionsResponse) String() string { func (*ShardReplicationPositionsResponse) ProtoMessage() {} func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[80] + mi := &file_vtctldata_proto_msgTypes[84] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4569,7 +4764,7 @@ func (x *ShardReplicationPositionsResponse) ProtoReflect() protoreflect.Message // Deprecated: Use ShardReplicationPositionsResponse.ProtoReflect.Descriptor instead. func (*ShardReplicationPositionsResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{80} + return file_vtctldata_proto_rawDescGZIP(), []int{84} } func (x *ShardReplicationPositionsResponse) GetReplicationStatuses() map[string]*replicationdata.Status { @@ -4599,7 +4794,7 @@ type TabletExternallyReparentedRequest struct { func (x *TabletExternallyReparentedRequest) Reset() { *x = TabletExternallyReparentedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[81] + mi := &file_vtctldata_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4612,7 +4807,7 @@ func (x *TabletExternallyReparentedRequest) String() string { func (*TabletExternallyReparentedRequest) ProtoMessage() {} func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[81] + mi := &file_vtctldata_proto_msgTypes[85] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4625,7 +4820,7 @@ func (x *TabletExternallyReparentedRequest) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedRequest.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{81} + return file_vtctldata_proto_rawDescGZIP(), []int{85} } func (x *TabletExternallyReparentedRequest) GetTablet() *topodata.TabletAlias { @@ -4649,7 +4844,7 @@ type TabletExternallyReparentedResponse struct { func (x *TabletExternallyReparentedResponse) Reset() { *x = TabletExternallyReparentedResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[82] + mi := &file_vtctldata_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4662,7 +4857,7 @@ func (x *TabletExternallyReparentedResponse) String() string { func (*TabletExternallyReparentedResponse) ProtoMessage() {} func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[82] + mi := &file_vtctldata_proto_msgTypes[86] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4675,7 +4870,7 @@ func (x *TabletExternallyReparentedResponse) ProtoReflect() protoreflect.Message // Deprecated: Use TabletExternallyReparentedResponse.ProtoReflect.Descriptor instead. func (*TabletExternallyReparentedResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{82} + return file_vtctldata_proto_rawDescGZIP(), []int{86} } func (x *TabletExternallyReparentedResponse) GetKeyspace() string { @@ -4718,7 +4913,7 @@ type UpdateCellInfoRequest struct { func (x *UpdateCellInfoRequest) Reset() { *x = UpdateCellInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[83] + mi := &file_vtctldata_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4731,7 +4926,7 @@ func (x *UpdateCellInfoRequest) String() string { func (*UpdateCellInfoRequest) ProtoMessage() {} func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[83] + mi := &file_vtctldata_proto_msgTypes[87] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4744,7 +4939,7 @@ func (x *UpdateCellInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoRequest.ProtoReflect.Descriptor instead. func (*UpdateCellInfoRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{83} + return file_vtctldata_proto_rawDescGZIP(), []int{87} } func (x *UpdateCellInfoRequest) GetName() string { @@ -4773,7 +4968,7 @@ type UpdateCellInfoResponse struct { func (x *UpdateCellInfoResponse) Reset() { *x = UpdateCellInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[84] + mi := &file_vtctldata_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4786,7 +4981,7 @@ func (x *UpdateCellInfoResponse) String() string { func (*UpdateCellInfoResponse) ProtoMessage() {} func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[84] + mi := &file_vtctldata_proto_msgTypes[88] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4799,7 +4994,7 @@ func (x *UpdateCellInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellInfoResponse.ProtoReflect.Descriptor instead. func (*UpdateCellInfoResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{84} + return file_vtctldata_proto_rawDescGZIP(), []int{88} } func (x *UpdateCellInfoResponse) GetName() string { @@ -4828,7 +5023,7 @@ type UpdateCellsAliasRequest struct { func (x *UpdateCellsAliasRequest) Reset() { *x = UpdateCellsAliasRequest{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[85] + mi := &file_vtctldata_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4841,7 +5036,7 @@ func (x *UpdateCellsAliasRequest) String() string { func (*UpdateCellsAliasRequest) ProtoMessage() {} func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[85] + mi := &file_vtctldata_proto_msgTypes[89] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4854,7 +5049,7 @@ func (x *UpdateCellsAliasRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasRequest.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasRequest) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{85} + return file_vtctldata_proto_rawDescGZIP(), []int{89} } func (x *UpdateCellsAliasRequest) GetName() string { @@ -4883,7 +5078,7 @@ type UpdateCellsAliasResponse struct { func (x *UpdateCellsAliasResponse) Reset() { *x = UpdateCellsAliasResponse{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[86] + mi := &file_vtctldata_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4896,7 +5091,7 @@ func (x *UpdateCellsAliasResponse) String() string { func (*UpdateCellsAliasResponse) ProtoMessage() {} func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[86] + mi := &file_vtctldata_proto_msgTypes[90] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4909,7 +5104,7 @@ func (x *UpdateCellsAliasResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateCellsAliasResponse.ProtoReflect.Descriptor instead. func (*UpdateCellsAliasResponse) Descriptor() ([]byte, []int) { - return file_vtctldata_proto_rawDescGZIP(), []int{86} + return file_vtctldata_proto_rawDescGZIP(), []int{90} } func (x *UpdateCellsAliasResponse) GetName() string { @@ -4938,7 +5133,7 @@ type Workflow_ReplicationLocation struct { func (x *Workflow_ReplicationLocation) Reset() { *x = Workflow_ReplicationLocation{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[88] + mi := &file_vtctldata_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4951,7 +5146,7 @@ func (x *Workflow_ReplicationLocation) String() string { func (*Workflow_ReplicationLocation) ProtoMessage() {} func (x *Workflow_ReplicationLocation) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[88] + mi := &file_vtctldata_proto_msgTypes[92] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4994,7 +5189,7 @@ type Workflow_ShardStream struct { func (x *Workflow_ShardStream) Reset() { *x = Workflow_ShardStream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[89] + mi := &file_vtctldata_proto_msgTypes[93] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5007,7 +5202,7 @@ func (x *Workflow_ShardStream) String() string { func (*Workflow_ShardStream) ProtoMessage() {} func (x *Workflow_ShardStream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[89] + mi := &file_vtctldata_proto_msgTypes[93] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5076,7 +5271,7 @@ type Workflow_Stream struct { func (x *Workflow_Stream) Reset() { *x = Workflow_Stream{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[90] + mi := &file_vtctldata_proto_msgTypes[94] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5089,7 +5284,7 @@ func (x *Workflow_Stream) String() string { func (*Workflow_Stream) ProtoMessage() {} func (x *Workflow_Stream) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[90] + mi := &file_vtctldata_proto_msgTypes[94] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5215,7 +5410,7 @@ type Workflow_Stream_CopyState struct { func (x *Workflow_Stream_CopyState) Reset() { *x = Workflow_Stream_CopyState{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[91] + mi := &file_vtctldata_proto_msgTypes[95] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5228,7 +5423,7 @@ func (x *Workflow_Stream_CopyState) String() string { func (*Workflow_Stream_CopyState) ProtoMessage() {} func (x *Workflow_Stream_CopyState) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[91] + mi := &file_vtctldata_proto_msgTypes[95] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5276,7 +5471,7 @@ type Workflow_Stream_Log struct { func (x *Workflow_Stream_Log) Reset() { *x = Workflow_Stream_Log{} if protoimpl.UnsafeEnabled { - mi := &file_vtctldata_proto_msgTypes[92] + mi := &file_vtctldata_proto_msgTypes[96] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5289,7 +5484,7 @@ func (x *Workflow_Stream_Log) String() string { func (*Workflow_Stream_Log) ProtoMessage() {} func (x *Workflow_Stream_Log) ProtoReflect() protoreflect.Message { - mi := &file_vtctldata_proto_msgTypes[92] + mi := &file_vtctldata_proto_msgTypes[96] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5937,118 +6132,136 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x6c, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x7f, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, - 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, - 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, - 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, - 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, - 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, - 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x4b, + 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, + 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, + 0x12, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x22, 0x7f, 0x0a, 0x19, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, + 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x1a, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, + 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, + 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, + 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0x7b, 0x0a, 0x16, 0x52, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x20, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xaa, + 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x5a, + 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, 0x0a, 0x18, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4e, 0x0a, 0x0e, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x52, 0x0a, 0x21, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, - 0x7b, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x20, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x22, 0xaa, 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, - 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, - 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, - 0x4e, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, - 0x52, 0x0a, 0x21, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, - 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, - 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x52, 0x0a, 0x6f, 0x6c, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, - 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, - 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, - 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, - 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, - 0x65, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, - 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, - 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0xc6, 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x12, 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6f, 0x6c, + 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, + 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x65, 0x0a, 0x18, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, + 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -6063,7 +6276,7 @@ func file_vtctldata_proto_rawDescGZIP() []byte { return file_vtctldata_proto_rawDescData } -var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 99) +var file_vtctldata_proto_msgTypes = make([]protoimpl.MessageInfo, 103) var file_vtctldata_proto_goTypes = []interface{}{ (*ExecuteVtctlCommandRequest)(nil), // 0: vtctldata.ExecuteVtctlCommandRequest (*ExecuteVtctlCommandResponse)(nil), // 1: vtctldata.ExecuteVtctlCommandResponse @@ -6138,145 +6351,150 @@ var file_vtctldata_proto_goTypes = []interface{}{ (*PlannedReparentShardResponse)(nil), // 70: vtctldata.PlannedReparentShardResponse (*RebuildVSchemaGraphRequest)(nil), // 71: vtctldata.RebuildVSchemaGraphRequest (*RebuildVSchemaGraphResponse)(nil), // 72: vtctldata.RebuildVSchemaGraphResponse - (*RemoveKeyspaceCellRequest)(nil), // 73: vtctldata.RemoveKeyspaceCellRequest - (*RemoveKeyspaceCellResponse)(nil), // 74: vtctldata.RemoveKeyspaceCellResponse - (*RemoveShardCellRequest)(nil), // 75: vtctldata.RemoveShardCellRequest - (*RemoveShardCellResponse)(nil), // 76: vtctldata.RemoveShardCellResponse - (*ReparentTabletRequest)(nil), // 77: vtctldata.ReparentTabletRequest - (*ReparentTabletResponse)(nil), // 78: vtctldata.ReparentTabletResponse - (*ShardReplicationPositionsRequest)(nil), // 79: vtctldata.ShardReplicationPositionsRequest - (*ShardReplicationPositionsResponse)(nil), // 80: vtctldata.ShardReplicationPositionsResponse - (*TabletExternallyReparentedRequest)(nil), // 81: vtctldata.TabletExternallyReparentedRequest - (*TabletExternallyReparentedResponse)(nil), // 82: vtctldata.TabletExternallyReparentedResponse - (*UpdateCellInfoRequest)(nil), // 83: vtctldata.UpdateCellInfoRequest - (*UpdateCellInfoResponse)(nil), // 84: vtctldata.UpdateCellInfoResponse - (*UpdateCellsAliasRequest)(nil), // 85: vtctldata.UpdateCellsAliasRequest - (*UpdateCellsAliasResponse)(nil), // 86: vtctldata.UpdateCellsAliasResponse - nil, // 87: vtctldata.Workflow.ShardStreamsEntry - (*Workflow_ReplicationLocation)(nil), // 88: vtctldata.Workflow.ReplicationLocation - (*Workflow_ShardStream)(nil), // 89: vtctldata.Workflow.ShardStream - (*Workflow_Stream)(nil), // 90: vtctldata.Workflow.Stream - (*Workflow_Stream_CopyState)(nil), // 91: vtctldata.Workflow.Stream.CopyState - (*Workflow_Stream_Log)(nil), // 92: vtctldata.Workflow.Stream.Log - nil, // 93: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - nil, // 94: vtctldata.GetCellsAliasesResponse.AliasesEntry - nil, // 95: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - nil, // 96: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - nil, // 97: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - nil, // 98: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - (*logutil.Event)(nil), // 99: logutil.Event - (*topodata.Keyspace)(nil), // 100: topodata.Keyspace - (*topodata.Shard)(nil), // 101: topodata.Shard - (*topodata.CellInfo)(nil), // 102: topodata.CellInfo - (*vschema.RoutingRules)(nil), // 103: vschema.RoutingRules - (*vschema.Keyspace)(nil), // 104: vschema.Keyspace - (*topodata.TabletAlias)(nil), // 105: topodata.TabletAlias - (topodata.TabletType)(0), // 106: topodata.TabletType - (*topodata.Tablet)(nil), // 107: topodata.Tablet - (topodata.KeyspaceIdType)(0), // 108: topodata.KeyspaceIdType - (*topodata.Keyspace_ServedFrom)(nil), // 109: topodata.Keyspace.ServedFrom - (topodata.KeyspaceType)(0), // 110: topodata.KeyspaceType - (*vttime.Time)(nil), // 111: vttime.Time - (*vttime.Duration)(nil), // 112: vttime.Duration - (*mysqlctl.BackupInfo)(nil), // 113: mysqlctl.BackupInfo - (*tabletmanagerdata.SchemaDefinition)(nil), // 114: tabletmanagerdata.SchemaDefinition - (*vschema.SrvVSchema)(nil), // 115: vschema.SrvVSchema - (*topodata.CellsAlias)(nil), // 116: topodata.CellsAlias - (*topodata.Shard_TabletControl)(nil), // 117: topodata.Shard.TabletControl - (*binlogdata.BinlogSource)(nil), // 118: binlogdata.BinlogSource - (*topodata.SrvKeyspace)(nil), // 119: topodata.SrvKeyspace - (*replicationdata.Status)(nil), // 120: replicationdata.Status + (*RefreshStateRequest)(nil), // 73: vtctldata.RefreshStateRequest + (*RefreshStateResponse)(nil), // 74: vtctldata.RefreshStateResponse + (*RefreshStateByShardRequest)(nil), // 75: vtctldata.RefreshStateByShardRequest + (*RefreshStateByShardResponse)(nil), // 76: vtctldata.RefreshStateByShardResponse + (*RemoveKeyspaceCellRequest)(nil), // 77: vtctldata.RemoveKeyspaceCellRequest + (*RemoveKeyspaceCellResponse)(nil), // 78: vtctldata.RemoveKeyspaceCellResponse + (*RemoveShardCellRequest)(nil), // 79: vtctldata.RemoveShardCellRequest + (*RemoveShardCellResponse)(nil), // 80: vtctldata.RemoveShardCellResponse + (*ReparentTabletRequest)(nil), // 81: vtctldata.ReparentTabletRequest + (*ReparentTabletResponse)(nil), // 82: vtctldata.ReparentTabletResponse + (*ShardReplicationPositionsRequest)(nil), // 83: vtctldata.ShardReplicationPositionsRequest + (*ShardReplicationPositionsResponse)(nil), // 84: vtctldata.ShardReplicationPositionsResponse + (*TabletExternallyReparentedRequest)(nil), // 85: vtctldata.TabletExternallyReparentedRequest + (*TabletExternallyReparentedResponse)(nil), // 86: vtctldata.TabletExternallyReparentedResponse + (*UpdateCellInfoRequest)(nil), // 87: vtctldata.UpdateCellInfoRequest + (*UpdateCellInfoResponse)(nil), // 88: vtctldata.UpdateCellInfoResponse + (*UpdateCellsAliasRequest)(nil), // 89: vtctldata.UpdateCellsAliasRequest + (*UpdateCellsAliasResponse)(nil), // 90: vtctldata.UpdateCellsAliasResponse + nil, // 91: vtctldata.Workflow.ShardStreamsEntry + (*Workflow_ReplicationLocation)(nil), // 92: vtctldata.Workflow.ReplicationLocation + (*Workflow_ShardStream)(nil), // 93: vtctldata.Workflow.ShardStream + (*Workflow_Stream)(nil), // 94: vtctldata.Workflow.Stream + (*Workflow_Stream_CopyState)(nil), // 95: vtctldata.Workflow.Stream.CopyState + (*Workflow_Stream_Log)(nil), // 96: vtctldata.Workflow.Stream.Log + nil, // 97: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + nil, // 98: vtctldata.GetCellsAliasesResponse.AliasesEntry + nil, // 99: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + nil, // 100: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + nil, // 101: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + nil, // 102: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + (*logutil.Event)(nil), // 103: logutil.Event + (*topodata.Keyspace)(nil), // 104: topodata.Keyspace + (*topodata.Shard)(nil), // 105: topodata.Shard + (*topodata.CellInfo)(nil), // 106: topodata.CellInfo + (*vschema.RoutingRules)(nil), // 107: vschema.RoutingRules + (*vschema.Keyspace)(nil), // 108: vschema.Keyspace + (*topodata.TabletAlias)(nil), // 109: topodata.TabletAlias + (topodata.TabletType)(0), // 110: topodata.TabletType + (*topodata.Tablet)(nil), // 111: topodata.Tablet + (topodata.KeyspaceIdType)(0), // 112: topodata.KeyspaceIdType + (*topodata.Keyspace_ServedFrom)(nil), // 113: topodata.Keyspace.ServedFrom + (topodata.KeyspaceType)(0), // 114: topodata.KeyspaceType + (*vttime.Time)(nil), // 115: vttime.Time + (*vttime.Duration)(nil), // 116: vttime.Duration + (*mysqlctl.BackupInfo)(nil), // 117: mysqlctl.BackupInfo + (*tabletmanagerdata.SchemaDefinition)(nil), // 118: tabletmanagerdata.SchemaDefinition + (*vschema.SrvVSchema)(nil), // 119: vschema.SrvVSchema + (*topodata.CellsAlias)(nil), // 120: topodata.CellsAlias + (*topodata.Shard_TabletControl)(nil), // 121: topodata.Shard.TabletControl + (*binlogdata.BinlogSource)(nil), // 122: binlogdata.BinlogSource + (*topodata.SrvKeyspace)(nil), // 123: topodata.SrvKeyspace + (*replicationdata.Status)(nil), // 124: replicationdata.Status } var file_vtctldata_proto_depIdxs = []int32{ - 99, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event + 103, // 0: vtctldata.ExecuteVtctlCommandResponse.event:type_name -> logutil.Event 2, // 1: vtctldata.MaterializeSettings.table_settings:type_name -> vtctldata.TableMaterializeSettings - 100, // 2: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace - 101, // 3: vtctldata.Shard.shard:type_name -> topodata.Shard - 88, // 4: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation - 88, // 5: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation - 87, // 6: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry - 102, // 7: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 103, // 8: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules - 104, // 9: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace - 104, // 10: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace - 105, // 11: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias - 106, // 12: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType - 107, // 13: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet - 107, // 14: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet - 108, // 15: vtctldata.CreateKeyspaceRequest.sharding_column_type:type_name -> topodata.KeyspaceIdType - 109, // 16: vtctldata.CreateKeyspaceRequest.served_froms:type_name -> topodata.Keyspace.ServedFrom - 110, // 17: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType - 111, // 18: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time + 104, // 2: vtctldata.Keyspace.keyspace:type_name -> topodata.Keyspace + 105, // 3: vtctldata.Shard.shard:type_name -> topodata.Shard + 92, // 4: vtctldata.Workflow.source:type_name -> vtctldata.Workflow.ReplicationLocation + 92, // 5: vtctldata.Workflow.target:type_name -> vtctldata.Workflow.ReplicationLocation + 91, // 6: vtctldata.Workflow.shard_streams:type_name -> vtctldata.Workflow.ShardStreamsEntry + 106, // 7: vtctldata.AddCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 107, // 8: vtctldata.ApplyRoutingRulesRequest.routing_rules:type_name -> vschema.RoutingRules + 108, // 9: vtctldata.ApplyVSchemaRequest.v_schema:type_name -> vschema.Keyspace + 108, // 10: vtctldata.ApplyVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 109, // 11: vtctldata.ChangeTabletTypeRequest.tablet_alias:type_name -> topodata.TabletAlias + 110, // 12: vtctldata.ChangeTabletTypeRequest.db_type:type_name -> topodata.TabletType + 111, // 13: vtctldata.ChangeTabletTypeResponse.before_tablet:type_name -> topodata.Tablet + 111, // 14: vtctldata.ChangeTabletTypeResponse.after_tablet:type_name -> topodata.Tablet + 112, // 15: vtctldata.CreateKeyspaceRequest.sharding_column_type:type_name -> topodata.KeyspaceIdType + 113, // 16: vtctldata.CreateKeyspaceRequest.served_froms:type_name -> topodata.Keyspace.ServedFrom + 114, // 17: vtctldata.CreateKeyspaceRequest.type:type_name -> topodata.KeyspaceType + 115, // 18: vtctldata.CreateKeyspaceRequest.snapshot_time:type_name -> vttime.Time 4, // 19: vtctldata.CreateKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace 4, // 20: vtctldata.CreateShardResponse.keyspace:type_name -> vtctldata.Keyspace 5, // 21: vtctldata.CreateShardResponse.shard:type_name -> vtctldata.Shard 5, // 22: vtctldata.DeleteShardsRequest.shards:type_name -> vtctldata.Shard - 105, // 23: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 105, // 24: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 105, // 25: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias - 112, // 26: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 105, // 27: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 99, // 28: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event - 93, // 29: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry - 113, // 30: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo - 102, // 31: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 94, // 32: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry + 109, // 23: vtctldata.DeleteTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 109, // 24: vtctldata.EmergencyReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 109, // 25: vtctldata.EmergencyReparentShardRequest.ignore_replicas:type_name -> topodata.TabletAlias + 116, // 26: vtctldata.EmergencyReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 109, // 27: vtctldata.EmergencyReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 103, // 28: vtctldata.EmergencyReparentShardResponse.events:type_name -> logutil.Event + 97, // 29: vtctldata.FindAllShardsInKeyspaceResponse.shards:type_name -> vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry + 117, // 30: vtctldata.GetBackupsResponse.backups:type_name -> mysqlctl.BackupInfo + 106, // 31: vtctldata.GetCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 98, // 32: vtctldata.GetCellsAliasesResponse.aliases:type_name -> vtctldata.GetCellsAliasesResponse.AliasesEntry 4, // 33: vtctldata.GetKeyspacesResponse.keyspaces:type_name -> vtctldata.Keyspace 4, // 34: vtctldata.GetKeyspaceResponse.keyspace:type_name -> vtctldata.Keyspace - 103, // 35: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules - 105, // 36: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias - 114, // 37: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition + 107, // 35: vtctldata.GetRoutingRulesResponse.routing_rules:type_name -> vschema.RoutingRules + 109, // 36: vtctldata.GetSchemaRequest.tablet_alias:type_name -> topodata.TabletAlias + 118, // 37: vtctldata.GetSchemaResponse.schema:type_name -> tabletmanagerdata.SchemaDefinition 5, // 38: vtctldata.GetShardResponse.shard:type_name -> vtctldata.Shard - 95, // 39: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry - 115, // 40: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema - 96, // 41: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry - 105, // 42: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias - 107, // 43: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet - 105, // 44: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias - 107, // 45: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet - 104, // 46: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace + 99, // 39: vtctldata.GetSrvKeyspacesResponse.srv_keyspaces:type_name -> vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry + 119, // 40: vtctldata.GetSrvVSchemaResponse.srv_v_schema:type_name -> vschema.SrvVSchema + 100, // 41: vtctldata.GetSrvVSchemasResponse.srv_v_schemas:type_name -> vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry + 109, // 42: vtctldata.GetTabletRequest.tablet_alias:type_name -> topodata.TabletAlias + 111, // 43: vtctldata.GetTabletResponse.tablet:type_name -> topodata.Tablet + 109, // 44: vtctldata.GetTabletsRequest.tablet_aliases:type_name -> topodata.TabletAlias + 111, // 45: vtctldata.GetTabletsResponse.tablets:type_name -> topodata.Tablet + 108, // 46: vtctldata.GetVSchemaResponse.v_schema:type_name -> vschema.Keyspace 6, // 47: vtctldata.GetWorkflowsResponse.workflows:type_name -> vtctldata.Workflow - 105, // 48: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias - 112, // 49: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration - 99, // 50: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event - 105, // 51: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias - 105, // 52: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias - 112, // 53: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration - 105, // 54: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias - 99, // 55: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event - 105, // 56: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias - 105, // 57: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias - 97, // 58: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry - 98, // 59: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry - 105, // 60: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias - 105, // 61: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias - 105, // 62: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias - 102, // 63: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo - 102, // 64: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo - 116, // 65: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias - 116, // 66: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias - 89, // 67: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream - 90, // 68: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream - 117, // 69: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl - 105, // 70: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias - 118, // 71: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource - 111, // 72: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time - 111, // 73: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time - 91, // 74: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState - 92, // 75: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log - 111, // 76: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time - 111, // 77: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time - 5, // 78: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard - 116, // 79: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias - 119, // 80: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace - 115, // 81: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema - 120, // 82: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status - 107, // 83: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet - 84, // [84:84] is the sub-list for method output_type - 84, // [84:84] is the sub-list for method input_type - 84, // [84:84] is the sub-list for extension type_name - 84, // [84:84] is the sub-list for extension extendee - 0, // [0:84] is the sub-list for field type_name + 109, // 48: vtctldata.InitShardPrimaryRequest.primary_elect_tablet_alias:type_name -> topodata.TabletAlias + 116, // 49: vtctldata.InitShardPrimaryRequest.wait_replicas_timeout:type_name -> vttime.Duration + 103, // 50: vtctldata.InitShardPrimaryResponse.events:type_name -> logutil.Event + 109, // 51: vtctldata.PlannedReparentShardRequest.new_primary:type_name -> topodata.TabletAlias + 109, // 52: vtctldata.PlannedReparentShardRequest.avoid_primary:type_name -> topodata.TabletAlias + 116, // 53: vtctldata.PlannedReparentShardRequest.wait_replicas_timeout:type_name -> vttime.Duration + 109, // 54: vtctldata.PlannedReparentShardResponse.promoted_primary:type_name -> topodata.TabletAlias + 103, // 55: vtctldata.PlannedReparentShardResponse.events:type_name -> logutil.Event + 109, // 56: vtctldata.RefreshStateRequest.tablet_alias:type_name -> topodata.TabletAlias + 109, // 57: vtctldata.ReparentTabletRequest.tablet:type_name -> topodata.TabletAlias + 109, // 58: vtctldata.ReparentTabletResponse.primary:type_name -> topodata.TabletAlias + 101, // 59: vtctldata.ShardReplicationPositionsResponse.replication_statuses:type_name -> vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry + 102, // 60: vtctldata.ShardReplicationPositionsResponse.tablet_map:type_name -> vtctldata.ShardReplicationPositionsResponse.TabletMapEntry + 109, // 61: vtctldata.TabletExternallyReparentedRequest.tablet:type_name -> topodata.TabletAlias + 109, // 62: vtctldata.TabletExternallyReparentedResponse.new_primary:type_name -> topodata.TabletAlias + 109, // 63: vtctldata.TabletExternallyReparentedResponse.old_primary:type_name -> topodata.TabletAlias + 106, // 64: vtctldata.UpdateCellInfoRequest.cell_info:type_name -> topodata.CellInfo + 106, // 65: vtctldata.UpdateCellInfoResponse.cell_info:type_name -> topodata.CellInfo + 120, // 66: vtctldata.UpdateCellsAliasRequest.cells_alias:type_name -> topodata.CellsAlias + 120, // 67: vtctldata.UpdateCellsAliasResponse.cells_alias:type_name -> topodata.CellsAlias + 93, // 68: vtctldata.Workflow.ShardStreamsEntry.value:type_name -> vtctldata.Workflow.ShardStream + 94, // 69: vtctldata.Workflow.ShardStream.streams:type_name -> vtctldata.Workflow.Stream + 121, // 70: vtctldata.Workflow.ShardStream.tablet_controls:type_name -> topodata.Shard.TabletControl + 109, // 71: vtctldata.Workflow.Stream.tablet:type_name -> topodata.TabletAlias + 122, // 72: vtctldata.Workflow.Stream.binlog_source:type_name -> binlogdata.BinlogSource + 115, // 73: vtctldata.Workflow.Stream.transaction_timestamp:type_name -> vttime.Time + 115, // 74: vtctldata.Workflow.Stream.time_updated:type_name -> vttime.Time + 95, // 75: vtctldata.Workflow.Stream.copy_states:type_name -> vtctldata.Workflow.Stream.CopyState + 96, // 76: vtctldata.Workflow.Stream.logs:type_name -> vtctldata.Workflow.Stream.Log + 115, // 77: vtctldata.Workflow.Stream.Log.created_at:type_name -> vttime.Time + 115, // 78: vtctldata.Workflow.Stream.Log.updated_at:type_name -> vttime.Time + 5, // 79: vtctldata.FindAllShardsInKeyspaceResponse.ShardsEntry.value:type_name -> vtctldata.Shard + 120, // 80: vtctldata.GetCellsAliasesResponse.AliasesEntry.value:type_name -> topodata.CellsAlias + 123, // 81: vtctldata.GetSrvKeyspacesResponse.SrvKeyspacesEntry.value:type_name -> topodata.SrvKeyspace + 119, // 82: vtctldata.GetSrvVSchemasResponse.SrvVSchemasEntry.value:type_name -> vschema.SrvVSchema + 124, // 83: vtctldata.ShardReplicationPositionsResponse.ReplicationStatusesEntry.value:type_name -> replicationdata.Status + 111, // 84: vtctldata.ShardReplicationPositionsResponse.TabletMapEntry.value:type_name -> topodata.Tablet + 85, // [85:85] is the sub-list for method output_type + 85, // [85:85] is the sub-list for method input_type + 85, // [85:85] is the sub-list for extension type_name + 85, // [85:85] is the sub-list for extension extendee + 0, // [0:85] is the sub-list for field type_name } func init() { file_vtctldata_proto_init() } @@ -7162,7 +7380,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveKeyspaceCellRequest); i { + switch v := v.(*RefreshStateRequest); i { case 0: return &v.state case 1: @@ -7174,7 +7392,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveKeyspaceCellResponse); i { + switch v := v.(*RefreshStateResponse); i { case 0: return &v.state case 1: @@ -7186,7 +7404,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveShardCellRequest); i { + switch v := v.(*RefreshStateByShardRequest); i { case 0: return &v.state case 1: @@ -7198,7 +7416,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RemoveShardCellResponse); i { + switch v := v.(*RefreshStateByShardResponse); i { case 0: return &v.state case 1: @@ -7210,7 +7428,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReparentTabletRequest); i { + switch v := v.(*RemoveKeyspaceCellRequest); i { case 0: return &v.state case 1: @@ -7222,7 +7440,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReparentTabletResponse); i { + switch v := v.(*RemoveKeyspaceCellResponse); i { case 0: return &v.state case 1: @@ -7234,7 +7452,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShardReplicationPositionsRequest); i { + switch v := v.(*RemoveShardCellRequest); i { case 0: return &v.state case 1: @@ -7246,7 +7464,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ShardReplicationPositionsResponse); i { + switch v := v.(*RemoveShardCellResponse); i { case 0: return &v.state case 1: @@ -7258,7 +7476,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TabletExternallyReparentedRequest); i { + switch v := v.(*ReparentTabletRequest); i { case 0: return &v.state case 1: @@ -7270,7 +7488,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TabletExternallyReparentedResponse); i { + switch v := v.(*ReparentTabletResponse); i { case 0: return &v.state case 1: @@ -7282,7 +7500,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateCellInfoRequest); i { + switch v := v.(*ShardReplicationPositionsRequest); i { case 0: return &v.state case 1: @@ -7294,7 +7512,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateCellInfoResponse); i { + switch v := v.(*ShardReplicationPositionsResponse); i { case 0: return &v.state case 1: @@ -7306,7 +7524,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateCellsAliasRequest); i { + switch v := v.(*TabletExternallyReparentedRequest); i { case 0: return &v.state case 1: @@ -7318,7 +7536,19 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateCellsAliasResponse); i { + switch v := v.(*TabletExternallyReparentedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateCellInfoRequest); i { case 0: return &v.state case 1: @@ -7330,7 +7560,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workflow_ReplicationLocation); i { + switch v := v.(*UpdateCellInfoResponse); i { case 0: return &v.state case 1: @@ -7342,7 +7572,7 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Workflow_ShardStream); i { + switch v := v.(*UpdateCellsAliasRequest); i { case 0: return &v.state case 1: @@ -7354,6 +7584,42 @@ func file_vtctldata_proto_init() { } } file_vtctldata_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateCellsAliasResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_ReplicationLocation); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Workflow_ShardStream); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_vtctldata_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream); i { case 0: return &v.state @@ -7365,7 +7631,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_CopyState); i { case 0: return &v.state @@ -7377,7 +7643,7 @@ func file_vtctldata_proto_init() { return nil } } - file_vtctldata_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} { + file_vtctldata_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Workflow_Stream_Log); i { case 0: return &v.state @@ -7396,7 +7662,7 @@ func file_vtctldata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_vtctldata_proto_rawDesc, NumEnums: 0, - NumMessages: 99, + NumMessages: 103, NumExtensions: 0, NumServices: 0, }, diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index abd998d99d4..8e721925cb9 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -4260,6 +4260,183 @@ func (m *RebuildVSchemaGraphResponse) MarshalToSizedBufferVT(dAtA []byte) (int, return len(dAtA) - i, nil } +func (m *RefreshStateRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefreshStateRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RefreshStateRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.TabletAlias != nil { + { + size, err := m.TabletAlias.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RefreshStateResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefreshStateResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RefreshStateResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *RefreshStateByShardRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefreshStateByShardRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RefreshStateByShardRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Cells) > 0 { + for iNdEx := len(m.Cells) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Cells[iNdEx]) + copy(dAtA[i:], m.Cells[iNdEx]) + i = encodeVarint(dAtA, i, uint64(len(m.Cells[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Shard) > 0 { + i -= len(m.Shard) + copy(dAtA[i:], m.Shard) + i = encodeVarint(dAtA, i, uint64(len(m.Shard))) + i-- + dAtA[i] = 0x12 + } + if len(m.Keyspace) > 0 { + i -= len(m.Keyspace) + copy(dAtA[i:], m.Keyspace) + i = encodeVarint(dAtA, i, uint64(len(m.Keyspace))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RefreshStateByShardResponse) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefreshStateByShardResponse) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RefreshStateByShardResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.IsPartialRefresh { + i-- + if m.IsPartialRefresh { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *RemoveKeyspaceCellRequest) MarshalVT() (dAtA []byte, err error) { if m == nil { return nil, nil @@ -6713,6 +6890,75 @@ func (m *RebuildVSchemaGraphResponse) SizeVT() (n int) { return n } +func (m *RefreshStateRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TabletAlias != nil { + l = m.TabletAlias.SizeVT() + n += 1 + l + sov(uint64(l)) + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *RefreshStateResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *RefreshStateByShardRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Keyspace) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.Shard) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if len(m.Cells) > 0 { + for _, s := range m.Cells { + l = len(s) + n += 1 + l + sov(uint64(l)) + } + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + +func (m *RefreshStateByShardResponse) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IsPartialRefresh { + n += 2 + } + if m.unknownFields != nil { + n += len(m.unknownFields) + } + return n +} + func (m *RemoveKeyspaceCellRequest) SizeVT() (n int) { if m == nil { return 0 @@ -16665,6 +16911,362 @@ func (m *RebuildVSchemaGraphResponse) UnmarshalVT(dAtA []byte) error { } return nil } +func (m *RefreshStateRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RefreshStateRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RefreshStateRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TabletAlias", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TabletAlias == nil { + m.TabletAlias = &topodata.TabletAlias{} + } + if err := m.TabletAlias.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RefreshStateResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RefreshStateResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RefreshStateResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RefreshStateByShardRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RefreshStateByShardRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RefreshStateByShardRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shard", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shard = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cells", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cells = append(m.Cells, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RefreshStateByShardResponse) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RefreshStateByShardResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RefreshStateByShardResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsPartialRefresh", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsPartialRefresh = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *RemoveKeyspaceCellRequest) UnmarshalVT(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/go/vt/proto/vtctlservice/vtctlservice.pb.go b/go/vt/proto/vtctlservice/vtctlservice.pb.go index 5085e544edd..d334c486451 100644 --- a/go/vt/proto/vtctlservice/vtctlservice.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice.pb.go @@ -51,7 +51,7 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0xaf, 0x1c, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, + 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x32, 0xea, 0x1d, 0x0a, 0x06, 0x56, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x12, 0x4e, 0x0a, 0x0b, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, @@ -234,54 +234,66 @@ var file_vtctlservice_proto_rawDesc = []byte{ 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x63, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x5a, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, - 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, - 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x57, 0x0a, 0x0e, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x19, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x1a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, + 0x51, 0x0a, 0x0c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x1e, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x66, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, + 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x26, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x12, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, + 0x12, 0x24, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x5a, 0x0a, 0x0f, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, + 0x6c, 0x6c, 0x12, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, + 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x52, + 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x12, 0x20, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x19, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x2b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, + 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, + 0x0a, 0x1a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x2c, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, - 0x64, 0x12, 0x2c, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x2d, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x57, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x22, 0x2e, + 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x23, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, 0x65, - 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, - 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x21, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, + 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x22, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0x2b, 0x5a, 0x29, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, + 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var file_vtctlservice_proto_goTypes = []interface{}{ @@ -319,54 +331,58 @@ var file_vtctlservice_proto_goTypes = []interface{}{ (*vtctldata.InitShardPrimaryRequest)(nil), // 31: vtctldata.InitShardPrimaryRequest (*vtctldata.PlannedReparentShardRequest)(nil), // 32: vtctldata.PlannedReparentShardRequest (*vtctldata.RebuildVSchemaGraphRequest)(nil), // 33: vtctldata.RebuildVSchemaGraphRequest - (*vtctldata.RemoveKeyspaceCellRequest)(nil), // 34: vtctldata.RemoveKeyspaceCellRequest - (*vtctldata.RemoveShardCellRequest)(nil), // 35: vtctldata.RemoveShardCellRequest - (*vtctldata.ReparentTabletRequest)(nil), // 36: vtctldata.ReparentTabletRequest - (*vtctldata.ShardReplicationPositionsRequest)(nil), // 37: vtctldata.ShardReplicationPositionsRequest - (*vtctldata.TabletExternallyReparentedRequest)(nil), // 38: vtctldata.TabletExternallyReparentedRequest - (*vtctldata.UpdateCellInfoRequest)(nil), // 39: vtctldata.UpdateCellInfoRequest - (*vtctldata.UpdateCellsAliasRequest)(nil), // 40: vtctldata.UpdateCellsAliasRequest - (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 41: vtctldata.ExecuteVtctlCommandResponse - (*vtctldata.AddCellInfoResponse)(nil), // 42: vtctldata.AddCellInfoResponse - (*vtctldata.AddCellsAliasResponse)(nil), // 43: vtctldata.AddCellsAliasResponse - (*vtctldata.ApplyRoutingRulesResponse)(nil), // 44: vtctldata.ApplyRoutingRulesResponse - (*vtctldata.ApplyVSchemaResponse)(nil), // 45: vtctldata.ApplyVSchemaResponse - (*vtctldata.ChangeTabletTypeResponse)(nil), // 46: vtctldata.ChangeTabletTypeResponse - (*vtctldata.CreateKeyspaceResponse)(nil), // 47: vtctldata.CreateKeyspaceResponse - (*vtctldata.CreateShardResponse)(nil), // 48: vtctldata.CreateShardResponse - (*vtctldata.DeleteCellInfoResponse)(nil), // 49: vtctldata.DeleteCellInfoResponse - (*vtctldata.DeleteCellsAliasResponse)(nil), // 50: vtctldata.DeleteCellsAliasResponse - (*vtctldata.DeleteKeyspaceResponse)(nil), // 51: vtctldata.DeleteKeyspaceResponse - (*vtctldata.DeleteShardsResponse)(nil), // 52: vtctldata.DeleteShardsResponse - (*vtctldata.DeleteTabletsResponse)(nil), // 53: vtctldata.DeleteTabletsResponse - (*vtctldata.EmergencyReparentShardResponse)(nil), // 54: vtctldata.EmergencyReparentShardResponse - (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 55: vtctldata.FindAllShardsInKeyspaceResponse - (*vtctldata.GetBackupsResponse)(nil), // 56: vtctldata.GetBackupsResponse - (*vtctldata.GetCellInfoResponse)(nil), // 57: vtctldata.GetCellInfoResponse - (*vtctldata.GetCellInfoNamesResponse)(nil), // 58: vtctldata.GetCellInfoNamesResponse - (*vtctldata.GetCellsAliasesResponse)(nil), // 59: vtctldata.GetCellsAliasesResponse - (*vtctldata.GetKeyspaceResponse)(nil), // 60: vtctldata.GetKeyspaceResponse - (*vtctldata.GetKeyspacesResponse)(nil), // 61: vtctldata.GetKeyspacesResponse - (*vtctldata.GetRoutingRulesResponse)(nil), // 62: vtctldata.GetRoutingRulesResponse - (*vtctldata.GetSchemaResponse)(nil), // 63: vtctldata.GetSchemaResponse - (*vtctldata.GetShardResponse)(nil), // 64: vtctldata.GetShardResponse - (*vtctldata.GetSrvKeyspacesResponse)(nil), // 65: vtctldata.GetSrvKeyspacesResponse - (*vtctldata.GetSrvVSchemaResponse)(nil), // 66: vtctldata.GetSrvVSchemaResponse - (*vtctldata.GetSrvVSchemasResponse)(nil), // 67: vtctldata.GetSrvVSchemasResponse - (*vtctldata.GetTabletResponse)(nil), // 68: vtctldata.GetTabletResponse - (*vtctldata.GetTabletsResponse)(nil), // 69: vtctldata.GetTabletsResponse - (*vtctldata.GetVSchemaResponse)(nil), // 70: vtctldata.GetVSchemaResponse - (*vtctldata.GetWorkflowsResponse)(nil), // 71: vtctldata.GetWorkflowsResponse - (*vtctldata.InitShardPrimaryResponse)(nil), // 72: vtctldata.InitShardPrimaryResponse - (*vtctldata.PlannedReparentShardResponse)(nil), // 73: vtctldata.PlannedReparentShardResponse - (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 74: vtctldata.RebuildVSchemaGraphResponse - (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 75: vtctldata.RemoveKeyspaceCellResponse - (*vtctldata.RemoveShardCellResponse)(nil), // 76: vtctldata.RemoveShardCellResponse - (*vtctldata.ReparentTabletResponse)(nil), // 77: vtctldata.ReparentTabletResponse - (*vtctldata.ShardReplicationPositionsResponse)(nil), // 78: vtctldata.ShardReplicationPositionsResponse - (*vtctldata.TabletExternallyReparentedResponse)(nil), // 79: vtctldata.TabletExternallyReparentedResponse - (*vtctldata.UpdateCellInfoResponse)(nil), // 80: vtctldata.UpdateCellInfoResponse - (*vtctldata.UpdateCellsAliasResponse)(nil), // 81: vtctldata.UpdateCellsAliasResponse + (*vtctldata.RefreshStateRequest)(nil), // 34: vtctldata.RefreshStateRequest + (*vtctldata.RefreshStateByShardRequest)(nil), // 35: vtctldata.RefreshStateByShardRequest + (*vtctldata.RemoveKeyspaceCellRequest)(nil), // 36: vtctldata.RemoveKeyspaceCellRequest + (*vtctldata.RemoveShardCellRequest)(nil), // 37: vtctldata.RemoveShardCellRequest + (*vtctldata.ReparentTabletRequest)(nil), // 38: vtctldata.ReparentTabletRequest + (*vtctldata.ShardReplicationPositionsRequest)(nil), // 39: vtctldata.ShardReplicationPositionsRequest + (*vtctldata.TabletExternallyReparentedRequest)(nil), // 40: vtctldata.TabletExternallyReparentedRequest + (*vtctldata.UpdateCellInfoRequest)(nil), // 41: vtctldata.UpdateCellInfoRequest + (*vtctldata.UpdateCellsAliasRequest)(nil), // 42: vtctldata.UpdateCellsAliasRequest + (*vtctldata.ExecuteVtctlCommandResponse)(nil), // 43: vtctldata.ExecuteVtctlCommandResponse + (*vtctldata.AddCellInfoResponse)(nil), // 44: vtctldata.AddCellInfoResponse + (*vtctldata.AddCellsAliasResponse)(nil), // 45: vtctldata.AddCellsAliasResponse + (*vtctldata.ApplyRoutingRulesResponse)(nil), // 46: vtctldata.ApplyRoutingRulesResponse + (*vtctldata.ApplyVSchemaResponse)(nil), // 47: vtctldata.ApplyVSchemaResponse + (*vtctldata.ChangeTabletTypeResponse)(nil), // 48: vtctldata.ChangeTabletTypeResponse + (*vtctldata.CreateKeyspaceResponse)(nil), // 49: vtctldata.CreateKeyspaceResponse + (*vtctldata.CreateShardResponse)(nil), // 50: vtctldata.CreateShardResponse + (*vtctldata.DeleteCellInfoResponse)(nil), // 51: vtctldata.DeleteCellInfoResponse + (*vtctldata.DeleteCellsAliasResponse)(nil), // 52: vtctldata.DeleteCellsAliasResponse + (*vtctldata.DeleteKeyspaceResponse)(nil), // 53: vtctldata.DeleteKeyspaceResponse + (*vtctldata.DeleteShardsResponse)(nil), // 54: vtctldata.DeleteShardsResponse + (*vtctldata.DeleteTabletsResponse)(nil), // 55: vtctldata.DeleteTabletsResponse + (*vtctldata.EmergencyReparentShardResponse)(nil), // 56: vtctldata.EmergencyReparentShardResponse + (*vtctldata.FindAllShardsInKeyspaceResponse)(nil), // 57: vtctldata.FindAllShardsInKeyspaceResponse + (*vtctldata.GetBackupsResponse)(nil), // 58: vtctldata.GetBackupsResponse + (*vtctldata.GetCellInfoResponse)(nil), // 59: vtctldata.GetCellInfoResponse + (*vtctldata.GetCellInfoNamesResponse)(nil), // 60: vtctldata.GetCellInfoNamesResponse + (*vtctldata.GetCellsAliasesResponse)(nil), // 61: vtctldata.GetCellsAliasesResponse + (*vtctldata.GetKeyspaceResponse)(nil), // 62: vtctldata.GetKeyspaceResponse + (*vtctldata.GetKeyspacesResponse)(nil), // 63: vtctldata.GetKeyspacesResponse + (*vtctldata.GetRoutingRulesResponse)(nil), // 64: vtctldata.GetRoutingRulesResponse + (*vtctldata.GetSchemaResponse)(nil), // 65: vtctldata.GetSchemaResponse + (*vtctldata.GetShardResponse)(nil), // 66: vtctldata.GetShardResponse + (*vtctldata.GetSrvKeyspacesResponse)(nil), // 67: vtctldata.GetSrvKeyspacesResponse + (*vtctldata.GetSrvVSchemaResponse)(nil), // 68: vtctldata.GetSrvVSchemaResponse + (*vtctldata.GetSrvVSchemasResponse)(nil), // 69: vtctldata.GetSrvVSchemasResponse + (*vtctldata.GetTabletResponse)(nil), // 70: vtctldata.GetTabletResponse + (*vtctldata.GetTabletsResponse)(nil), // 71: vtctldata.GetTabletsResponse + (*vtctldata.GetVSchemaResponse)(nil), // 72: vtctldata.GetVSchemaResponse + (*vtctldata.GetWorkflowsResponse)(nil), // 73: vtctldata.GetWorkflowsResponse + (*vtctldata.InitShardPrimaryResponse)(nil), // 74: vtctldata.InitShardPrimaryResponse + (*vtctldata.PlannedReparentShardResponse)(nil), // 75: vtctldata.PlannedReparentShardResponse + (*vtctldata.RebuildVSchemaGraphResponse)(nil), // 76: vtctldata.RebuildVSchemaGraphResponse + (*vtctldata.RefreshStateResponse)(nil), // 77: vtctldata.RefreshStateResponse + (*vtctldata.RefreshStateByShardResponse)(nil), // 78: vtctldata.RefreshStateByShardResponse + (*vtctldata.RemoveKeyspaceCellResponse)(nil), // 79: vtctldata.RemoveKeyspaceCellResponse + (*vtctldata.RemoveShardCellResponse)(nil), // 80: vtctldata.RemoveShardCellResponse + (*vtctldata.ReparentTabletResponse)(nil), // 81: vtctldata.ReparentTabletResponse + (*vtctldata.ShardReplicationPositionsResponse)(nil), // 82: vtctldata.ShardReplicationPositionsResponse + (*vtctldata.TabletExternallyReparentedResponse)(nil), // 83: vtctldata.TabletExternallyReparentedResponse + (*vtctldata.UpdateCellInfoResponse)(nil), // 84: vtctldata.UpdateCellInfoResponse + (*vtctldata.UpdateCellsAliasResponse)(nil), // 85: vtctldata.UpdateCellsAliasResponse } var file_vtctlservice_proto_depIdxs = []int32{ 0, // 0: vtctlservice.Vtctl.ExecuteVtctlCommand:input_type -> vtctldata.ExecuteVtctlCommandRequest @@ -403,56 +419,60 @@ var file_vtctlservice_proto_depIdxs = []int32{ 31, // 31: vtctlservice.Vtctld.InitShardPrimary:input_type -> vtctldata.InitShardPrimaryRequest 32, // 32: vtctlservice.Vtctld.PlannedReparentShard:input_type -> vtctldata.PlannedReparentShardRequest 33, // 33: vtctlservice.Vtctld.RebuildVSchemaGraph:input_type -> vtctldata.RebuildVSchemaGraphRequest - 34, // 34: vtctlservice.Vtctld.RemoveKeyspaceCell:input_type -> vtctldata.RemoveKeyspaceCellRequest - 35, // 35: vtctlservice.Vtctld.RemoveShardCell:input_type -> vtctldata.RemoveShardCellRequest - 36, // 36: vtctlservice.Vtctld.ReparentTablet:input_type -> vtctldata.ReparentTabletRequest - 37, // 37: vtctlservice.Vtctld.ShardReplicationPositions:input_type -> vtctldata.ShardReplicationPositionsRequest - 38, // 38: vtctlservice.Vtctld.TabletExternallyReparented:input_type -> vtctldata.TabletExternallyReparentedRequest - 39, // 39: vtctlservice.Vtctld.UpdateCellInfo:input_type -> vtctldata.UpdateCellInfoRequest - 40, // 40: vtctlservice.Vtctld.UpdateCellsAlias:input_type -> vtctldata.UpdateCellsAliasRequest - 41, // 41: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse - 42, // 42: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse - 43, // 43: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse - 44, // 44: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse - 45, // 45: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse - 46, // 46: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse - 47, // 47: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse - 48, // 48: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse - 49, // 49: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse - 50, // 50: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse - 51, // 51: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse - 52, // 52: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse - 53, // 53: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse - 54, // 54: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse - 55, // 55: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse - 56, // 56: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse - 57, // 57: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse - 58, // 58: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse - 59, // 59: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse - 60, // 60: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse - 61, // 61: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse - 62, // 62: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse - 63, // 63: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse - 64, // 64: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse - 65, // 65: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse - 66, // 66: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse - 67, // 67: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse - 68, // 68: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse - 69, // 69: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse - 70, // 70: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse - 71, // 71: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse - 72, // 72: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse - 73, // 73: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse - 74, // 74: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse - 75, // 75: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse - 76, // 76: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse - 77, // 77: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse - 78, // 78: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse - 79, // 79: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse - 80, // 80: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse - 81, // 81: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse - 41, // [41:82] is the sub-list for method output_type - 0, // [0:41] is the sub-list for method input_type + 34, // 34: vtctlservice.Vtctld.RefreshState:input_type -> vtctldata.RefreshStateRequest + 35, // 35: vtctlservice.Vtctld.RefreshStateByShard:input_type -> vtctldata.RefreshStateByShardRequest + 36, // 36: vtctlservice.Vtctld.RemoveKeyspaceCell:input_type -> vtctldata.RemoveKeyspaceCellRequest + 37, // 37: vtctlservice.Vtctld.RemoveShardCell:input_type -> vtctldata.RemoveShardCellRequest + 38, // 38: vtctlservice.Vtctld.ReparentTablet:input_type -> vtctldata.ReparentTabletRequest + 39, // 39: vtctlservice.Vtctld.ShardReplicationPositions:input_type -> vtctldata.ShardReplicationPositionsRequest + 40, // 40: vtctlservice.Vtctld.TabletExternallyReparented:input_type -> vtctldata.TabletExternallyReparentedRequest + 41, // 41: vtctlservice.Vtctld.UpdateCellInfo:input_type -> vtctldata.UpdateCellInfoRequest + 42, // 42: vtctlservice.Vtctld.UpdateCellsAlias:input_type -> vtctldata.UpdateCellsAliasRequest + 43, // 43: vtctlservice.Vtctl.ExecuteVtctlCommand:output_type -> vtctldata.ExecuteVtctlCommandResponse + 44, // 44: vtctlservice.Vtctld.AddCellInfo:output_type -> vtctldata.AddCellInfoResponse + 45, // 45: vtctlservice.Vtctld.AddCellsAlias:output_type -> vtctldata.AddCellsAliasResponse + 46, // 46: vtctlservice.Vtctld.ApplyRoutingRules:output_type -> vtctldata.ApplyRoutingRulesResponse + 47, // 47: vtctlservice.Vtctld.ApplyVSchema:output_type -> vtctldata.ApplyVSchemaResponse + 48, // 48: vtctlservice.Vtctld.ChangeTabletType:output_type -> vtctldata.ChangeTabletTypeResponse + 49, // 49: vtctlservice.Vtctld.CreateKeyspace:output_type -> vtctldata.CreateKeyspaceResponse + 50, // 50: vtctlservice.Vtctld.CreateShard:output_type -> vtctldata.CreateShardResponse + 51, // 51: vtctlservice.Vtctld.DeleteCellInfo:output_type -> vtctldata.DeleteCellInfoResponse + 52, // 52: vtctlservice.Vtctld.DeleteCellsAlias:output_type -> vtctldata.DeleteCellsAliasResponse + 53, // 53: vtctlservice.Vtctld.DeleteKeyspace:output_type -> vtctldata.DeleteKeyspaceResponse + 54, // 54: vtctlservice.Vtctld.DeleteShards:output_type -> vtctldata.DeleteShardsResponse + 55, // 55: vtctlservice.Vtctld.DeleteTablets:output_type -> vtctldata.DeleteTabletsResponse + 56, // 56: vtctlservice.Vtctld.EmergencyReparentShard:output_type -> vtctldata.EmergencyReparentShardResponse + 57, // 57: vtctlservice.Vtctld.FindAllShardsInKeyspace:output_type -> vtctldata.FindAllShardsInKeyspaceResponse + 58, // 58: vtctlservice.Vtctld.GetBackups:output_type -> vtctldata.GetBackupsResponse + 59, // 59: vtctlservice.Vtctld.GetCellInfo:output_type -> vtctldata.GetCellInfoResponse + 60, // 60: vtctlservice.Vtctld.GetCellInfoNames:output_type -> vtctldata.GetCellInfoNamesResponse + 61, // 61: vtctlservice.Vtctld.GetCellsAliases:output_type -> vtctldata.GetCellsAliasesResponse + 62, // 62: vtctlservice.Vtctld.GetKeyspace:output_type -> vtctldata.GetKeyspaceResponse + 63, // 63: vtctlservice.Vtctld.GetKeyspaces:output_type -> vtctldata.GetKeyspacesResponse + 64, // 64: vtctlservice.Vtctld.GetRoutingRules:output_type -> vtctldata.GetRoutingRulesResponse + 65, // 65: vtctlservice.Vtctld.GetSchema:output_type -> vtctldata.GetSchemaResponse + 66, // 66: vtctlservice.Vtctld.GetShard:output_type -> vtctldata.GetShardResponse + 67, // 67: vtctlservice.Vtctld.GetSrvKeyspaces:output_type -> vtctldata.GetSrvKeyspacesResponse + 68, // 68: vtctlservice.Vtctld.GetSrvVSchema:output_type -> vtctldata.GetSrvVSchemaResponse + 69, // 69: vtctlservice.Vtctld.GetSrvVSchemas:output_type -> vtctldata.GetSrvVSchemasResponse + 70, // 70: vtctlservice.Vtctld.GetTablet:output_type -> vtctldata.GetTabletResponse + 71, // 71: vtctlservice.Vtctld.GetTablets:output_type -> vtctldata.GetTabletsResponse + 72, // 72: vtctlservice.Vtctld.GetVSchema:output_type -> vtctldata.GetVSchemaResponse + 73, // 73: vtctlservice.Vtctld.GetWorkflows:output_type -> vtctldata.GetWorkflowsResponse + 74, // 74: vtctlservice.Vtctld.InitShardPrimary:output_type -> vtctldata.InitShardPrimaryResponse + 75, // 75: vtctlservice.Vtctld.PlannedReparentShard:output_type -> vtctldata.PlannedReparentShardResponse + 76, // 76: vtctlservice.Vtctld.RebuildVSchemaGraph:output_type -> vtctldata.RebuildVSchemaGraphResponse + 77, // 77: vtctlservice.Vtctld.RefreshState:output_type -> vtctldata.RefreshStateResponse + 78, // 78: vtctlservice.Vtctld.RefreshStateByShard:output_type -> vtctldata.RefreshStateByShardResponse + 79, // 79: vtctlservice.Vtctld.RemoveKeyspaceCell:output_type -> vtctldata.RemoveKeyspaceCellResponse + 80, // 80: vtctlservice.Vtctld.RemoveShardCell:output_type -> vtctldata.RemoveShardCellResponse + 81, // 81: vtctlservice.Vtctld.ReparentTablet:output_type -> vtctldata.ReparentTabletResponse + 82, // 82: vtctlservice.Vtctld.ShardReplicationPositions:output_type -> vtctldata.ShardReplicationPositionsResponse + 83, // 83: vtctlservice.Vtctld.TabletExternallyReparented:output_type -> vtctldata.TabletExternallyReparentedResponse + 84, // 84: vtctlservice.Vtctld.UpdateCellInfo:output_type -> vtctldata.UpdateCellInfoResponse + 85, // 85: vtctlservice.Vtctld.UpdateCellsAlias:output_type -> vtctldata.UpdateCellsAliasResponse + 43, // [43:86] is the sub-list for method output_type + 0, // [0:43] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go index 1b548d562d9..55979760d59 100644 --- a/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go +++ b/go/vt/proto/vtctlservice/vtctlservice_grpc.pb.go @@ -237,6 +237,10 @@ type VtctldClient interface { // VSchema objects in the provided cells (or all cells in the topo none // provided). RebuildVSchemaGraph(ctx context.Context, in *vtctldata.RebuildVSchemaGraphRequest, opts ...grpc.CallOption) (*vtctldata.RebuildVSchemaGraphResponse, error) + // RefreshState reloads the tablet record on the specified tablet. + RefreshState(ctx context.Context, in *vtctldata.RefreshStateRequest, opts ...grpc.CallOption) (*vtctldata.RefreshStateResponse, error) + // RefreshStateByShard calls RefreshState on all the tablets in the given shard. + RefreshStateByShard(ctx context.Context, in *vtctldata.RefreshStateByShardRequest, opts ...grpc.CallOption) (*vtctldata.RefreshStateByShardResponse, error) // RemoveKeyspaceCell removes the specified cell from the Cells list for all // shards in the specified keyspace, as well as from the SrvKeyspace for that // keyspace in that cell. @@ -576,6 +580,24 @@ func (c *vtctldClient) RebuildVSchemaGraph(ctx context.Context, in *vtctldata.Re return out, nil } +func (c *vtctldClient) RefreshState(ctx context.Context, in *vtctldata.RefreshStateRequest, opts ...grpc.CallOption) (*vtctldata.RefreshStateResponse, error) { + out := new(vtctldata.RefreshStateResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/RefreshState", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *vtctldClient) RefreshStateByShard(ctx context.Context, in *vtctldata.RefreshStateByShardRequest, opts ...grpc.CallOption) (*vtctldata.RefreshStateByShardResponse, error) { + out := new(vtctldata.RefreshStateByShardResponse) + err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/RefreshStateByShard", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *vtctldClient) RemoveKeyspaceCell(ctx context.Context, in *vtctldata.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldata.RemoveKeyspaceCellResponse, error) { out := new(vtctldata.RemoveKeyspaceCellResponse) err := c.cc.Invoke(ctx, "/vtctlservice.Vtctld/RemoveKeyspaceCell", in, out, opts...) @@ -748,6 +770,10 @@ type VtctldServer interface { // VSchema objects in the provided cells (or all cells in the topo none // provided). RebuildVSchemaGraph(context.Context, *vtctldata.RebuildVSchemaGraphRequest) (*vtctldata.RebuildVSchemaGraphResponse, error) + // RefreshState reloads the tablet record on the specified tablet. + RefreshState(context.Context, *vtctldata.RefreshStateRequest) (*vtctldata.RefreshStateResponse, error) + // RefreshStateByShard calls RefreshState on all the tablets in the given shard. + RefreshStateByShard(context.Context, *vtctldata.RefreshStateByShardRequest) (*vtctldata.RefreshStateByShardResponse, error) // RemoveKeyspaceCell removes the specified cell from the Cells list for all // shards in the specified keyspace, as well as from the SrvKeyspace for that // keyspace in that cell. @@ -886,6 +912,12 @@ func (UnimplementedVtctldServer) PlannedReparentShard(context.Context, *vtctldat func (UnimplementedVtctldServer) RebuildVSchemaGraph(context.Context, *vtctldata.RebuildVSchemaGraphRequest) (*vtctldata.RebuildVSchemaGraphResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RebuildVSchemaGraph not implemented") } +func (UnimplementedVtctldServer) RefreshState(context.Context, *vtctldata.RefreshStateRequest) (*vtctldata.RefreshStateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RefreshState not implemented") +} +func (UnimplementedVtctldServer) RefreshStateByShard(context.Context, *vtctldata.RefreshStateByShardRequest) (*vtctldata.RefreshStateByShardResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RefreshStateByShard not implemented") +} func (UnimplementedVtctldServer) RemoveKeyspaceCell(context.Context, *vtctldata.RemoveKeyspaceCellRequest) (*vtctldata.RemoveKeyspaceCellResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RemoveKeyspaceCell not implemented") } @@ -1514,6 +1546,42 @@ func _Vtctld_RebuildVSchemaGraph_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _Vtctld_RefreshState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.RefreshStateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).RefreshState(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/RefreshState", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).RefreshState(ctx, req.(*vtctldata.RefreshStateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Vtctld_RefreshStateByShard_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(vtctldata.RefreshStateByShardRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(VtctldServer).RefreshStateByShard(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/vtctlservice.Vtctld/RefreshStateByShard", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(VtctldServer).RefreshStateByShard(ctx, req.(*vtctldata.RefreshStateByShardRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Vtctld_RemoveKeyspaceCell_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(vtctldata.RemoveKeyspaceCellRequest) if err := dec(in); err != nil { @@ -1779,6 +1847,14 @@ var Vtctld_ServiceDesc = grpc.ServiceDesc{ MethodName: "RebuildVSchemaGraph", Handler: _Vtctld_RebuildVSchemaGraph_Handler, }, + { + MethodName: "RefreshState", + Handler: _Vtctld_RefreshState_Handler, + }, + { + MethodName: "RefreshStateByShard", + Handler: _Vtctld_RefreshStateByShard_Handler, + }, { MethodName: "RemoveKeyspaceCell", Handler: _Vtctld_RemoveKeyspaceCell_Handler, diff --git a/go/vt/vtctl/grpcvtctldclient/client_gen.go b/go/vt/vtctl/grpcvtctldclient/client_gen.go index 4057b14994a..076b4d87b78 100644 --- a/go/vt/vtctl/grpcvtctldclient/client_gen.go +++ b/go/vt/vtctl/grpcvtctldclient/client_gen.go @@ -325,6 +325,24 @@ func (client *gRPCVtctldClient) RebuildVSchemaGraph(ctx context.Context, in *vtc return client.c.RebuildVSchemaGraph(ctx, in, opts...) } +// RefreshState is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) RefreshState(ctx context.Context, in *vtctldatapb.RefreshStateRequest, opts ...grpc.CallOption) (*vtctldatapb.RefreshStateResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.RefreshState(ctx, in, opts...) +} + +// RefreshStateByShard is part of the vtctlservicepb.VtctldClient interface. +func (client *gRPCVtctldClient) RefreshStateByShard(ctx context.Context, in *vtctldatapb.RefreshStateByShardRequest, opts ...grpc.CallOption) (*vtctldatapb.RefreshStateByShardResponse, error) { + if client.c == nil { + return nil, status.Error(codes.Unavailable, connClosedMsg) + } + + return client.c.RefreshStateByShard(ctx, in, opts...) +} + // RemoveKeyspaceCell is part of the vtctlservicepb.VtctldClient interface. func (client *gRPCVtctldClient) RemoveKeyspaceCell(ctx context.Context, in *vtctldatapb.RemoveKeyspaceCellRequest, opts ...grpc.CallOption) (*vtctldatapb.RemoveKeyspaceCellResponse, error) { if client.c == nil { diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 8ce8e329d3e..f8aa3f36420 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -1521,6 +1521,16 @@ func (s *VtctldServer) RebuildVSchemaGraph(ctx context.Context, req *vtctldatapb return &vtctldatapb.RebuildVSchemaGraphResponse{}, nil } +// RefreshState is part of the vtctldservicepb.VtctldServer interface. +func (s *VtctldServer) RefreshState(ctx context.Context, req *vtctldatapb.RefreshStateRequest) (*vtctldatapb.RefreshStateResponse, error) { + panic("unimplemented!") +} + +// RefreshStateByShard is part of the vtctldservicepb.VtctldServer interface. +func (s *VtctldServer) RefreshStateByShard(ctx context.Context, req *vtctldatapb.RefreshStateByShardRequest) (*vtctldatapb.RefreshStateByShardResponse, error) { + panic("unimplemented!") +} + // RemoveKeyspaceCell is part of the vtctlservicepb.VtctldServer interface. func (s *VtctldServer) RemoveKeyspaceCell(ctx context.Context, req *vtctldatapb.RemoveKeyspaceCellRequest) (*vtctldatapb.RemoveKeyspaceCellResponse, error) { span, ctx := trace.NewSpan(ctx, "VtctldServer.RemoveKeyspaceCell") diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index c7fecd9d2b2..01832c9cf5d 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -579,6 +579,23 @@ message RebuildVSchemaGraphRequest { message RebuildVSchemaGraphResponse { } +message RefreshStateRequest { + topodata.TabletAlias tablet_alias = 1; +} + +message RefreshStateResponse { +} + +message RefreshStateByShardRequest { + string keyspace = 1; + string shard = 2; + repeated string cells = 3; +} + +message RefreshStateByShardResponse { + bool is_partial_refresh = 1; +} + message RemoveKeyspaceCellRequest { string keyspace = 1; string cell = 2; diff --git a/proto/vtctlservice.proto b/proto/vtctlservice.proto index 93571e506c5..e2b826930c2 100644 --- a/proto/vtctlservice.proto +++ b/proto/vtctlservice.proto @@ -136,6 +136,10 @@ service Vtctld { // VSchema objects in the provided cells (or all cells in the topo none // provided). rpc RebuildVSchemaGraph(vtctldata.RebuildVSchemaGraphRequest) returns (vtctldata.RebuildVSchemaGraphResponse) {}; + // RefreshState reloads the tablet record on the specified tablet. + rpc RefreshState(vtctldata.RefreshStateRequest) returns (vtctldata.RefreshStateResponse) {}; + // RefreshStateByShard calls RefreshState on all the tablets in the given shard. + rpc RefreshStateByShard(vtctldata.RefreshStateByShardRequest) returns (vtctldata.RefreshStateByShardResponse) {}; // RemoveKeyspaceCell removes the specified cell from the Cells list for all // shards in the specified keyspace, as well as from the SrvKeyspace for that // keyspace in that cell. diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index c37d43b41f2..9775ce7b631 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -30903,6 +30903,372 @@ export namespace vtctldata { public toJSON(): { [k: string]: any }; } + /** Properties of a RefreshStateRequest. */ + interface IRefreshStateRequest { + + /** RefreshStateRequest tablet_alias */ + tablet_alias?: (topodata.ITabletAlias|null); + } + + /** Represents a RefreshStateRequest. */ + class RefreshStateRequest implements IRefreshStateRequest { + + /** + * Constructs a new RefreshStateRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IRefreshStateRequest); + + /** RefreshStateRequest tablet_alias. */ + public tablet_alias?: (topodata.ITabletAlias|null); + + /** + * Creates a new RefreshStateRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns RefreshStateRequest instance + */ + public static create(properties?: vtctldata.IRefreshStateRequest): vtctldata.RefreshStateRequest; + + /** + * Encodes the specified RefreshStateRequest message. Does not implicitly {@link vtctldata.RefreshStateRequest.verify|verify} messages. + * @param message RefreshStateRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IRefreshStateRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RefreshStateRequest message, length delimited. Does not implicitly {@link vtctldata.RefreshStateRequest.verify|verify} messages. + * @param message RefreshStateRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IRefreshStateRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RefreshStateRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RefreshStateRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.RefreshStateRequest; + + /** + * Decodes a RefreshStateRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RefreshStateRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.RefreshStateRequest; + + /** + * Verifies a RefreshStateRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RefreshStateRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RefreshStateRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.RefreshStateRequest; + + /** + * Creates a plain object from a RefreshStateRequest message. Also converts values to other types if specified. + * @param message RefreshStateRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.RefreshStateRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RefreshStateRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RefreshStateResponse. */ + interface IRefreshStateResponse { + } + + /** Represents a RefreshStateResponse. */ + class RefreshStateResponse implements IRefreshStateResponse { + + /** + * Constructs a new RefreshStateResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IRefreshStateResponse); + + /** + * Creates a new RefreshStateResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns RefreshStateResponse instance + */ + public static create(properties?: vtctldata.IRefreshStateResponse): vtctldata.RefreshStateResponse; + + /** + * Encodes the specified RefreshStateResponse message. Does not implicitly {@link vtctldata.RefreshStateResponse.verify|verify} messages. + * @param message RefreshStateResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IRefreshStateResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RefreshStateResponse message, length delimited. Does not implicitly {@link vtctldata.RefreshStateResponse.verify|verify} messages. + * @param message RefreshStateResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IRefreshStateResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RefreshStateResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RefreshStateResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.RefreshStateResponse; + + /** + * Decodes a RefreshStateResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RefreshStateResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.RefreshStateResponse; + + /** + * Verifies a RefreshStateResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RefreshStateResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RefreshStateResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.RefreshStateResponse; + + /** + * Creates a plain object from a RefreshStateResponse message. Also converts values to other types if specified. + * @param message RefreshStateResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.RefreshStateResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RefreshStateResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RefreshStateByShardRequest. */ + interface IRefreshStateByShardRequest { + + /** RefreshStateByShardRequest keyspace */ + keyspace?: (string|null); + + /** RefreshStateByShardRequest shard */ + shard?: (string|null); + + /** RefreshStateByShardRequest cells */ + cells?: (string[]|null); + } + + /** Represents a RefreshStateByShardRequest. */ + class RefreshStateByShardRequest implements IRefreshStateByShardRequest { + + /** + * Constructs a new RefreshStateByShardRequest. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IRefreshStateByShardRequest); + + /** RefreshStateByShardRequest keyspace. */ + public keyspace: string; + + /** RefreshStateByShardRequest shard. */ + public shard: string; + + /** RefreshStateByShardRequest cells. */ + public cells: string[]; + + /** + * Creates a new RefreshStateByShardRequest instance using the specified properties. + * @param [properties] Properties to set + * @returns RefreshStateByShardRequest instance + */ + public static create(properties?: vtctldata.IRefreshStateByShardRequest): vtctldata.RefreshStateByShardRequest; + + /** + * Encodes the specified RefreshStateByShardRequest message. Does not implicitly {@link vtctldata.RefreshStateByShardRequest.verify|verify} messages. + * @param message RefreshStateByShardRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IRefreshStateByShardRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RefreshStateByShardRequest message, length delimited. Does not implicitly {@link vtctldata.RefreshStateByShardRequest.verify|verify} messages. + * @param message RefreshStateByShardRequest message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IRefreshStateByShardRequest, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RefreshStateByShardRequest message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RefreshStateByShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.RefreshStateByShardRequest; + + /** + * Decodes a RefreshStateByShardRequest message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RefreshStateByShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.RefreshStateByShardRequest; + + /** + * Verifies a RefreshStateByShardRequest message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RefreshStateByShardRequest message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RefreshStateByShardRequest + */ + public static fromObject(object: { [k: string]: any }): vtctldata.RefreshStateByShardRequest; + + /** + * Creates a plain object from a RefreshStateByShardRequest message. Also converts values to other types if specified. + * @param message RefreshStateByShardRequest + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.RefreshStateByShardRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RefreshStateByShardRequest to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + + /** Properties of a RefreshStateByShardResponse. */ + interface IRefreshStateByShardResponse { + + /** RefreshStateByShardResponse is_partial_refresh */ + is_partial_refresh?: (boolean|null); + } + + /** Represents a RefreshStateByShardResponse. */ + class RefreshStateByShardResponse implements IRefreshStateByShardResponse { + + /** + * Constructs a new RefreshStateByShardResponse. + * @param [properties] Properties to set + */ + constructor(properties?: vtctldata.IRefreshStateByShardResponse); + + /** RefreshStateByShardResponse is_partial_refresh. */ + public is_partial_refresh: boolean; + + /** + * Creates a new RefreshStateByShardResponse instance using the specified properties. + * @param [properties] Properties to set + * @returns RefreshStateByShardResponse instance + */ + public static create(properties?: vtctldata.IRefreshStateByShardResponse): vtctldata.RefreshStateByShardResponse; + + /** + * Encodes the specified RefreshStateByShardResponse message. Does not implicitly {@link vtctldata.RefreshStateByShardResponse.verify|verify} messages. + * @param message RefreshStateByShardResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encode(message: vtctldata.IRefreshStateByShardResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Encodes the specified RefreshStateByShardResponse message, length delimited. Does not implicitly {@link vtctldata.RefreshStateByShardResponse.verify|verify} messages. + * @param message RefreshStateByShardResponse message or plain object to encode + * @param [writer] Writer to encode to + * @returns Writer + */ + public static encodeDelimited(message: vtctldata.IRefreshStateByShardResponse, writer?: $protobuf.Writer): $protobuf.Writer; + + /** + * Decodes a RefreshStateByShardResponse message from the specified reader or buffer. + * @param reader Reader or buffer to decode from + * @param [length] Message length if known beforehand + * @returns RefreshStateByShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): vtctldata.RefreshStateByShardResponse; + + /** + * Decodes a RefreshStateByShardResponse message from the specified reader or buffer, length delimited. + * @param reader Reader or buffer to decode from + * @returns RefreshStateByShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): vtctldata.RefreshStateByShardResponse; + + /** + * Verifies a RefreshStateByShardResponse message. + * @param message Plain object to verify + * @returns `null` if valid, otherwise the reason why it is not + */ + public static verify(message: { [k: string]: any }): (string|null); + + /** + * Creates a RefreshStateByShardResponse message from a plain object. Also converts values to their respective internal types. + * @param object Plain object + * @returns RefreshStateByShardResponse + */ + public static fromObject(object: { [k: string]: any }): vtctldata.RefreshStateByShardResponse; + + /** + * Creates a plain object from a RefreshStateByShardResponse message. Also converts values to other types if specified. + * @param message RefreshStateByShardResponse + * @param [options] Conversion options + * @returns Plain object + */ + public static toObject(message: vtctldata.RefreshStateByShardResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; + + /** + * Converts this RefreshStateByShardResponse to JSON. + * @returns JSON object + */ + public toJSON(): { [k: string]: any }; + } + /** Properties of a RemoveKeyspaceCellRequest. */ interface IRemoveKeyspaceCellRequest { diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index 1628750744b..c0abe9aea41 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -73717,6 +73717,794 @@ $root.vtctldata = (function() { return RebuildVSchemaGraphResponse; })(); + vtctldata.RefreshStateRequest = (function() { + + /** + * Properties of a RefreshStateRequest. + * @memberof vtctldata + * @interface IRefreshStateRequest + * @property {topodata.ITabletAlias|null} [tablet_alias] RefreshStateRequest tablet_alias + */ + + /** + * Constructs a new RefreshStateRequest. + * @memberof vtctldata + * @classdesc Represents a RefreshStateRequest. + * @implements IRefreshStateRequest + * @constructor + * @param {vtctldata.IRefreshStateRequest=} [properties] Properties to set + */ + function RefreshStateRequest(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RefreshStateRequest tablet_alias. + * @member {topodata.ITabletAlias|null|undefined} tablet_alias + * @memberof vtctldata.RefreshStateRequest + * @instance + */ + RefreshStateRequest.prototype.tablet_alias = null; + + /** + * Creates a new RefreshStateRequest instance using the specified properties. + * @function create + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {vtctldata.IRefreshStateRequest=} [properties] Properties to set + * @returns {vtctldata.RefreshStateRequest} RefreshStateRequest instance + */ + RefreshStateRequest.create = function create(properties) { + return new RefreshStateRequest(properties); + }; + + /** + * Encodes the specified RefreshStateRequest message. Does not implicitly {@link vtctldata.RefreshStateRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {vtctldata.IRefreshStateRequest} message RefreshStateRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.tablet_alias != null && Object.hasOwnProperty.call(message, "tablet_alias")) + $root.topodata.TabletAlias.encode(message.tablet_alias, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim(); + return writer; + }; + + /** + * Encodes the specified RefreshStateRequest message, length delimited. Does not implicitly {@link vtctldata.RefreshStateRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {vtctldata.IRefreshStateRequest} message RefreshStateRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RefreshStateRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.RefreshStateRequest} RefreshStateRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.RefreshStateRequest(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.tablet_alias = $root.topodata.TabletAlias.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RefreshStateRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.RefreshStateRequest} RefreshStateRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RefreshStateRequest message. + * @function verify + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RefreshStateRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.tablet_alias != null && message.hasOwnProperty("tablet_alias")) { + var error = $root.topodata.TabletAlias.verify(message.tablet_alias); + if (error) + return "tablet_alias." + error; + } + return null; + }; + + /** + * Creates a RefreshStateRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.RefreshStateRequest} RefreshStateRequest + */ + RefreshStateRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.RefreshStateRequest) + return object; + var message = new $root.vtctldata.RefreshStateRequest(); + if (object.tablet_alias != null) { + if (typeof object.tablet_alias !== "object") + throw TypeError(".vtctldata.RefreshStateRequest.tablet_alias: object expected"); + message.tablet_alias = $root.topodata.TabletAlias.fromObject(object.tablet_alias); + } + return message; + }; + + /** + * Creates a plain object from a RefreshStateRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.RefreshStateRequest + * @static + * @param {vtctldata.RefreshStateRequest} message RefreshStateRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RefreshStateRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.tablet_alias = null; + if (message.tablet_alias != null && message.hasOwnProperty("tablet_alias")) + object.tablet_alias = $root.topodata.TabletAlias.toObject(message.tablet_alias, options); + return object; + }; + + /** + * Converts this RefreshStateRequest to JSON. + * @function toJSON + * @memberof vtctldata.RefreshStateRequest + * @instance + * @returns {Object.} JSON object + */ + RefreshStateRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RefreshStateRequest; + })(); + + vtctldata.RefreshStateResponse = (function() { + + /** + * Properties of a RefreshStateResponse. + * @memberof vtctldata + * @interface IRefreshStateResponse + */ + + /** + * Constructs a new RefreshStateResponse. + * @memberof vtctldata + * @classdesc Represents a RefreshStateResponse. + * @implements IRefreshStateResponse + * @constructor + * @param {vtctldata.IRefreshStateResponse=} [properties] Properties to set + */ + function RefreshStateResponse(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * Creates a new RefreshStateResponse instance using the specified properties. + * @function create + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {vtctldata.IRefreshStateResponse=} [properties] Properties to set + * @returns {vtctldata.RefreshStateResponse} RefreshStateResponse instance + */ + RefreshStateResponse.create = function create(properties) { + return new RefreshStateResponse(properties); + }; + + /** + * Encodes the specified RefreshStateResponse message. Does not implicitly {@link vtctldata.RefreshStateResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {vtctldata.IRefreshStateResponse} message RefreshStateResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + return writer; + }; + + /** + * Encodes the specified RefreshStateResponse message, length delimited. Does not implicitly {@link vtctldata.RefreshStateResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {vtctldata.IRefreshStateResponse} message RefreshStateResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RefreshStateResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.RefreshStateResponse} RefreshStateResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.RefreshStateResponse(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RefreshStateResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.RefreshStateResponse} RefreshStateResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RefreshStateResponse message. + * @function verify + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RefreshStateResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + return null; + }; + + /** + * Creates a RefreshStateResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.RefreshStateResponse} RefreshStateResponse + */ + RefreshStateResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.RefreshStateResponse) + return object; + return new $root.vtctldata.RefreshStateResponse(); + }; + + /** + * Creates a plain object from a RefreshStateResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.RefreshStateResponse + * @static + * @param {vtctldata.RefreshStateResponse} message RefreshStateResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RefreshStateResponse.toObject = function toObject() { + return {}; + }; + + /** + * Converts this RefreshStateResponse to JSON. + * @function toJSON + * @memberof vtctldata.RefreshStateResponse + * @instance + * @returns {Object.} JSON object + */ + RefreshStateResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RefreshStateResponse; + })(); + + vtctldata.RefreshStateByShardRequest = (function() { + + /** + * Properties of a RefreshStateByShardRequest. + * @memberof vtctldata + * @interface IRefreshStateByShardRequest + * @property {string|null} [keyspace] RefreshStateByShardRequest keyspace + * @property {string|null} [shard] RefreshStateByShardRequest shard + * @property {Array.|null} [cells] RefreshStateByShardRequest cells + */ + + /** + * Constructs a new RefreshStateByShardRequest. + * @memberof vtctldata + * @classdesc Represents a RefreshStateByShardRequest. + * @implements IRefreshStateByShardRequest + * @constructor + * @param {vtctldata.IRefreshStateByShardRequest=} [properties] Properties to set + */ + function RefreshStateByShardRequest(properties) { + this.cells = []; + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RefreshStateByShardRequest keyspace. + * @member {string} keyspace + * @memberof vtctldata.RefreshStateByShardRequest + * @instance + */ + RefreshStateByShardRequest.prototype.keyspace = ""; + + /** + * RefreshStateByShardRequest shard. + * @member {string} shard + * @memberof vtctldata.RefreshStateByShardRequest + * @instance + */ + RefreshStateByShardRequest.prototype.shard = ""; + + /** + * RefreshStateByShardRequest cells. + * @member {Array.} cells + * @memberof vtctldata.RefreshStateByShardRequest + * @instance + */ + RefreshStateByShardRequest.prototype.cells = $util.emptyArray; + + /** + * Creates a new RefreshStateByShardRequest instance using the specified properties. + * @function create + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {vtctldata.IRefreshStateByShardRequest=} [properties] Properties to set + * @returns {vtctldata.RefreshStateByShardRequest} RefreshStateByShardRequest instance + */ + RefreshStateByShardRequest.create = function create(properties) { + return new RefreshStateByShardRequest(properties); + }; + + /** + * Encodes the specified RefreshStateByShardRequest message. Does not implicitly {@link vtctldata.RefreshStateByShardRequest.verify|verify} messages. + * @function encode + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {vtctldata.IRefreshStateByShardRequest} message RefreshStateByShardRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateByShardRequest.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); + if (message.shard != null && Object.hasOwnProperty.call(message, "shard")) + writer.uint32(/* id 2, wireType 2 =*/18).string(message.shard); + if (message.cells != null && message.cells.length) + for (var i = 0; i < message.cells.length; ++i) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.cells[i]); + return writer; + }; + + /** + * Encodes the specified RefreshStateByShardRequest message, length delimited. Does not implicitly {@link vtctldata.RefreshStateByShardRequest.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {vtctldata.IRefreshStateByShardRequest} message RefreshStateByShardRequest message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateByShardRequest.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RefreshStateByShardRequest message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.RefreshStateByShardRequest} RefreshStateByShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateByShardRequest.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.RefreshStateByShardRequest(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.keyspace = reader.string(); + break; + case 2: + message.shard = reader.string(); + break; + case 3: + if (!(message.cells && message.cells.length)) + message.cells = []; + message.cells.push(reader.string()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RefreshStateByShardRequest message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.RefreshStateByShardRequest} RefreshStateByShardRequest + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateByShardRequest.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RefreshStateByShardRequest message. + * @function verify + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RefreshStateByShardRequest.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.shard != null && message.hasOwnProperty("shard")) + if (!$util.isString(message.shard)) + return "shard: string expected"; + if (message.cells != null && message.hasOwnProperty("cells")) { + if (!Array.isArray(message.cells)) + return "cells: array expected"; + for (var i = 0; i < message.cells.length; ++i) + if (!$util.isString(message.cells[i])) + return "cells: string[] expected"; + } + return null; + }; + + /** + * Creates a RefreshStateByShardRequest message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.RefreshStateByShardRequest} RefreshStateByShardRequest + */ + RefreshStateByShardRequest.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.RefreshStateByShardRequest) + return object; + var message = new $root.vtctldata.RefreshStateByShardRequest(); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.shard != null) + message.shard = String(object.shard); + if (object.cells) { + if (!Array.isArray(object.cells)) + throw TypeError(".vtctldata.RefreshStateByShardRequest.cells: array expected"); + message.cells = []; + for (var i = 0; i < object.cells.length; ++i) + message.cells[i] = String(object.cells[i]); + } + return message; + }; + + /** + * Creates a plain object from a RefreshStateByShardRequest message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.RefreshStateByShardRequest + * @static + * @param {vtctldata.RefreshStateByShardRequest} message RefreshStateByShardRequest + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RefreshStateByShardRequest.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.arrays || options.defaults) + object.cells = []; + if (options.defaults) { + object.keyspace = ""; + object.shard = ""; + } + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.shard != null && message.hasOwnProperty("shard")) + object.shard = message.shard; + if (message.cells && message.cells.length) { + object.cells = []; + for (var j = 0; j < message.cells.length; ++j) + object.cells[j] = message.cells[j]; + } + return object; + }; + + /** + * Converts this RefreshStateByShardRequest to JSON. + * @function toJSON + * @memberof vtctldata.RefreshStateByShardRequest + * @instance + * @returns {Object.} JSON object + */ + RefreshStateByShardRequest.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RefreshStateByShardRequest; + })(); + + vtctldata.RefreshStateByShardResponse = (function() { + + /** + * Properties of a RefreshStateByShardResponse. + * @memberof vtctldata + * @interface IRefreshStateByShardResponse + * @property {boolean|null} [is_partial_refresh] RefreshStateByShardResponse is_partial_refresh + */ + + /** + * Constructs a new RefreshStateByShardResponse. + * @memberof vtctldata + * @classdesc Represents a RefreshStateByShardResponse. + * @implements IRefreshStateByShardResponse + * @constructor + * @param {vtctldata.IRefreshStateByShardResponse=} [properties] Properties to set + */ + function RefreshStateByShardResponse(properties) { + if (properties) + for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i) + if (properties[keys[i]] != null) + this[keys[i]] = properties[keys[i]]; + } + + /** + * RefreshStateByShardResponse is_partial_refresh. + * @member {boolean} is_partial_refresh + * @memberof vtctldata.RefreshStateByShardResponse + * @instance + */ + RefreshStateByShardResponse.prototype.is_partial_refresh = false; + + /** + * Creates a new RefreshStateByShardResponse instance using the specified properties. + * @function create + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {vtctldata.IRefreshStateByShardResponse=} [properties] Properties to set + * @returns {vtctldata.RefreshStateByShardResponse} RefreshStateByShardResponse instance + */ + RefreshStateByShardResponse.create = function create(properties) { + return new RefreshStateByShardResponse(properties); + }; + + /** + * Encodes the specified RefreshStateByShardResponse message. Does not implicitly {@link vtctldata.RefreshStateByShardResponse.verify|verify} messages. + * @function encode + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {vtctldata.IRefreshStateByShardResponse} message RefreshStateByShardResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateByShardResponse.encode = function encode(message, writer) { + if (!writer) + writer = $Writer.create(); + if (message.is_partial_refresh != null && Object.hasOwnProperty.call(message, "is_partial_refresh")) + writer.uint32(/* id 1, wireType 0 =*/8).bool(message.is_partial_refresh); + return writer; + }; + + /** + * Encodes the specified RefreshStateByShardResponse message, length delimited. Does not implicitly {@link vtctldata.RefreshStateByShardResponse.verify|verify} messages. + * @function encodeDelimited + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {vtctldata.IRefreshStateByShardResponse} message RefreshStateByShardResponse message or plain object to encode + * @param {$protobuf.Writer} [writer] Writer to encode to + * @returns {$protobuf.Writer} Writer + */ + RefreshStateByShardResponse.encodeDelimited = function encodeDelimited(message, writer) { + return this.encode(message, writer).ldelim(); + }; + + /** + * Decodes a RefreshStateByShardResponse message from the specified reader or buffer. + * @function decode + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @param {number} [length] Message length if known beforehand + * @returns {vtctldata.RefreshStateByShardResponse} RefreshStateByShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateByShardResponse.decode = function decode(reader, length) { + if (!(reader instanceof $Reader)) + reader = $Reader.create(reader); + var end = length === undefined ? reader.len : reader.pos + length, message = new $root.vtctldata.RefreshStateByShardResponse(); + while (reader.pos < end) { + var tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.is_partial_refresh = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }; + + /** + * Decodes a RefreshStateByShardResponse message from the specified reader or buffer, length delimited. + * @function decodeDelimited + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from + * @returns {vtctldata.RefreshStateByShardResponse} RefreshStateByShardResponse + * @throws {Error} If the payload is not a reader or valid buffer + * @throws {$protobuf.util.ProtocolError} If required fields are missing + */ + RefreshStateByShardResponse.decodeDelimited = function decodeDelimited(reader) { + if (!(reader instanceof $Reader)) + reader = new $Reader(reader); + return this.decode(reader, reader.uint32()); + }; + + /** + * Verifies a RefreshStateByShardResponse message. + * @function verify + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {Object.} message Plain object to verify + * @returns {string|null} `null` if valid, otherwise the reason why it is not + */ + RefreshStateByShardResponse.verify = function verify(message) { + if (typeof message !== "object" || message === null) + return "object expected"; + if (message.is_partial_refresh != null && message.hasOwnProperty("is_partial_refresh")) + if (typeof message.is_partial_refresh !== "boolean") + return "is_partial_refresh: boolean expected"; + return null; + }; + + /** + * Creates a RefreshStateByShardResponse message from a plain object. Also converts values to their respective internal types. + * @function fromObject + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {Object.} object Plain object + * @returns {vtctldata.RefreshStateByShardResponse} RefreshStateByShardResponse + */ + RefreshStateByShardResponse.fromObject = function fromObject(object) { + if (object instanceof $root.vtctldata.RefreshStateByShardResponse) + return object; + var message = new $root.vtctldata.RefreshStateByShardResponse(); + if (object.is_partial_refresh != null) + message.is_partial_refresh = Boolean(object.is_partial_refresh); + return message; + }; + + /** + * Creates a plain object from a RefreshStateByShardResponse message. Also converts values to other types if specified. + * @function toObject + * @memberof vtctldata.RefreshStateByShardResponse + * @static + * @param {vtctldata.RefreshStateByShardResponse} message RefreshStateByShardResponse + * @param {$protobuf.IConversionOptions} [options] Conversion options + * @returns {Object.} Plain object + */ + RefreshStateByShardResponse.toObject = function toObject(message, options) { + if (!options) + options = {}; + var object = {}; + if (options.defaults) + object.is_partial_refresh = false; + if (message.is_partial_refresh != null && message.hasOwnProperty("is_partial_refresh")) + object.is_partial_refresh = message.is_partial_refresh; + return object; + }; + + /** + * Converts this RefreshStateByShardResponse to JSON. + * @function toJSON + * @memberof vtctldata.RefreshStateByShardResponse + * @instance + * @returns {Object.} JSON object + */ + RefreshStateByShardResponse.prototype.toJSON = function toJSON() { + return this.constructor.toObject(this, $protobuf.util.toJSONOptions); + }; + + return RefreshStateByShardResponse; + })(); + vtctldata.RemoveKeyspaceCellRequest = (function() { /** From 4c7b37e1a1c7a59cfafb316c4f06081d4c68f6f8 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 1 Jun 2021 20:06:33 -0400 Subject: [PATCH 259/310] [topotools] Refactor RefreshTabletsByShard to indicate if the refresh was only partial Signed-off-by: Andrew Mason --- go/vt/topotools/keyspace.go | 20 +++++++++++++++----- go/vt/wrangler/keyspace.go | 3 ++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/go/vt/topotools/keyspace.go b/go/vt/topotools/keyspace.go index 480adc6790f..16f0a6fd2bd 100644 --- a/go/vt/topotools/keyspace.go +++ b/go/vt/topotools/keyspace.go @@ -33,7 +33,10 @@ import ( // It only returns errors from looking up the tablet map from the topology; // errors returned from any RefreshState RPCs are logged and then ignored. Also, // any tablets without a .Hostname set in the topology are skipped. -func RefreshTabletsByShard(ctx context.Context, ts *topo.Server, tmc tmclient.TabletManagerClient, si *topo.ShardInfo, cells []string, logger logutil.Logger) error { +// +// However, on partial errors from the topology, or errors from a RefreshState +// RPC will cause a boolean flag to be returned indicating only partial success. +func RefreshTabletsByShard(ctx context.Context, ts *topo.Server, tmc tmclient.TabletManagerClient, si *topo.ShardInfo, cells []string, logger logutil.Logger) (isPartialRefresh bool, err error) { logger.Infof("RefreshTabletsByShard called on shard %v/%v", si.Keyspace(), si.ShardName()) tabletMap, err := ts.GetTabletMapForShardByCell(ctx, si.Keyspace(), si.ShardName(), cells) @@ -42,12 +45,16 @@ func RefreshTabletsByShard(ctx context.Context, ts *topo.Server, tmc tmclient.Ta // keep going case topo.IsErrType(err, topo.PartialResult): logger.Warningf("RefreshTabletsByShard: got partial result for shard %v/%v, may not refresh all tablets everywhere", si.Keyspace(), si.ShardName()) + isPartialRefresh = true default: - return err + return false, err } // Any errors from this point onward are ignored. - var wg sync.WaitGroup + var ( + m sync.Mutex + wg sync.WaitGroup + ) for _, ti := range tabletMap { if ti.Hostname == "" { // The tablet is not running, we don't have the host @@ -66,12 +73,15 @@ func RefreshTabletsByShard(ctx context.Context, ts *topo.Server, tmc tmclient.Ta if err := tmc.RefreshState(ctx, ti.Tablet); err != nil { logger.Warningf("RefreshTabletsByShard: failed to refresh %v: %v", ti.AliasString(), err) + m.Lock() + isPartialRefresh = true + m.Unlock() } }(ti) } wg.Wait() - return nil + return isPartialRefresh, nil } // UpdateShardRecords updates the shard records based on 'from' or 'to' @@ -111,7 +121,7 @@ func UpdateShardRecords( // For 'to' shards, refresh to make them serve. The 'from' shards will // be refreshed after traffic has migrated. if !isFrom { - if err := RefreshTabletsByShard(ctx, ts, tmc, si, cells, logger); err != nil { + if _, err := RefreshTabletsByShard(ctx, ts, tmc, si, cells, logger); err != nil { logger.Warningf("RefreshTabletsByShard(%v/%v, cells=%v) failed with %v; continuing ...", si.Keyspace(), si.ShardName(), cells, err) } } diff --git a/go/vt/wrangler/keyspace.go b/go/vt/wrangler/keyspace.go index 4a089d5811b..d95da7acd37 100644 --- a/go/vt/wrangler/keyspace.go +++ b/go/vt/wrangler/keyspace.go @@ -1359,7 +1359,8 @@ func (wr *Wrangler) SetKeyspaceServedFrom(ctx context.Context, keyspace string, // RefreshTabletsByShard calls RefreshState on all the tablets in a given shard. func (wr *Wrangler) RefreshTabletsByShard(ctx context.Context, si *topo.ShardInfo, cells []string) error { - return topotools.RefreshTabletsByShard(ctx, wr.ts, wr.tmc, si, cells, wr.Logger()) + _, err := topotools.RefreshTabletsByShard(ctx, wr.ts, wr.tmc, si, cells, wr.Logger()) + return err } // DeleteKeyspace will do all the necessary changes in the topology server From d246b9ab4aa84a08127f37f3fa4e53d05846a380 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 1 Jun 2021 21:45:53 -0400 Subject: [PATCH 260/310] [vtctldserver] Implement `RefreshState(ByShard)?` with tests Signed-off-by: Andrew Mason --- go/vt/vtctl/grpcvtctldserver/server.go | 52 +++- go/vt/vtctl/grpcvtctldserver/server_test.go | 288 ++++++++++++++++++ .../testutil/test_tmclient.go | 16 + 3 files changed, 354 insertions(+), 2 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index f8aa3f36420..647517ee0d4 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -1523,12 +1523,60 @@ func (s *VtctldServer) RebuildVSchemaGraph(ctx context.Context, req *vtctldatapb // RefreshState is part of the vtctldservicepb.VtctldServer interface. func (s *VtctldServer) RefreshState(ctx context.Context, req *vtctldatapb.RefreshStateRequest) (*vtctldatapb.RefreshStateResponse, error) { - panic("unimplemented!") + if req.TabletAlias == nil { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "RefreshState requires a tablet alias") + } + + ctx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + + tablet, err := s.ts.GetTablet(ctx, req.TabletAlias) + if err != nil { + return nil, fmt.Errorf("Failed to get tablet %s: %w", topoproto.TabletAliasString(req.TabletAlias), err) + } + + if err := s.tmc.RefreshState(ctx, tablet.Tablet); err != nil { + return nil, err + } + + return &vtctldatapb.RefreshStateResponse{}, nil } // RefreshStateByShard is part of the vtctldservicepb.VtctldServer interface. func (s *VtctldServer) RefreshStateByShard(ctx context.Context, req *vtctldatapb.RefreshStateByShardRequest) (*vtctldatapb.RefreshStateByShardResponse, error) { - panic("unimplemented!") + if req.Keyspace == "" { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "RefreshStateByShard requires a keyspace") + } + + if req.Shard == "" { + return nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "RefreshStateByShard requires a shard") + } + + ctx, cancel := context.WithTimeout(ctx, *topo.RemoteOperationTimeout) + defer cancel() + + si, err := s.ts.GetShard(ctx, req.Keyspace, req.Shard) + if err != nil { + return nil, fmt.Errorf("Failed to get shard %s/%s/: %w", req.Keyspace, req.Shard, err) + } + + isPartial, err := topotools.RefreshTabletsByShard(ctx, s.ts, s.tmc, si, req.Cells, logutil.NewCallbackLogger(func(e *logutilpb.Event) { + switch e.Level { + case logutilpb.Level_WARNING: + log.Warningf(e.Value) + case logutilpb.Level_ERROR: + log.Errorf(e.Value) + default: + log.Infof(e.Value) + } + })) + if err != nil { + return nil, err + } + + return &vtctldatapb.RefreshStateByShardResponse{ + IsPartialRefresh: isPartial, + }, nil } // RemoveKeyspaceCell is part of the vtctlservicepb.VtctldServer interface. diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 3db13543e1f..7a5cb9f44a4 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -4535,6 +4535,294 @@ func TestRebuildVSchemaGraph(t *testing.T) { } } +func TestRefreshState(t *testing.T) { + t.Parallel() + + ctx := context.Background() + tests := []struct { + name string + ts *topo.Server + tablet *topodatapb.Tablet + refreshStateError error + req *vtctldatapb.RefreshStateRequest + shouldErr bool + }{ + { + name: "success", + ts: memorytopo.NewServer("zone1"), + tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + refreshStateError: nil, + req: &vtctldatapb.RefreshStateRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + }, + { + name: "tablet alias nil", + ts: memorytopo.NewServer(), + req: &vtctldatapb.RefreshStateRequest{}, + shouldErr: true, + }, + { + name: "tablet not found", + ts: memorytopo.NewServer("zone1"), + tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + refreshStateError: nil, + req: &vtctldatapb.RefreshStateRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 400, + }, + }, + shouldErr: true, + }, + { + name: "RefreshState failed", + ts: memorytopo.NewServer("zone1"), + tablet: &topodatapb.Tablet{ + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + refreshStateError: fmt.Errorf("%w: RefreshState failed", assert.AnError), + req: &vtctldatapb.RefreshStateRequest{ + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + }, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + var tmc testutil.TabletManagerClient + if tt.tablet != nil { + testutil.AddTablet(ctx, t, tt.ts, tt.tablet, nil) + tmc.RefreshStateResults = map[string]error{ + topoproto.TabletAliasString(tt.tablet.Alias): tt.refreshStateError, + } + } + + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, tt.ts, &tmc, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) + _, err := vtctld.RefreshState(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + assert.NoError(t, err) + }) + } +} + +func TestRefreshStateByShard(t *testing.T) { + t.Parallel() + + ctx := context.Background() + tests := []struct { + name string + ts *topo.Server + tablets []*topodatapb.Tablet + refreshStateErrors []error // must have len(tablets) + req *vtctldatapb.RefreshStateByShardRequest + expected *vtctldatapb.RefreshStateByShardResponse + shouldErr bool + }{ + { + name: "success", + ts: memorytopo.NewServer("zone1", "zone2"), + tablets: []*topodatapb.Tablet{ + { + Hostname: "zone1-100", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-", + }, + { + Hostname: "zone2-100", + Alias: &topodatapb.TabletAlias{ + Cell: "zone2", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-", + }, + }, + refreshStateErrors: []error{ + nil, // zone1-100 + nil, // zone2-100 + }, + req: &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: "ks", + Shard: "-", + }, + expected: &vtctldatapb.RefreshStateByShardResponse{}, + }, + { + name: "cell filtering", + ts: memorytopo.NewServer("zone1", "zone2"), + tablets: []*topodatapb.Tablet{ + { + Hostname: "zone1-100", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-", + }, + { + Hostname: "zone2-100", + Alias: &topodatapb.TabletAlias{ + Cell: "zone2", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-", + }, + }, + refreshStateErrors: []error{ + nil, + fmt.Errorf("%w: RefreshState failed on zone2-100", assert.AnError), + }, + req: &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: "ks", + Shard: "-", + Cells: []string{"zone1"}, // If we didn't filter, we would get IsPartialRefresh=true because of the failure in zone2. + }, + expected: &vtctldatapb.RefreshStateByShardResponse{ + IsPartialRefresh: false, + }, + shouldErr: false, + }, + { + name: "partial result", + ts: memorytopo.NewServer("zone1", "zone2"), + tablets: []*topodatapb.Tablet{ + { + Hostname: "zone1-100", + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-", + }, + { + Hostname: "zone2-100", + Alias: &topodatapb.TabletAlias{ + Cell: "zone2", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-", + }, + }, + refreshStateErrors: []error{ + nil, + fmt.Errorf("%w: RefreshState failed on zone2-100", assert.AnError), + }, + req: &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: "ks", + Shard: "-", + }, + expected: &vtctldatapb.RefreshStateByShardResponse{ + IsPartialRefresh: true, + }, + shouldErr: false, + }, + { + name: "missing keyspace argument", + ts: memorytopo.NewServer(), + req: &vtctldatapb.RefreshStateByShardRequest{}, + shouldErr: true, + }, + { + name: "missing shard argument", + ts: memorytopo.NewServer(), + req: &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: "ks", + }, + shouldErr: true, + }, + { + name: "shard not found", + ts: memorytopo.NewServer("zone1"), + tablets: []*topodatapb.Tablet{ + { + Alias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Keyspace: "ks", + Shard: "-80", + }, + }, + refreshStateErrors: []error{nil}, + req: &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: "ks2", + Shard: "-", + }, + shouldErr: true, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + require.Equal(t, len(tt.tablets), len(tt.refreshStateErrors), "Invalid test case: must have one refreshStateError for each tablet") + + tmc := &testutil.TabletManagerClient{ + RefreshStateResults: make(map[string]error, len(tt.tablets)), + } + testutil.AddTablets(ctx, t, tt.ts, nil, tt.tablets...) + for i, tablet := range tt.tablets { + key := topoproto.TabletAliasString(tablet.Alias) + tmc.RefreshStateResults[key] = tt.refreshStateErrors[i] + } + + vtctld := testutil.NewVtctldServerWithTabletManagerClient(t, tt.ts, tmc, func(ts *topo.Server) vtctlservicepb.VtctldServer { + return NewVtctldServer(ts) + }) + resp, err := vtctld.RefreshStateByShard(ctx, tt.req) + if tt.shouldErr { + assert.Error(t, err) + return + } + + require.NoError(t, err) + utils.MustMatch(t, tt.expected, resp) + }) + } +} + func TestRemoveKeyspaceCell(t *testing.T) { t.Parallel() diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go index ccc4e53c5b0..5423d72c5cf 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/test_tmclient.go @@ -162,6 +162,8 @@ type TabletManagerClient struct { Result string Error error } + // keyed by tablet alias. + RefreshStateResults map[string]error ReplicationStatusDelays map[string]time.Duration ReplicationStatusResults map[string]struct { Position *replicationdatapb.Status @@ -366,6 +368,20 @@ func (fake *TabletManagerClient) PromoteReplica(ctx context.Context, tablet *top return "", assert.AnError } +// RefreshState is part of the tmclient.TabletManagerClient interface. +func (fake *TabletManagerClient) RefreshState(ctx context.Context, tablet *topodatapb.Tablet) error { + if fake.RefreshStateResults == nil { + return fmt.Errorf("%w: no RefreshState results on fake TabletManagerClient", assert.AnError) + } + + key := topoproto.TabletAliasString(tablet.Alias) + if err, ok := fake.RefreshStateResults[key]; ok { + return err + } + + return fmt.Errorf("%w: no RefreshState result set for tablet %s", assert.AnError, key) +} + // ReplicationStatus is part of the tmclient.TabletManagerClient interface. func (fake *TabletManagerClient) ReplicationStatus(ctx context.Context, tablet *topodatapb.Tablet) (*replicationdatapb.Status, error) { if fake.ReplicationStatusResults == nil { From 69b786172e2560ba819d0732047242c3db35d4ae Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 1 Jun 2021 22:08:33 -0400 Subject: [PATCH 261/310] Add CLI entrypoints for `RefreshState` and `RefreshStateByShard` Signed-off-by: Andrew Mason --- .../vtctldclient/internal/command/tablets.go | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/go/cmd/vtctldclient/internal/command/tablets.go b/go/cmd/vtctldclient/internal/command/tablets.go index 65aef8298fd..9b2b4b41eea 100644 --- a/go/cmd/vtctldclient/internal/command/tablets.go +++ b/go/cmd/vtctldclient/internal/command/tablets.go @@ -54,6 +54,22 @@ var ( Args: cobra.NoArgs, RunE: commandGetTablets, } + // RefreshState makes a RefreshState gRPC call to a vtctld. + RefreshState = &cobra.Command{ + Use: "RefreshState ", + Short: "Reloads the tablet record on the specified tablet.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandRefreshState, + } + // RefreshStateByShard makes a RefreshStateByShard gRPC call to a vtcld. + RefreshStateByShard = &cobra.Command{ + Use: "RefreshStateByShard [--cell ...] ", + Short: "Reloads the tablet record all tablets in the shard, optionally limited to the specified cells.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandRefreshStateByShard, + } ) var changeTabletTypeOptions = struct { @@ -218,6 +234,60 @@ func commandGetTablets(cmd *cobra.Command, args []string) error { return nil } +func commandRefreshState(cmd *cobra.Command, args []string) error { + alias, err := topoproto.ParseTabletAlias(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + _, err = client.RefreshState(commandCtx, &vtctldatapb.RefreshStateRequest{ + TabletAlias: alias, + }) + if err != nil { + return err + } + + fmt.Printf("Refreshed state on %s\n", topoproto.TabletAliasString(alias)) + return nil +} + +var refreshStateByShardOptions = struct { + Cells []string +}{} + +func commandRefreshStateByShard(cmd *cobra.Command, args []string) error { + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } + + cli.FinishedParsing(cmd) + + resp, err := client.RefreshStateByShard(commandCtx, &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: keyspace, + Shard: shard, + Cells: refreshStateByShardOptions.Cells, + }) + if err != nil { + return err + } + + msg := &strings.Builder{} + msg.WriteString(fmt.Sprintf("Refreshed state on %s/%s", keyspace, shard)) + if len(refreshStateByShardOptions.Cells) > 0 { + msg.WriteString(fmt.Sprintf(" in cells %s", strings.Join(refreshStateByShardOptions.Cells, ", "))) + } + msg.WriteByte('\n') + if resp.IsPartialRefresh { + msg.WriteString("State refresh was partial; some tablets in the shard may not have succeeded.\n") + } + + fmt.Print(msg.String()) + return nil +} + func init() { ChangeTabletType.Flags().BoolVarP(&changeTabletTypeOptions.DryRun, "dry-run", "d", false, "Shows the proposed change without actually executing it") Root.AddCommand(ChangeTabletType) @@ -234,4 +304,9 @@ func init() { GetTablets.Flags().StringVar(&getTabletsOptions.Format, "format", "awk", "Output format to use; valid choices are (json, awk)") GetTablets.Flags().BoolVar(&getTabletsOptions.Strict, "strict", false, "Require all cells to return successful tablet data. Without --strict, tablet listings may be partial.") Root.AddCommand(GetTablets) + + Root.AddCommand(RefreshState) + + RefreshStateByShard.Flags().StringSliceVarP(&refreshStateByShardOptions.Cells, "cells", "c", nil, "If specified, only call RefreshState on tablets in the specified cells. If empty, all cells are considered.") + Root.AddCommand(RefreshStateByShard) } From e9f08e18c784b93543f0c2432664956b4329225b Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 1 Jun 2021 22:17:31 -0400 Subject: [PATCH 262/310] Add help texts to other tablet commands while I'm here Signed-off-by: Andrew Mason --- .../vtctldclient/internal/command/tablets.go | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/go/cmd/vtctldclient/internal/command/tablets.go b/go/cmd/vtctldclient/internal/command/tablets.go index 9b2b4b41eea..a8ff785a677 100644 --- a/go/cmd/vtctldclient/internal/command/tablets.go +++ b/go/cmd/vtctldclient/internal/command/tablets.go @@ -32,27 +32,53 @@ import ( var ( // ChangeTabletType makes a ChangeTabletType gRPC call to a vtctld. ChangeTabletType = &cobra.Command{ - Use: "ChangeTabletType [--dry-run] TABLET_ALIAS TABLET_TYPE", - Args: cobra.ExactArgs(2), - RunE: commandChangeTabletType, + Use: "ChangeTabletType [--dry-run] ", + Short: "Changes the db type for the specified tablet, if possible.", + Long: `Changes the db type for the specified tablet, if possible. + +This command is used primarily to arrange replicas, and it will not convert a primary. +NOTE: This command automatically updates the serving graph.`, + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(2), + RunE: commandChangeTabletType, } // DeleteTablets makes a DeleteTablets gRPC call to a vtctld. DeleteTablets = &cobra.Command{ - Use: "DeleteTablets TABLET_ALIAS [ TABLET_ALIAS ... ]", - Args: cobra.MinimumNArgs(1), - RunE: commandDeleteTablets, + Use: "DeleteTablets [ ... ]", + Short: "Deletes tablet(s) from the topology.", + DisableFlagsInUseLine: true, + Args: cobra.MinimumNArgs(1), + RunE: commandDeleteTablets, } // GetTablet makes a GetTablet gRPC call to a vtctld. GetTablet = &cobra.Command{ - Use: "GetTablet alias", - Args: cobra.ExactArgs(1), - RunE: commandGetTablet, + Use: "GetTablet ", + Short: "Outputs a JSON structure that contains information about the tablet.", + DisableFlagsInUseLine: true, + Args: cobra.ExactArgs(1), + RunE: commandGetTablet, } // GetTablets makes a GetTablets gRPC call to a vtctld. GetTablets = &cobra.Command{ - Use: "GetTablets [--strict] [{--cell $c1 [--cell $c2 ...], --keyspace $ks [--shard $shard], --tablet-alias $alias}]", - Args: cobra.NoArgs, - RunE: commandGetTablets, + Use: "GetTablets [--strict] [{--cell $c1 [--cell $c2 ...], --keyspace $ks [--shard $shard], --tablet-alias $alias}]", + Short: "Looks up tablets according to filter criteria.", + Long: `Looks up tablets according to the filter criteria. + +If --tablet-alias is passed, none of the other filters (keyspace, shard, cell) may +be passed, and tablets are looked up by tablet alias only. + +If --keyspace is passed, then all tablets in the keyspace are retrieved. The +--shard flag may also be passed to further narrow the set of tablets to that +. Passing --shard without also passing --keyspace will fail. + +Passing --cell limits the set of tablets to those in the specified cells. The +--cell flag accepts a CSV argument (e.g. --cell "c1,c2") and may be repeated +(e.g. --cell "c1" --cell "c2"). + +Valid output formats are "awk" and "json".`, + DisableFlagsInUseLine: true, + Args: cobra.NoArgs, + RunE: commandGetTablets, } // RefreshState makes a RefreshState gRPC call to a vtctld. RefreshState = &cobra.Command{ From 96c74575f9cce415e3a0bb6a94ee54741f4f1fde Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 1 Jun 2021 22:20:19 -0400 Subject: [PATCH 263/310] [vtctl] Swap out old implementation for new, transparently to callers Signed-off-by: Andrew Mason --- go/vt/vtctl/vtctl.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/go/vt/vtctl/vtctl.go b/go/vt/vtctl/vtctl.go index 4fa1c963894..41bf6f36d79 100644 --- a/go/vt/vtctl/vtctl.go +++ b/go/vt/vtctl/vtctl.go @@ -941,11 +941,11 @@ func commandRefreshState(ctx context.Context, wr *wrangler.Wrangler, subFlags *f if err != nil { return err } - tabletInfo, err := wr.TopoServer().GetTablet(ctx, tabletAlias) - if err != nil { - return err - } - return wr.TabletManagerClient().RefreshState(ctx, tabletInfo.Tablet) + + _, err = wr.VtctldServer().RefreshState(ctx, &vtctldatapb.RefreshStateRequest{ + TabletAlias: tabletAlias, + }) + return err } func commandRefreshStateByShard(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { @@ -961,16 +961,18 @@ func commandRefreshStateByShard(ctx context.Context, wr *wrangler.Wrangler, subF if err != nil { return err } - si, err := wr.TopoServer().GetShard(ctx, keyspace, shard) - if err != nil { - return err - } var cells []string if *cellsStr != "" { cells = strings.Split(*cellsStr, ",") } - return wr.RefreshTabletsByShard(ctx, si, cells) + + _, err = wr.VtctldServer().RefreshStateByShard(ctx, &vtctldatapb.RefreshStateByShardRequest{ + Keyspace: keyspace, + Shard: shard, + Cells: cells, + }) + return err } func commandRunHealthCheck(ctx context.Context, wr *wrangler.Wrangler, subFlags *flag.FlagSet, args []string) error { From ac75428d40d23b103d0e213d8444e178e61ab29e Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:29:18 +0300 Subject: [PATCH 264/310] lazy initialization of convertUsingUTF8Columns Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletserver/vstreamer/planbuilder.go | 25 ++++++++++++++++--- .../tabletserver/vstreamer/rowstreamer.go | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index b4cc346b5f8..29ee3e01d20 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -48,7 +48,7 @@ type Plan struct { // in the stream. ColExprs []ColExpr - convertToBinary map[string]bool + convertUsingUTF8Columns map[string]bool // Filters is the list of filters to be applied to the columns // of the table. @@ -401,8 +401,7 @@ func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, erro } plan := &Plan{ - Table: ti, - convertToBinary: map[string]bool{}, + Table: ti, } if err := plan.analyzeWhere(vschema, sel.Where); err != nil { log.Errorf("%s", err.Error()) @@ -444,6 +443,24 @@ func analyzeSelect(query string) (sel *sqlparser.Select, fromTable sqlparser.Tab return sel, fromTable, nil } +// isConvertColumnUsingUTF8 returns 'true' when given column needs to be converted as UTF8 +// while read from source table +func (plan *Plan) isConvertColumnUsingUTF8(columnName string) bool { + if plan.convertUsingUTF8Columns == nil { + return false + } + return plan.convertUsingUTF8Columns[columnName] +} + +// setConvertColumnUsingUTF8 marks given column as needs to be converted as UTF8 +// while read from source table +func (plan *Plan) setConvertColumnUsingUTF8(columnName string) { + if plan.convertUsingUTF8Columns == nil { + plan.convertUsingUTF8Columns = map[string]bool{} + } + plan.convertUsingUTF8Columns[columnName] = true +} + func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) error { if where == nil { return nil @@ -612,7 +629,7 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp return ColExpr{}, err } field := plan.Table.Fields[colnum] - plan.convertToBinary[field.Name] = true + plan.setConvertColumnUsingUTF8(field.Name) return ColExpr{ ColNum: colnum, Field: field, diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index e934fb51ac6..2afbf181b92 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -171,7 +171,7 @@ func (rs *rowStreamer) buildSelect() (string, error) { buf.Myprintf("select ") prefix := "" for _, col := range rs.plan.Table.Fields { - if rs.plan.convertToBinary[col.Name] { + if rs.plan.isConvertColumnUsingUTF8(col.Name) { // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) buf.Myprintf("%sconvert(%v using utf8mb4)", prefix, sqlparser.NewColIdent(col.Name)) From fc63022bf1ae76df4a5505bd2ec760eb4f37e23a Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:36:48 +0300 Subject: [PATCH 265/310] strictly check for NULL Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletmanager/vreplication/replicator_plan.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 39df9a736fa..7a3b375e2d7 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -303,20 +303,20 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun after = true vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { - if enumValues, ok := tp.EnumValuesMap[field.Name]; ok && vals[i].IsQuoted() { + val := &vals[i] + if enumValues, ok := tp.EnumValuesMap[field.Name]; ok && !val.IsNull() { // The fact that this fielkd has a EnumValuesMap entry, means we must // use the enum's text value as opposed to the enum's numerical value. // Once known use case is with Online DDL, when a column is converted from // ENUM to a VARCHAR/TEXT. - // The above vals[i].IsQuoted() helps us to exclude a NULL value - enumValue, enumValueOK := enumValues[vals[i].ToString()] + enumValue, enumValueOK := enumValues[val.ToString()] if !enumValueOK { - return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Invalid enum value: %v for field %s", vals[i], field.Name) + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Invalid enum value: %v for field %s", val, field.Name) } // get the enum text fir this val bindvars["a_"+field.Name] = sqltypes.StringBindVariable(enumValue) } else { - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(vals[i]) + bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(*val) } } } From a921f2cacda30844a1f0534f8ecab66a3b746070 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:55:05 +0300 Subject: [PATCH 266/310] test for NULL values Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql | 1 + .../vrepl_suite/testdata/alter-charset-non-utf8/create.sql | 1 + 2 files changed, 2 insertions(+) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql index 6f97756291b..26bae0cc966 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8-80/create.sql @@ -26,4 +26,5 @@ begin insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); insert into onlineddl_test values (null, 'testátest-binlog', 'testátest-binlog', 'testátest-binlog', '🍻😀', 'átesting-binlog'); + insert into onlineddl_test values (null, 'átesting-bnull', 'átesting-bnull', 'átesting-bnull', null, null); end ;; diff --git a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql index d0d19253449..72df20e51ad 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/alter-charset-non-utf8/create.sql @@ -24,4 +24,5 @@ create event onlineddl_test begin insert into onlineddl_test values (null, md5(rand()), md5(rand()), md5(rand()), md5(rand()), md5(rand())); insert into onlineddl_test values (null, 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog', 'átesting-binlog'); + insert into onlineddl_test values (null, 'átesting-bnull', 'átesting-bnull', 'átesting-bnull', null, null); end ;; From 594d2b99c9b0afb4ba49b725f70482d74d67df6a Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:55:32 +0300 Subject: [PATCH 267/310] strip comments; more to go Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 34 +------------------------------ 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 7cefafbf4ea..2a75a2180bc 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -231,9 +231,6 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect column.BinaryOctetLength = columnOctetLength } if charset := row.AsString("CHARACTER_SET_NAME", ""); charset != "" { - // if !strings.HasPrefix(charset, "utf8") { - // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Vitess does not support charset '%s'. Only utf8 and derivatives (like utf8mb4) are supported", charset) - // } column.Charset = charset } if collation := row.AsString("COLLATION_NAME", ""); collation != "" { @@ -404,10 +401,6 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) } if true || sourceCol.Collation != targetCol.Collation { - // sourceEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] - // if !ok { - // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) - // } fromEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] if !ok { return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) @@ -422,33 +415,8 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { FromCharset: sourceCol.Charset, ToCharset: targetCol.Charset, } - fmt.Printf("============ v.convertCharset[targetName]: %v, %v\n", targetName, v.convertCharset[targetName]) } - fmt.Printf("============ collcation change: %s => %s\n", sourceCol.Collation, targetCol.Collation) - if strings.HasPrefix(sourceCol.Charset, "utf8") { - // sb.WriteString(escapeName(name)) - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) - } else { - // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - } - // if strings.HasPrefix(targetCol.Charset, "utf8") { - // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // } else if strings.HasPrefix(sourceCol.Charset, "utf8") { - // // sb.WriteString(fmt.Sprintf("cast(%s as binary)", escapeName(name))) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // } else { - // // sb.WriteString(fmt.Sprintf("convert(%s USING %s)", escapeName(name), targetCol.Charset)) - // sb.WriteString(fmt.Sprintf("convert(%s USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // // sb.WriteString(fmt.Sprintf("convert(convert(%s USING binary) USING %s) COLLATE %s", escapeName(name), targetCol.Charset, targetCol.Collation)) - // } + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) } else { sb.WriteString(escapeName(name)) } From 2da4b7eaf03d17625da80ff5ff7db0739789c964 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:56:04 +0300 Subject: [PATCH 268/310] strip comments; more to go Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go | 1 - 1 file changed, 1 deletion(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 529d1028ac5..9e6c589741a 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -354,7 +354,6 @@ func analyzeSelectFrom(query string) (sel *sqlparser.Select, from string, err er func (tpb *tablePlanBuilder) analyzeExprs(selExprs sqlparser.SelectExprs) error { for _, selExpr := range selExprs { cexpr, err := tpb.analyzeExpr(selExpr) - fmt.Printf("============ selExpr: %v, cexpr.expr: %v\n", sqlparser.String(selExpr), sqlparser.String(cexpr.expr)) if err != nil { return err } From 0c669938fe7b17e6a49e77262d2c864169699896 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 08:59:07 +0300 Subject: [PATCH 269/310] refactor, simplify Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 2a75a2180bc..f2e3595d78d 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -400,7 +400,9 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { if targetCol == nil { return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Cannot find target column %s", targetName) } - if true || sourceCol.Collation != targetCol.Collation { + { + // Check source and target charset/encoding. If needed, create + // a binlogdatapb.CharsetConversion entry (later written to vreplication) fromEncoding, ok := mysql.CharacterSetEncoding[sourceCol.Charset] if !ok { return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", sourceCol.Charset, sourceCol.Name) @@ -416,10 +418,9 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { ToCharset: targetCol.Charset, } } - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) - } else { - sb.WriteString(escapeName(name)) } + // We will always read strings as utf8mb4. + sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) default: sb.WriteString(escapeName(name)) } From a4e1114ae739a71f540797c935dfb51cde7894a0 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:21:17 +0300 Subject: [PATCH 270/310] refactor: extract bindFiledVar function Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vreplication/replicator_plan.go | 69 ++++++++----------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 3e9eb11f814..75125dcb349 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -289,6 +289,33 @@ func (tp *TablePlan) isOutsidePKRange(bindvars map[string]*querypb.BindVariable, return false } +// bindFieldVal returns a bind variable based on given field and value. +// Most values will just bind directly. But some values may need manipulation: +// - text values with charset conversion +// - enum values converted to text via Online DDL +// - ...any other future possible values +func (tp *TablePlan) bindFieldVal(field *querypb.Field, val *sqltypes.Value) (*querypb.BindVariable, error) { + if conversion, ok := tp.ConvertCharset[field.Name]; ok && !val.IsNull() { + // Non-null string value, for which we have a charset conversion instruction + valString := val.ToString() + fromEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.FromCharset] + if !encodingOK { + return nil, vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.FromCharset, field.Name) + } + if fromEncoding != nil { + // As reminder, encoding can be nil for trivial charsets, like utf8 or ascii. + // encoding will be non-nil for charsets like latin1, gbk, etc. + var err error + valString, err = fromEncoding.NewDecoder().String(valString) + if err != nil { + return nil, err + } + } + return sqltypes.StringBindVariable(valString), nil + } + return sqltypes.ValueBindVariable(*val), nil +} + func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor func(string) (*sqltypes.Result, error)) (*sqltypes.Result, error) { // MakeRowTrusted is needed here because Proto3ToResult is not convenient. var before, after bool @@ -305,47 +332,11 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { val := &vals[i] - bindVal := func() (err error) { - if conversion, ok := tp.ConvertCharset[field.Name]; ok && !val.IsNull() { - valString := val.ToString() - fmt.Printf("=========== ConvertCharset[field.Name]: %v, %v \n", field.Name, conversion) - fmt.Printf("=========== s0: %v \n", valString) - - fromEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.FromCharset] - if !encodingOK { - return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.FromCharset, field.Name) - } - if fromEncoding != nil { - fmt.Printf("=========== ConvertCharset fromEncoding: %v, %v \n", field.Name, fromEncoding) - valString, err = fromEncoding.NewDecoder().String(valString) - if err != nil { - return err - } - fmt.Printf("=========== s1: %v \n", valString) - } - - // // There is a request to encode given charset - // toEncoding, encodingOK := mysql.CharacterSetEncoding[conversion.ToCharset] - // if !encodingOK { - // return vterrors.Errorf(vtrpcpb.Code_INVALID_ARGUMENT, "Character set %s not supported for column %s", conversion.ToCharset, field.Name) - // } - // if toEncoding != nil { - // fmt.Printf("=========== ConvertCharset toEncoding: %v, %v \n", field.Name, toEncoding) - // valString, err = toEncoding.NewEncoder().String(valString) - // if err != nil { - // return err - // } - // fmt.Printf("=========== s2: %v \n", valString) - // } - bindvars["a_"+field.Name] = sqltypes.StringBindVariable(valString) - return nil - } - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(*val) - return nil - } - if err := bindVal(); err != nil { + bindVar, err := tp.bindFieldVal(field, val) + if err != nil { return nil, err } + bindvars["a_"+field.Name] = bindVar } } switch { From 9d392930832936c724745ae7689718472aa4b20e Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:21:36 +0300 Subject: [PATCH 271/310] remove comments Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vttablet/tabletmanager/vreplication/table_plan_builder.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 9e6c589741a..7122e3e1557 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -186,7 +186,6 @@ func MatchTable(tableName string, filter *binlogdatapb.Filter) (*binlogdatapb.Ru func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInfo, lastpk *sqltypes.Result, convertCharset map[string](*binlogdatapb.CharsetConversion), stats *binlogplayer.Stats) (*TablePlan, error) { query := filter // generate equivalent select statement if filter is empty or a keyrange. - fmt.Printf("============ filter: %v\n", filter) switch { case filter == "": buf := sqlparser.NewTrackedBuffer(nil) @@ -239,9 +238,6 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf stats: stats, } - for _, s := range sel.SelectExprs { - fmt.Printf("============ SelectExpr: %v\n", sqlparser.String(s)) - } if err := tpb.analyzeExprs(sel.SelectExprs); err != nil { return nil, err } From 7a2ba41f5ccc761c193fc5a3ac7587d7e2f9f471 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:25:50 +0300 Subject: [PATCH 272/310] remvoe comments Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vreplication/table_plan_builder.go | 28 ------------------- .../tabletmanager/vreplication/vcopier.go | 2 -- .../tabletserver/vstreamer/planbuilder.go | 3 -- .../tabletserver/vstreamer/rowstreamer.go | 5 ---- 4 files changed, 38 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 7122e3e1557..01d2d214b64 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -269,9 +269,7 @@ func buildTablePlan(tableName, filter string, colInfoMap map[string][]*ColumnInf }, }) } - fmt.Printf("============ sendSelect.SelectExprs [3]: %v\n", sqlparser.String(tpb.sendSelect.SelectExprs)) sendRule.Filter = sqlparser.String(tpb.sendSelect) - fmt.Printf("============ sendRule.Filter: %v\n", sendRule.Filter) tablePlan := tpb.generate() tablePlan.SendRule = sendRule @@ -377,46 +375,20 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr references: make(map[string]bool), } if expr, ok := aliased.Expr.(*sqlparser.ConvertUsingExpr); ok { - fmt.Printf("============ ConvertUsingExpr: %v\n", sqlparser.String(expr)) selExpr := &sqlparser.ConvertUsingExpr{ Type: "utf8mb4", Expr: &sqlparser.ColName{Name: as}, } - fmt.Printf("============ ConvertUsingExpr generated: %v\n", sqlparser.String(selExpr)) cexpr.expr = expr cexpr.operation = opExpr tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) return cexpr, nil } if expr, ok := aliased.Expr.(*sqlparser.ConvertExpr); ok { - // convertAsBinary := fmt.Sprintf("convert(%s, binary) as %s", sqlparser.String(as), sqlparser.String(as)) - // fmt.Printf("============ convertAsBinary: %v\n", convertAsBinary) - // convertAsBinaryExpr, err := sqlparser.Parse(convertAsBinary) - // fmt.Printf("============ convertAsBinaryExpr, err: %v, %v\n", convertAsBinaryExpr, err) - // if err != nil { - // return nil, err - // } - // expr, ok := convertAsBinaryExpr.(*sqlparser.ConvertExpr) - fmt.Printf("============ ConvertExpr: %v\n", sqlparser.String(expr)) - fmt.Printf("============ ConvertExpr.Type: %v\n", expr.Type) - fmt.Printf("============ ConvertExpr.Type.Type: %v\n", expr.Type.Type) - fmt.Printf("============ ConvertExpr.Type.Charset: %v\n", expr.Type.Charset) - fmt.Printf("============ ConvertExpr.Expr: %v\n", expr.Expr) - // expr.Type:= - // type ConvertType struct { - // Type string - // Length *Literal - // Scale *Literal - // Operator ConvertTypeOperator - // Charset string - // } - // expr.Type = &sqlparser.ConvertType{Type: "binary"} - // expr.Expr = as selExpr := &sqlparser.ConvertExpr{ Type: &sqlparser.ConvertType{Type: "binary"}, Expr: &sqlparser.ColName{Name: as}, } - fmt.Printf("============ ConvertExpr generated: %v\n", sqlparser.String(selExpr)) cexpr.expr = expr cexpr.operation = opExpr tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go index 25ca3e90cf1..6472d0b79e5 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier.go @@ -200,7 +200,6 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma log.Infof("Copying table %s, lastpk: %v", tableName, copyState[tableName]) - fmt.Printf("============ buildReplicatorPlan( ivc.vr.source.Filter: %v\n", vc.vr.source.Filter) plan, err := buildReplicatorPlan(vc.vr.source.Filter, vc.vr.colInfoMap, nil, vc.vr.stats) if err != nil { return err @@ -223,7 +222,6 @@ func (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState ma var updateCopyState *sqlparser.ParsedQuery var bv map[string]*querypb.BindVariable var sqlbuffer bytes2.Buffer - fmt.Printf("============ VStreamRows( initialPlan.SendRule.Filter: %v\n", initialPlan.SendRule.Filter) err = vc.vr.sourceVStreamer.VStreamRows(ctx, initialPlan.SendRule.Filter, lastpkpb, func(rows *binlogdatapb.VStreamRowsResponse) error { for { select { diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 29ee3e01d20..5149c3d36ab 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -407,7 +407,6 @@ func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, erro log.Errorf("%s", err.Error()) return nil, err } - fmt.Printf("========= buildTablePlan.analyzeExprs: sel.SelectExprs: %v, %v\n", len(sel.SelectExprs), sqlparser.String(sel.SelectExprs)) if err := plan.analyzeExprs(vschema, sel.SelectExprs); err != nil { log.Errorf("%s", err.Error()) return nil, err @@ -557,7 +556,6 @@ func (plan *Plan) analyzeExprs(vschema *localVSchema, selExprs sqlparser.SelectE } func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err error) { - fmt.Printf("========= Plan: analyzeExpr selExpr s: %v\n", sqlparser.String(selExpr)) aliased, ok := selExpr.(*sqlparser.AliasedExpr) if !ok { return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(selExpr)) @@ -624,7 +622,6 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp }, nil case *sqlparser.ConvertExpr, *sqlparser.ConvertUsingExpr: colnum, err := findColumn(plan.Table, aliased.As) - fmt.Printf("========= findColumn2: %v, %v \n", colnum, err) if err != nil { return ColExpr{}, err } diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go index 2afbf181b92..d1e5aaec9f6 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer.go @@ -113,7 +113,6 @@ func (rs *rowStreamer) Stream() error { func (rs *rowStreamer) buildPlan() error { // This pre-parsing is required to extract the table name // and create its metadata. - fmt.Printf("========= analyzeSelect: %v\n", rs.query) _, fromTable, err := analyzeSelect(rs.query) if err != nil { return err @@ -140,7 +139,6 @@ func (rs *rowStreamer) buildPlan() error { return err } rs.sendQuery, err = rs.buildSelect() - fmt.Printf("================= rs.sendQuery: %v\n", rs.sendQuery) if err != nil { return err } @@ -172,10 +170,7 @@ func (rs *rowStreamer) buildSelect() (string, error) { prefix := "" for _, col := range rs.plan.Table.Fields { if rs.plan.isConvertColumnUsingUTF8(col.Name) { - // fmt.Printf("========== WOOHOO! convertToBinary for %v\n", col.Name) - // buf.Myprintf("%sconvert(convert(%v using binary) using utf8)", prefix, sqlparser.NewColIdent(col.Name)) buf.Myprintf("%sconvert(%v using utf8mb4)", prefix, sqlparser.NewColIdent(col.Name)) - // buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } else { buf.Myprintf("%s%v", prefix, sqlparser.NewColIdent(col.Name)) } From 4ec59590184995d2d5f5054267e2a1c47227f47c Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:38:49 +0300 Subject: [PATCH 273/310] vrepl.IntegerColumnType is for a different PR Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index f2e3595d78d..d935a9da1e5 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -219,9 +219,6 @@ func (v *VRepl) applyColumnTypes(ctx context.Context, conn *dbconnpool.DBConnect if strings.Contains(columnType, "float") { column.Type = vrepl.FloatColumnType } - if strings.Contains(columnType, "int") { - column.Type = vrepl.IntegerColumnType - } if strings.HasPrefix(columnType, "enum") { column.Type = vrepl.EnumColumnType column.EnumValues = vrepl.ParseEnumValues(columnType) @@ -420,7 +417,7 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } } // We will always read strings as utf8mb4. - sb.WriteString(fmt.Sprintf("convert(%s USING utf8mb4)", escapeName(name))) + sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) default: sb.WriteString(escapeName(name)) } From 60eb70dc7739c4a873c74210eea92b952658153b Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:40:03 +0300 Subject: [PATCH 274/310] ConvertUsingExpr is the only hint vreplication/plan sends to vstreamer/plan ; ConvertExpr not needed Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../tabletmanager/vreplication/table_plan_builder.go | 10 ---------- go/vt/vttablet/tabletserver/vstreamer/planbuilder.go | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 01d2d214b64..734f119be60 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -384,16 +384,6 @@ func (tpb *tablePlanBuilder) analyzeExpr(selExpr sqlparser.SelectExpr) (*colExpr tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) return cexpr, nil } - if expr, ok := aliased.Expr.(*sqlparser.ConvertExpr); ok { - selExpr := &sqlparser.ConvertExpr{ - Type: &sqlparser.ConvertType{Type: "binary"}, - Expr: &sqlparser.ColName{Name: as}, - } - cexpr.expr = expr - cexpr.operation = opExpr - tpb.sendSelect.SelectExprs = append(tpb.sendSelect.SelectExprs, &sqlparser.AliasedExpr{Expr: selExpr, As: as}) - return cexpr, nil - } if expr, ok := aliased.Expr.(*sqlparser.FuncExpr); ok { if expr.Distinct { return nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 5149c3d36ab..8eabce49642 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -620,7 +620,7 @@ func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExp ColNum: -1, FixedValue: sqltypes.NewInt64(num), }, nil - case *sqlparser.ConvertExpr, *sqlparser.ConvertUsingExpr: + case *sqlparser.ConvertUsingExpr: colnum, err := findColumn(plan.Table, aliased.As) if err != nil { return ColExpr{}, err From 8043874a8bbd9a791aeadcf71ee31c5640426ebf Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:14:16 +0300 Subject: [PATCH 275/310] adding test: convert-utf8mb4 Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vrepl_suite/{untestdata => testdata}/convert-utf8mb4/alter | 0 .../{untestdata => testdata}/convert-utf8mb4/create.sql | 3 --- 2 files changed, 3 deletions(-) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata => testdata}/convert-utf8mb4/alter (100%) rename go/test/endtoend/onlineddl/vrepl_suite/{untestdata => testdata}/convert-utf8mb4/create.sql (94%) diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/alter b/go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/alter similarity index 100% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/alter rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/alter diff --git a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/create.sql b/go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/create.sql similarity index 94% rename from go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/create.sql rename to go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/create.sql index a2a662fe23c..54963d7ff17 100644 --- a/go/test/endtoend/onlineddl/vrepl_suite/untestdata/convert-utf8mb4/create.sql +++ b/go/test/endtoend/onlineddl/vrepl_suite/testdata/convert-utf8mb4/create.sql @@ -7,9 +7,6 @@ create table onlineddl_test ( primary key(id) ) auto_increment=1; -insert into onlineddl_test values (null, 'átesting'); - - insert into onlineddl_test values (null, 'Hello world, Καλημέρα κόσμε, コンニチハ', 'átesting0', 'initial'); drop event if exists onlineddl_test; From a9c30c4f28d5c9e1f689145eba40fef271178d05 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 14 Jun 2021 12:55:39 +0530 Subject: [PATCH 276/310] check if starExpr has qualifier and then only expand for that table Signed-off-by: Harshit Gangal --- go/vt/vtgate/planbuilder/route_planning.go | 29 +++++++++++++++---- .../vtgate/planbuilder/route_planning_test.go | 6 ++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/go/vt/vtgate/planbuilder/route_planning.go b/go/vt/vtgate/planbuilder/route_planning.go index 4cedb6e137d..7c179729542 100644 --- a/go/vt/vtgate/planbuilder/route_planning.go +++ b/go/vt/vtgate/planbuilder/route_planning.go @@ -108,21 +108,38 @@ func expandStar(sel *sqlparser.Select, semTable *semantics.SemTable) *sqlparser. tables := semTable.GetSelectTables(node) var selExprs sqlparser.SelectExprs for _, selectExpr := range node.SelectExprs { - _, isStarExpr := selectExpr.(*sqlparser.StarExpr) + starExpr, isStarExpr := selectExpr.(*sqlparser.StarExpr) if !isStarExpr { selExprs = append(selExprs, selectExpr) continue } - //if !starExpr.TableName.IsEmpty() { - // // TODO: only expand specific table - //} var colNames sqlparser.SelectExprs - expandStar := true + expandStar := false for _, tbl := range tables { + if !starExpr.TableName.IsEmpty() { + if !tbl.ASTNode.As.IsEmpty() { + if !starExpr.TableName.Qualifier.IsEmpty() { + continue + } + if starExpr.TableName.Name.String() != tbl.ASTNode.As.String() { + continue + } + } else { + if !starExpr.TableName.Qualifier.IsEmpty() { + if starExpr.TableName.Qualifier.String() != tbl.Table.Keyspace.Name { + continue + } + } + tblName := tbl.ASTNode.Expr.(sqlparser.TableName) + if starExpr.TableName.Name.String() != tblName.Name.String() { + continue + } + } + } if !tbl.Table.ColumnListAuthoritative { - expandStar = false break } + expandStar = true for _, col := range tbl.Table.Columns { colNames = append(colNames, &sqlparser.AliasedExpr{ Expr: sqlparser.NewColNameWithQualifier(col.Name.String(), sqlparser.TableName{Name: tbl.Table.Name}), diff --git a/go/vt/vtgate/planbuilder/route_planning_test.go b/go/vt/vtgate/planbuilder/route_planning_test.go index 8e2f1ee3950..c17ae60efb2 100644 --- a/go/vt/vtgate/planbuilder/route_planning_test.go +++ b/go/vt/vtgate/planbuilder/route_planning_test.go @@ -187,6 +187,12 @@ func TestExpandStar(t *testing.T) { }, { sql: "select t1.* from t1, t2", expSQL: "select t1.a, t1.b, t1.c from t1, t2", + }, { + sql: "select *, t1.* from t1, t2", + expSQL: "select t1.a, t1.b, t1.c, t2.c1, t2.c2, t1.a, t1.b, t1.c from t1, t2", + }, { // TODO: This should fail on analyze step and should not reach down. + sql: "select t3.* from t1, t2", + expSQL: "select t3.* from t1, t2", }} for _, tcase := range tcases { t.Run(tcase.sql, func(t *testing.T) { From f947bd1c0f62f80054a66211f1a908f05f6ad77e Mon Sep 17 00:00:00 2001 From: Alkin Tezuysal Date: Mon, 14 Jun 2021 10:55:39 +0300 Subject: [PATCH 277/310] include squashed PRs in release notes Signed-off-by: Alkin Tezuysal --- go/tools/release-notes/release_notes.go | 19 +++++++++++++------ go/tools/release-notes/release_notes_test.go | 8 ++++---- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/go/tools/release-notes/release_notes.go b/go/tools/release-notes/release_notes.go index 63acecd5ac0..f7025e3af8e 100644 --- a/go/tools/release-notes/release_notes.go +++ b/go/tools/release-notes/release_notes.go @@ -94,6 +94,7 @@ func loadMergedPRs(from, to string) (prs []string, authors []string, commitCount func parseGitLog(s string) (prs []string, authorCommits []string, commitCount int, err error) { rx := regexp.MustCompile(`(.+)\t(.+)\t(.+)\t(.+)`) mergePR := regexp.MustCompile(`Merge pull request #(\d+)`) + squashPR := regexp.MustCompile(`\(#(\d+)\)`) authMap := map[string]string{} // here we will store email <-> gh user mappings lines := strings.Split(s, "\n") for _, line := range lines { @@ -112,13 +113,19 @@ func parseGitLog(s string) (prs []string, authorCommits []string, commitCount in continue } - if len(parents) > lengthOfSingleSHA { - // if we have two parents, it means this is a merge commit. we only count non-merge commits - continue + if len(parents) <= lengthOfSingleSHA { + // we have a single parent, and the commit counts + commitCount++ + if _, exists := authMap[authorEmail]; !exists { + authMap[authorEmail] = sha + } } - commitCount++ - if _, exists := authMap[authorEmail]; !exists { - authMap[authorEmail] = sha + + squashed := squashPR.FindStringSubmatch(title) + if len(squashed) == 2 { + // this is a merged PR. remember the PR # + prs = append(prs, squashed[1]) + continue } } diff --git a/go/tools/release-notes/release_notes_test.go b/go/tools/release-notes/release_notes_test.go index 8b4a2299336..b4d358bba46 100644 --- a/go/tools/release-notes/release_notes_test.go +++ b/go/tools/release-notes/release_notes_test.go @@ -98,9 +98,9 @@ aquarapTEST@gmail.com Fix mysql80 docker build with dep. a28591577b8d432b9c5d78a TEST@planetscale.com Revert "docker/lite/install_dependencies.sh: Upgrade MySQL 8 to 8.0.24" 7858ff46545cff749b3663c92ae90ef27a5dfbc2 27a5dfbc2 TEST@planetscale.com docker/lite/install_dependencies.sh: Upgrade MySQL 8 to 8.0.24 c91d46782933292941a846fef2590ff1a6fa193f a6fa193f` - prs, authorCommits, count, err := parseGitLog(in) + prs, authorCommits, nonMergeCommits, err := parseGitLog(in) require.NoError(t, err) - assert.Equal(t, []string{"7629", "7831", "7912", "7943", "7951", "7959", "7964", "7968", "7970"}, prs) - assert.Equal(t, []string{"385d0b327", "3b744e782", "4a0a943b0", "538709da5", "616f5562c", "6b9a731a2", "e5242a88a", "edac2baf8"}, authorCommits) - assert.Equal(t, 28, count) + assert.Equal(t, prs, []string{"7629", "7831", "7912", "7934", "7943", "7951", "7959", "7964", "7968", "7970"}) + assert.Equal(t, authorCommits, []string{"385d0b327", "3b744e782", "4a0a943b0", "538709da5", "616f5562c", "6b9a731a2", "e5242a88a", "edac2baf8"}) + assert.Equal(t, 28, nonMergeCommits) } From e1ff59a5839e7f7333fb67a97c80f4133f098ab6 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 11:01:12 +0300 Subject: [PATCH 278/310] refactor: extract bindFieldVal outside applyChange Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .../vreplication/replicator_plan.go | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go index 7a3b375e2d7..2bbce2202b8 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go +++ b/go/vt/vttablet/tabletmanager/vreplication/replicator_plan.go @@ -288,6 +288,27 @@ func (tp *TablePlan) isOutsidePKRange(bindvars map[string]*querypb.BindVariable, return false } +// bindFieldVal returns a bind variable based on given field and value. +// Most values will just bind directly. But some values may need manipulation: +// - text values with charset conversion +// - enum values converted to text via Online DDL +// - ...any other future possible values +func (tp *TablePlan) bindFieldVal(field *querypb.Field, val *sqltypes.Value) (*querypb.BindVariable, error) { + if enumValues, ok := tp.EnumValuesMap[field.Name]; ok && !val.IsNull() { + // The fact that this fielkd has a EnumValuesMap entry, means we must + // use the enum's text value as opposed to the enum's numerical value. + // Once known use case is with Online DDL, when a column is converted from + // ENUM to a VARCHAR/TEXT. + enumValue, enumValueOK := enumValues[val.ToString()] + if !enumValueOK { + return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Invalid enum value: %v for field %s", val, field.Name) + } + // get the enum text fir this val + return sqltypes.StringBindVariable(enumValue), nil + } + return sqltypes.ValueBindVariable(*val), nil +} + func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor func(string) (*sqltypes.Result, error)) (*sqltypes.Result, error) { // MakeRowTrusted is needed here because Proto3ToResult is not convenient. var before, after bool @@ -304,20 +325,11 @@ func (tp *TablePlan) applyChange(rowChange *binlogdatapb.RowChange, executor fun vals := sqltypes.MakeRowTrusted(tp.Fields, rowChange.After) for i, field := range tp.Fields { val := &vals[i] - if enumValues, ok := tp.EnumValuesMap[field.Name]; ok && !val.IsNull() { - // The fact that this fielkd has a EnumValuesMap entry, means we must - // use the enum's text value as opposed to the enum's numerical value. - // Once known use case is with Online DDL, when a column is converted from - // ENUM to a VARCHAR/TEXT. - enumValue, enumValueOK := enumValues[val.ToString()] - if !enumValueOK { - return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "Invalid enum value: %v for field %s", val, field.Name) - } - // get the enum text fir this val - bindvars["a_"+field.Name] = sqltypes.StringBindVariable(enumValue) - } else { - bindvars["a_"+field.Name] = sqltypes.ValueBindVariable(*val) + bindVar, err := tp.bindFieldVal(field, val) + if err != nil { + return nil, err } + bindvars["a_"+field.Name] = bindVar } } switch { From 44b8a17215b9864570d5ad17d133ee070cafeb35 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 11:12:23 +0300 Subject: [PATCH 279/310] Rename proto field name Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/proto/binlogdata/binlogdata.pb.go | 510 +++++++++--------- .../proto/binlogdata/binlogdata_vtproto.pb.go | 18 +- go/vt/vttablet/onlineddl/vrepl.go | 30 +- .../vreplication/table_plan_builder.go | 2 +- proto/binlogdata.proto | 6 +- 5 files changed, 284 insertions(+), 282 deletions(-) diff --git a/go/vt/proto/binlogdata/binlogdata.pb.go b/go/vt/proto/binlogdata/binlogdata.pb.go index fd65cda5f94..ece3d31fb90 100644 --- a/go/vt/proto/binlogdata/binlogdata.pb.go +++ b/go/vt/proto/binlogdata/binlogdata.pb.go @@ -752,11 +752,8 @@ type Rule struct { // to be excluded. // TODO(sougou): support this on vstreamer side also. Filter string `protobuf:"bytes,2,opt,name=filter,proto3" json:"filter,omitempty"` - // EnumText: optional, list per enum column name, the list of textual values. - // When reading the binary log, all enum values are numeric. But sometimes it - // is useful/needed to know what the textual mapping are. - // Online DDL provides such use case. - EnumText map[string]string `protobuf:"bytes,3,rep,name=enum_text,json=enumText,proto3" json:"enum_text,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // Example: key="color", value="'red','green','blue'" + ConvertEnumToText map[string]string `protobuf:"bytes,3,rep,name=convert_enum_to_text,json=convertEnumToText,proto3" json:"convert_enum_to_text,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *Rule) Reset() { @@ -805,9 +802,9 @@ func (x *Rule) GetFilter() string { return "" } -func (x *Rule) GetEnumText() map[string]string { +func (x *Rule) GetConvertEnumToText() map[string]string { if x != nil { - return x.EnumText + return x.ConvertEnumToText } return nil } @@ -2418,259 +2415,262 @@ var file_binlogdata_proto_rawDesc = []byte{ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x11, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xae, 0x01, + 0x6f, 0x67, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xd4, 0x01, 0x0a, 0x04, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x09, 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x65, 0x78, - 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x65, - 0x78, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x65, 0x6e, 0x75, 0x6d, 0x54, 0x65, 0x78, - 0x74, 0x1a, 0x3b, 0x0a, 0x0d, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, - 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x05, 0x72, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, - 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, - 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, - 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x2e, 0x46, 0x69, - 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x36, 0x0a, 0x0e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x13, - 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, - 0x52, 0x54, 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, - 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, - 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, - 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, - 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, 0x64, 0x64, 0x6c, 0x18, 0x07, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x6f, 0x6e, - 0x44, 0x64, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, - 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, - 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, - 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x70, 0x79, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, - 0x70, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x22, 0x51, 0x0a, - 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x22, 0x0a, 0x06, 0x62, 0x65, - 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x12, 0x20, - 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, - 0x22, 0x61, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, - 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, - 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, - 0x67, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, - 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x4b, - 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, - 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, - 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, - 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, - 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, - 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, - 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x61, - 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x0c, 0x70, 0x61, 0x72, - 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, - 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, - 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, - 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1c, 0x0a, - 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x09, 0x72, - 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x37, - 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0a, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, - 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, - 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, - 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x64, 0x6d, - 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, - 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, - 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, - 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, - 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, - 0x70, 0x5f, 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, - 0x03, 0x52, 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x22, 0x41, 0x0a, 0x0d, - 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, - 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, - 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, - 0xc7, 0x02, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, - 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, - 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, - 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, - 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, - 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x58, 0x0a, 0x14, 0x63, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x5f, + 0x65, 0x6e, 0x75, 0x6d, 0x5f, 0x74, 0x6f, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x52, 0x75, 0x6c, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x75, 0x6d, + 0x54, 0x6f, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x63, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x54, 0x65, 0x78, 0x74, 0x1a, 0x44, + 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x75, 0x6d, 0x54, 0x6f, 0x54, + 0x65, 0x78, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb3, 0x01, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x26, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x75, 0x6c, 0x65, + 0x52, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x49, 0x0a, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x21, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, + 0x64, 0x65, 0x52, 0x0e, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4d, 0x6f, + 0x64, 0x65, 0x22, 0x36, 0x0a, 0x0e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x52, 0x52, 0x5f, 0x4f, 0x4e, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x42, 0x45, 0x53, + 0x54, 0x5f, 0x45, 0x46, 0x46, 0x4f, 0x52, 0x54, 0x10, 0x01, 0x22, 0x96, 0x03, 0x0a, 0x0c, 0x42, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x35, 0x0a, + 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x5f, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x52, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x2a, 0x0a, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, - 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x2e, 0x0a, 0x06, 0x6f, 0x6e, 0x5f, + 0x64, 0x64, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x05, 0x6f, 0x6e, 0x44, 0x64, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x4d, 0x79, 0x73, 0x71, 0x6c, + 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x61, 0x66, 0x74, 0x65, 0x72, 0x5f, 0x63, + 0x6f, 0x70, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x70, 0x41, + 0x66, 0x74, 0x65, 0x72, 0x43, 0x6f, 0x70, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, + 0x74, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x09, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x12, 0x22, 0x0a, 0x06, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x12, 0x20, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, + 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x08, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x72, 0x6f, 0x77, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x0a, 0x72, + 0x6f, 0x77, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x22, 0x51, 0x0a, 0x0a, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x22, 0x88, 0x01, 0x0a, + 0x09, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, + 0x12, 0x35, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x5f, 0x6b, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x08, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x50, 0x4b, 0x73, 0x22, 0x3f, 0x0a, 0x05, 0x56, 0x47, 0x74, 0x69, 0x64, + 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, + 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4b, 0x65, 0x79, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xbc, 0x02, 0x0a, 0x07, + 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x36, 0x0a, 0x0b, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x5f, 0x67, 0x74, 0x69, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, + 0x47, 0x74, 0x69, 0x64, 0x52, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x47, 0x74, 0x69, 0x64, 0x73, + 0x12, 0x3d, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, + 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x69, 0x70, 0x61, 0x6e, 0x74, 0x73, 0x12, + 0x29, 0x0a, 0x10, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, + 0x6f, 0x77, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xbb, 0x03, 0x0a, 0x06, 0x56, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, + 0x74, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x12, 0x31, 0x0a, 0x09, 0x72, 0x6f, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x52, 0x6f, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x08, 0x72, 0x6f, 0x77, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x12, 0x37, 0x0a, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x62, 0x69, 0x6e, 0x6c, + 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x52, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x27, 0x0a, + 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x62, + 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x47, 0x74, 0x69, 0x64, 0x52, + 0x05, 0x76, 0x67, 0x74, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x07, 0x6a, 0x6f, 0x75, 0x72, 0x6e, 0x61, + 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4a, 0x6f, 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x52, 0x07, 0x6a, 0x6f, + 0x75, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x64, 0x6d, 0x6c, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x64, 0x6d, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6c, 0x61, + 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, 0x3d, 0x0a, 0x0f, 0x56, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, - 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, - 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, 0x02, 0x0a, 0x12, 0x56, 0x53, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, - 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, - 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, - 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, - 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, - 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, - 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, - 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, - 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, - 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, - 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, - 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, - 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, - 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, - 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, - 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, - 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, - 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, - 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, - 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, - 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, + 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x0b, 0x6c, 0x61, 0x73, + 0x74, 0x50, 0x4b, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x4d, 0x69, 0x6e, 0x69, + 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x06, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x1e, 0x0a, 0x0b, 0x70, 0x5f, 0x6b, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x70, 0x4b, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x73, 0x22, 0x41, 0x0a, 0x0d, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4d, 0x69, 0x6e, 0x69, 0x6d, 0x61, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x22, 0xc7, 0x02, 0x0a, 0x0e, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, + 0x54, 0x47, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, + 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x3e, 0x0a, 0x0f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, + 0x6b, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, + 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, + 0x4b, 0x52, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x73, 0x22, + 0x3d, 0x0a, 0x0f, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x85, + 0x02, 0x0a, 0x12, 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x2a, 0x0a, 0x06, 0x6c, 0x61, + 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x71, 0x75, 0x65, + 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, + 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xbd, 0x01, 0x0a, 0x13, 0x56, 0x53, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x52, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, - 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, - 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, - 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, - 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, - 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, - 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, 0x01, 0x0a, 0x0a, 0x56, 0x45, 0x76, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, 0x49, 0x44, 0x10, 0x01, 0x12, 0x09, - 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, - 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, - 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, - 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, - 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, - 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x09, 0x12, 0x07, 0x0a, - 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, - 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49, - 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, - 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, 0x54, 0x49, 0x44, 0x10, 0x0f, 0x12, - 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x10, 0x12, 0x0b, 0x0a, 0x07, - 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x53, - 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, - 0x4e, 0x54, 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, - 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, - 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, - 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, - 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x6c, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x52, 0x08, 0x70, 0x6b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x67, 0x74, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, + 0x69, 0x64, 0x12, 0x1e, 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, + 0x77, 0x73, 0x12, 0x22, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x06, + 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0x69, 0x0a, 0x0b, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, + 0x61, 0x73, 0x74, 0x5f, 0x70, 0x5f, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, + 0x74, 0x50, 0x4b, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x64, 0x22, 0x58, 0x0a, 0x0b, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x50, 0x4b, + 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x2a, 0x0a, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x52, 0x06, 0x6c, 0x61, 0x73, 0x74, 0x70, 0x6b, 0x22, 0xdc, 0x01, 0x0a, 0x15, + 0x56, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x76, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x49, 0x44, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x43, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x13, 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x74, 0x65, 0x5f, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x56, 0x54, 0x47, 0x61, + 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x44, 0x52, 0x11, 0x69, 0x6d, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x64, 0x12, 0x25, 0x0a, + 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x72, 0x0a, 0x16, 0x56, 0x53, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x2e, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x52, 0x06, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x67, 0x74, + 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x67, 0x74, 0x69, 0x64, 0x12, 0x1e, + 0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x2e, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x2a, 0x3e, + 0x0a, 0x0b, 0x4f, 0x6e, 0x44, 0x44, 0x4c, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0a, 0x0a, + 0x06, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, + 0x50, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x58, 0x45, 0x43, 0x10, 0x02, 0x12, 0x0f, 0x0a, + 0x0b, 0x45, 0x58, 0x45, 0x43, 0x5f, 0x49, 0x47, 0x4e, 0x4f, 0x52, 0x45, 0x10, 0x03, 0x2a, 0xf9, + 0x01, 0x0a, 0x0a, 0x56, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x47, 0x54, + 0x49, 0x44, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x10, 0x02, 0x12, + 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4d, 0x4d, 0x49, 0x54, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x52, + 0x4f, 0x4c, 0x4c, 0x42, 0x41, 0x43, 0x4b, 0x10, 0x04, 0x12, 0x07, 0x0a, 0x03, 0x44, 0x44, 0x4c, + 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x4e, 0x53, 0x45, 0x52, 0x54, 0x10, 0x06, 0x12, 0x0b, + 0x0a, 0x07, 0x52, 0x45, 0x50, 0x4c, 0x41, 0x43, 0x45, 0x10, 0x07, 0x12, 0x0a, 0x0a, 0x06, 0x55, + 0x50, 0x44, 0x41, 0x54, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x45, 0x10, 0x09, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x45, 0x54, 0x10, 0x0a, 0x12, 0x09, 0x0a, 0x05, + 0x4f, 0x54, 0x48, 0x45, 0x52, 0x10, 0x0b, 0x12, 0x07, 0x0a, 0x03, 0x52, 0x4f, 0x57, 0x10, 0x0c, + 0x12, 0x09, 0x0a, 0x05, 0x46, 0x49, 0x45, 0x4c, 0x44, 0x10, 0x0d, 0x12, 0x0d, 0x0a, 0x09, 0x48, + 0x45, 0x41, 0x52, 0x54, 0x42, 0x45, 0x41, 0x54, 0x10, 0x0e, 0x12, 0x09, 0x0a, 0x05, 0x56, 0x47, + 0x54, 0x49, 0x44, 0x10, 0x0f, 0x12, 0x0b, 0x0a, 0x07, 0x4a, 0x4f, 0x55, 0x52, 0x4e, 0x41, 0x4c, + 0x10, 0x10, 0x12, 0x0b, 0x0a, 0x07, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x11, 0x12, + 0x0a, 0x0a, 0x06, 0x4c, 0x41, 0x53, 0x54, 0x50, 0x4b, 0x10, 0x12, 0x12, 0x0d, 0x0a, 0x09, 0x53, + 0x41, 0x56, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x13, 0x2a, 0x27, 0x0a, 0x0d, 0x4d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x54, + 0x41, 0x42, 0x4c, 0x45, 0x53, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x48, 0x41, 0x52, 0x44, + 0x53, 0x10, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, + 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x62, 0x69, 0x6e, 0x6c, 0x6f, 0x67, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2721,7 +2721,7 @@ var file_binlogdata_proto_goTypes = []interface{}{ (*VStreamResultsRequest)(nil), // 30: binlogdata.VStreamResultsRequest (*VStreamResultsResponse)(nil), // 31: binlogdata.VStreamResultsResponse (*BinlogTransaction_Statement)(nil), // 32: binlogdata.BinlogTransaction.Statement - nil, // 33: binlogdata.Rule.EnumTextEntry + nil, // 33: binlogdata.Rule.ConvertEnumToTextEntry (*query.EventToken)(nil), // 34: query.EventToken (*topodata.KeyRange)(nil), // 35: topodata.KeyRange (topodata.TabletType)(0), // 36: topodata.TabletType @@ -2740,7 +2740,7 @@ var file_binlogdata_proto_depIdxs = []int32{ 6, // 4: binlogdata.StreamKeyRangeResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction 5, // 5: binlogdata.StreamTablesRequest.charset:type_name -> binlogdata.Charset 6, // 6: binlogdata.StreamTablesResponse.binlog_transaction:type_name -> binlogdata.BinlogTransaction - 33, // 7: binlogdata.Rule.enum_text:type_name -> binlogdata.Rule.EnumTextEntry + 33, // 7: binlogdata.Rule.convert_enum_to_text:type_name -> binlogdata.Rule.ConvertEnumToTextEntry 11, // 8: binlogdata.Filter.rules:type_name -> binlogdata.Rule 4, // 9: binlogdata.Filter.fieldEventMode:type_name -> binlogdata.Filter.FieldEventMode 36, // 10: binlogdata.BinlogSource.tablet_type:type_name -> topodata.TabletType diff --git a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go index 29626b07e89..ff37cb064e4 100644 --- a/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go +++ b/go/vt/proto/binlogdata/binlogdata_vtproto.pb.go @@ -431,9 +431,9 @@ func (m *Rule) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } - if len(m.EnumText) > 0 { - for k := range m.EnumText { - v := m.EnumText[k] + if len(m.ConvertEnumToText) > 0 { + for k := range m.ConvertEnumToText { + v := m.ConvertEnumToText[k] baseI := i i -= len(v) copy(dAtA[i:], v) @@ -2095,8 +2095,8 @@ func (m *Rule) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } - if len(m.EnumText) > 0 { - for k, v := range m.EnumText { + if len(m.ConvertEnumToText) > 0 { + for k, v := range m.ConvertEnumToText { _ = k _ = v mapEntrySize := 1 + len(k) + sov(uint64(len(k))) + 1 + len(v) + sov(uint64(len(v))) @@ -3630,7 +3630,7 @@ func (m *Rule) UnmarshalVT(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field EnumText", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ConvertEnumToText", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -3657,8 +3657,8 @@ func (m *Rule) UnmarshalVT(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.EnumText == nil { - m.EnumText = make(map[string]string) + if m.ConvertEnumToText == nil { + m.ConvertEnumToText = make(map[string]string) } var mapkey string var mapvalue string @@ -3753,7 +3753,7 @@ func (m *Rule) UnmarshalVT(dAtA []byte) error { iNdEx += skippy } } - m.EnumText[mapkey] = mapvalue + m.ConvertEnumToText[mapkey] = mapvalue iNdEx = postIndex default: iNdEx = preIndex diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 87e2ef1a588..7325deffbf2 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -73,9 +73,9 @@ type VRepl struct { sharedColumnsMap map[string]string sourceAutoIncrement uint64 - filterQuery string - enumTextMap map[string]string - bls *binlogdatapb.BinlogSource + filterQuery string + enumToTextMap map[string]string + bls *binlogdatapb.BinlogSource parser *vrepl.AlterTableParser } @@ -83,15 +83,15 @@ type VRepl struct { // NewVRepl creates a VReplication handler for Online DDL func NewVRepl(workflow, keyspace, shard, dbName, sourceTable, targetTable, alterOptions string) *VRepl { return &VRepl{ - workflow: workflow, - keyspace: keyspace, - shard: shard, - dbName: dbName, - sourceTable: sourceTable, - targetTable: targetTable, - alterOptions: alterOptions, - parser: vrepl.NewAlterTableParser(), - enumTextMap: map[string]string{}, + workflow: workflow, + keyspace: keyspace, + shard: shard, + dbName: dbName, + sourceTable: sourceTable, + targetTable: targetTable, + alterOptions: alterOptions, + parser: vrepl.NewAlterTableParser(), + enumToTextMap: map[string]string{}, } } @@ -368,7 +368,7 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection // A column is converted from ENUM type to textual type v.targetSharedColumns.SetEnumToTextConversion(mappedColumn.Name) v.targetSharedColumns.SetEnumValues(mappedColumn.Name, column.EnumValues) - v.enumTextMap[mappedColumn.Name] = column.EnumValues + v.enumToTextMap[mappedColumn.Name] = column.EnumValues } } @@ -424,8 +424,8 @@ func (v *VRepl) analyzeBinlogSource(ctx context.Context) { Match: v.targetTable, Filter: v.filterQuery, } - if len(v.enumTextMap) > 0 { - rule.EnumText = v.enumTextMap + if len(v.enumToTextMap) > 0 { + rule.ConvertEnumToText = v.enumToTextMap } bls.Filter.Rules = append(bls.Filter.Rules, rule) diff --git a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go index 415f8831a3a..b4dc23ded2c 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go +++ b/go/vt/vttablet/tabletmanager/vreplication/table_plan_builder.go @@ -143,7 +143,7 @@ func buildReplicatorPlan(filter *binlogdatapb.Filter, colInfoMap map[string][]*C if rule == nil { continue } - tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, rule.EnumText, stats) + tablePlan, err := buildTablePlan(tableName, rule.Filter, colInfoMap, lastpk, rule.ConvertEnumToText, stats) if err != nil { return nil, err } diff --git a/proto/binlogdata.proto b/proto/binlogdata.proto index 23c5c727aa4..44c1e1ebe3f 100644 --- a/proto/binlogdata.proto +++ b/proto/binlogdata.proto @@ -138,11 +138,13 @@ message Rule { // to be excluded. // TODO(sougou): support this on vstreamer side also. string filter = 2; - // EnumText: optional, list per enum column name, the list of textual values. + // ConvertEnumToText: optional, list per enum column name, the list of textual values. // When reading the binary log, all enum values are numeric. But sometimes it // is useful/needed to know what the textual mapping are. // Online DDL provides such use case. - map enum_text = 3; + + // Example: key="color", value="'red','green','blue'" + map convert_enum_to_text = 3; } // Filter represents a list of ordered rules. The first From a2447c50e4578b9451bfb7ca2b404cfb4087c0cf Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 11:42:35 +0300 Subject: [PATCH 280/310] fix scenario where enum column is renamed Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 7325deffbf2..52445797c0f 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -362,13 +362,14 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection } for i := range v.sourceSharedColumns.Columns() { - column := v.sourceSharedColumns.Columns()[i] + sourceColumn := v.sourceSharedColumns.Columns()[i] mappedColumn := v.targetSharedColumns.Columns()[i] - if column.Name == mappedColumn.Name && column.Type == vrepl.EnumColumnType && mappedColumn.Type != vrepl.EnumColumnType && mappedColumn.Charset != "" { + if sourceColumn.Type == vrepl.EnumColumnType && mappedColumn.Type != vrepl.EnumColumnType && mappedColumn.Charset != "" { // A column is converted from ENUM type to textual type v.targetSharedColumns.SetEnumToTextConversion(mappedColumn.Name) - v.targetSharedColumns.SetEnumValues(mappedColumn.Name, column.EnumValues) - v.enumToTextMap[mappedColumn.Name] = column.EnumValues + v.targetSharedColumns.SetEnumValues(mappedColumn.Name, sourceColumn.EnumValues) + + v.enumToTextMap[sourceColumn.Name] = sourceColumn.EnumValues } } @@ -388,17 +389,17 @@ func (v *VRepl) generateFilterQuery(ctx context.Context) error { } var sb strings.Builder sb.WriteString("select ") - for i, col := range v.sourceSharedColumns.Columns() { - name := col.Name + for i, sourceCol := range v.sourceSharedColumns.Columns() { + name := sourceCol.Name targetName := v.sharedColumnsMap[name] if i > 0 { sb.WriteString(", ") } switch { - case col.Type == vrepl.JSONColumnType: + case sourceCol.Type == vrepl.JSONColumnType: sb.WriteString(fmt.Sprintf("convert(%s using utf8mb4)", escapeName(name))) - case col.EnumToTextConversion: + case sourceCol.EnumToTextConversion: sb.WriteString(fmt.Sprintf("CONCAT(%s)", escapeName(name))) default: sb.WriteString(escapeName(name)) From ed06e513e797a6b72e4781ac012d53e1858c2b36 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Mon, 14 Jun 2021 14:14:11 +0530 Subject: [PATCH 281/310] make expandStar as false if the table is non-authoritative Signed-off-by: Harshit Gangal --- go/vt/vtgate/planbuilder/route_planning.go | 1 + go/vt/vtgate/planbuilder/route_planning_test.go | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/go/vt/vtgate/planbuilder/route_planning.go b/go/vt/vtgate/planbuilder/route_planning.go index 7c179729542..be696bca770 100644 --- a/go/vt/vtgate/planbuilder/route_planning.go +++ b/go/vt/vtgate/planbuilder/route_planning.go @@ -137,6 +137,7 @@ func expandStar(sel *sqlparser.Select, semTable *semantics.SemTable) *sqlparser. } } if !tbl.Table.ColumnListAuthoritative { + expandStar = false break } expandStar = true diff --git a/go/vt/vtgate/planbuilder/route_planning_test.go b/go/vt/vtgate/planbuilder/route_planning_test.go index c17ae60efb2..24ed2bd688f 100644 --- a/go/vt/vtgate/planbuilder/route_planning_test.go +++ b/go/vt/vtgate/planbuilder/route_planning_test.go @@ -190,9 +190,18 @@ func TestExpandStar(t *testing.T) { }, { sql: "select *, t1.* from t1, t2", expSQL: "select t1.a, t1.b, t1.c, t2.c1, t2.c2, t1.a, t1.b, t1.c from t1, t2", + }, { // t3 is non-authoritative table + sql: "select * from t3", + expSQL: "select * from t3", + }, { // t3 is non-authoritative table + sql: "select * from t1, t2, t3", + expSQL: "select * from t1, t2, t3", + }, { // t3 is non-authoritative table + sql: "select t1.*, t2.*, t3.* from t1, t2, t3", + expSQL: "select t1.a, t1.b, t1.c, t2.c1, t2.c2, t3.* from t1, t2, t3", }, { // TODO: This should fail on analyze step and should not reach down. - sql: "select t3.* from t1, t2", - expSQL: "select t3.* from t1, t2", + sql: "select foo.* from t1, t2", + expSQL: "select foo.* from t1, t2", }} for _, tcase := range tcases { t.Run(tcase.sql, func(t *testing.T) { From 516f2dfec0beaa01d00c165cc1284a348d2938a6 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 12:00:30 +0300 Subject: [PATCH 282/310] small refactor Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- go/vt/vttablet/onlineddl/vrepl.go | 3 +-- go/vt/vttablet/onlineddl/vrepl/types.go | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 52445797c0f..94697470095 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -366,8 +366,7 @@ func (v *VRepl) analyzeTables(ctx context.Context, conn *dbconnpool.DBConnection mappedColumn := v.targetSharedColumns.Columns()[i] if sourceColumn.Type == vrepl.EnumColumnType && mappedColumn.Type != vrepl.EnumColumnType && mappedColumn.Charset != "" { // A column is converted from ENUM type to textual type - v.targetSharedColumns.SetEnumToTextConversion(mappedColumn.Name) - v.targetSharedColumns.SetEnumValues(mappedColumn.Name, sourceColumn.EnumValues) + v.targetSharedColumns.SetEnumToTextConversion(mappedColumn.Name, sourceColumn.EnumValues) v.enumToTextMap[sourceColumn.Name] = sourceColumn.EnumValues } diff --git a/go/vt/vttablet/onlineddl/vrepl/types.go b/go/vt/vttablet/onlineddl/vrepl/types.go index 2bceef5c2a0..f7c8ef34c5e 100644 --- a/go/vt/vttablet/onlineddl/vrepl/types.go +++ b/go/vt/vttablet/onlineddl/vrepl/types.go @@ -171,8 +171,9 @@ func (l *ColumnList) Len() int { } // SetEnumToTextConversion tells this column list that an enum is conveted to text -func (l *ColumnList) SetEnumToTextConversion(columnName string) { +func (l *ColumnList) SetEnumToTextConversion(columnName string, enumValues string) { l.GetColumn(columnName).EnumToTextConversion = true + l.GetColumn(columnName).EnumValues = enumValues } // IsEnumToTextConversion tells whether an enum was converted to text @@ -180,11 +181,6 @@ func (l *ColumnList) IsEnumToTextConversion(columnName string) bool { return l.GetColumn(columnName).EnumToTextConversion } -// SetEnumValues sets a columns enum values list, e.g. 'red','green','blue' -func (l *ColumnList) SetEnumValues(columnName string, enumValues string) { - l.GetColumn(columnName).EnumValues = enumValues -} - // UniqueKey is the combination of a key's name and columns type UniqueKey struct { Name string From 6f95226bb1973aa59bfbb41b936ff3c374685109 Mon Sep 17 00:00:00 2001 From: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> Date: Mon, 14 Jun 2021 13:22:42 +0300 Subject: [PATCH 283/310] pr-labels workflow: only check actual PRs Signed-off-by: Shlomi Noach <2607934+shlomi-noach@users.noreply.github.com> --- .github/workflows/pr-labels.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-labels.yml b/.github/workflows/pr-labels.yml index 7052780882f..eef96ca36f2 100644 --- a/.github/workflows/pr-labels.yml +++ b/.github/workflows/pr-labels.yml @@ -2,8 +2,6 @@ name: pr-labels on: pull_request: types: [opened, labeled, unlabeled, synchronize] - push: - label: jobs: analyze: if: github.repository == 'vitessio/vitess' @@ -24,6 +22,9 @@ jobs: env: PR_NUMBER: ${{ github.event.pull_request.number }} run: | + if [ -z "$PR_NUMBER" ] ; then + exit 0 + fi LABELS_JSON="/tmp/labels.json" # Get labels for this pull request From 7a08a42e4e147049b3298b667a6d6a67574dc491 Mon Sep 17 00:00:00 2001 From: Sara Bee <855595+doeg@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:40:04 -0400 Subject: [PATCH 284/310] [vtadmin-web] Add getStreamTablets util Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com> --- web/vtadmin/src/util/workflows.test.ts | 49 +++++++++++++++++++++++++- web/vtadmin/src/util/workflows.ts | 21 +++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/web/vtadmin/src/util/workflows.test.ts b/web/vtadmin/src/util/workflows.test.ts index 38dc0e31987..3b6014669ed 100644 --- a/web/vtadmin/src/util/workflows.test.ts +++ b/web/vtadmin/src/util/workflows.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { vtadmin as pb } from '../proto/vtadmin'; -import { getStreams } from './workflows'; +import { getStreams, getStreamTablets } from './workflows'; describe('getStreams', () => { const tests: { @@ -70,3 +70,50 @@ describe('getStreams', () => { } ); }); + +describe('getStreamTablets', () => { + const tests: { + name: string; + input: Parameters; + expected: ReturnType; + }[] = [ + { + name: 'should return a set of unique tablet aliases', + input: [ + pb.Workflow.create({ + workflow: { + shard_streams: { + '-80/us_east_1a-123456': { + streams: [ + { id: 1, shard: '-80', tablet: { cell: 'us_east_1a', uid: 123456 } }, + { id: 2, shard: '-80', tablet: { cell: 'us_east_1a', uid: 123456 } }, + ], + }, + '80-/us_east_1a-789012': { + streams: [{ id: 1, shard: '80-', tablet: { cell: 'us_east_1a', uid: 789012 } }], + }, + }, + }, + }), + ], + expected: ['us_east_1a-123456', 'us_east_1a-789012'], + }, + { + name: 'should handle empty workflow', + input: [pb.Workflow.create()], + expected: [], + }, + { + name: 'should handle null input', + input: [null], + expected: [], + }, + ]; + + test.each(tests.map(Object.values))( + '%s', + (name: string, input: Parameters, expected: ReturnType) => { + expect(getStreamTablets(...input)).toEqual(expected); + } + ); +}); diff --git a/web/vtadmin/src/util/workflows.ts b/web/vtadmin/src/util/workflows.ts index 61fac25e48a..75ed02c6939 100644 --- a/web/vtadmin/src/util/workflows.ts +++ b/web/vtadmin/src/util/workflows.ts @@ -59,3 +59,24 @@ export const getTimeUpdated = (workflow: W | null | unde const timestamps = getStreams(workflow).map((s) => parseInt(`${s.time_updated?.seconds}`, 10)); return Math.max(...timestamps); }; + +/** + * getStreamTablets returns an unordered set of tablet alias strings across all streams + * in the workflow. + */ +export const getStreamTablets = (workflow: W | null | undefined): string[] => { + const streams = getStreams(workflow); + if (!Array.isArray(streams)) { + return []; + } + + const aliases = new Set(); + streams.forEach((stream) => { + const alias = formatAlias(stream.tablet); + if (alias) { + aliases.add(alias); + } + }); + + return [...aliases]; +}; From 643174478c18d19def913667de5d24426d4ef45b Mon Sep 17 00:00:00 2001 From: Sara Bee <855595+doeg@users.noreply.github.com> Date: Mon, 14 Jun 2021 10:20:41 -0400 Subject: [PATCH 285/310] [vtadmin-web] Add useManyExperimentalTabletDebugVars query hook Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com> --- web/vtadmin/src/api/http.ts | 16 ++++++++++--- .../src/components/charts/TabletQPSChart.tsx | 2 +- .../charts/TabletVReplicationQPSChart.tsx | 2 +- web/vtadmin/src/hooks/api.ts | 23 +++++++++++++++---- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/web/vtadmin/src/api/http.ts b/web/vtadmin/src/api/http.ts index 61c8c62c0e4..d550fb2c6ae 100644 --- a/web/vtadmin/src/api/http.ts +++ b/web/vtadmin/src/api/http.ts @@ -18,6 +18,7 @@ import { vtadmin as pb } from '../proto/vtadmin'; import * as errorHandler from '../errors/errorHandler'; import { HttpFetchError, HttpResponseNotOkError, MalformedHttpResponseError } from '../errors/errorTypes'; import { HttpOkResponse } from './responseTypes'; +import { TabletDebugVars } from '../util/tabletDebugVars'; /** * vtfetch makes HTTP requests against the given vtadmin-api endpoint @@ -188,13 +189,22 @@ export const fetchTablet = async ({ clusterID, alias }: FetchTabletParams) => { return pb.Tablet.create(result); }; -export const fetchExperimentalTabletDebugVars = async ({ clusterID, alias }: FetchTabletParams) => { +export interface TabletDebugVarsResponse { + params: FetchTabletParams; + data?: TabletDebugVars; +} + +export const fetchExperimentalTabletDebugVars = async (params: FetchTabletParams): Promise => { if (!process.env.REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS) { - return Promise.resolve({}); + return Promise.resolve({ params }); } + const { clusterID, alias } = params; const { result } = await vtfetch(`/api/experimental/tablet/${alias}/debug/vars?cluster=${clusterID}`); - return result; + + // /debug/vars doesn't contain cluster/tablet information, so we + // return that as part of the response. + return { params, data: result }; }; export const fetchTablets = async () => diff --git a/web/vtadmin/src/components/charts/TabletQPSChart.tsx b/web/vtadmin/src/components/charts/TabletQPSChart.tsx index 031a8a15f7c..154e2f32602 100644 --- a/web/vtadmin/src/components/charts/TabletQPSChart.tsx +++ b/web/vtadmin/src/components/charts/TabletQPSChart.tsx @@ -37,7 +37,7 @@ export const TabletQPSChart = ({ alias, clusterID }: Props) => { ); const options = useMemo(() => { - const tsdata = getQPSTimeseries(debugVars, query.dataUpdatedAt); + const tsdata = getQPSTimeseries(debugVars?.data, query.dataUpdatedAt); const series: Highcharts.SeriesOptionsType[] = Object.entries(tsdata).map(([name, data]) => ({ data, diff --git a/web/vtadmin/src/components/charts/TabletVReplicationQPSChart.tsx b/web/vtadmin/src/components/charts/TabletVReplicationQPSChart.tsx index 8075e9ba24a..8f11818e56f 100644 --- a/web/vtadmin/src/components/charts/TabletVReplicationQPSChart.tsx +++ b/web/vtadmin/src/components/charts/TabletVReplicationQPSChart.tsx @@ -37,7 +37,7 @@ export const TabletVReplicationQPSChart = ({ alias, clusterID }: Props) => { ); const options = useMemo(() => { - const tsdata = getVReplicationQPSTimeseries(debugVars, query.dataUpdatedAt); + const tsdata = getVReplicationQPSTimeseries(debugVars?.data, query.dataUpdatedAt); const series: Highcharts.SeriesOptionsType[] = Object.entries(tsdata).map(([name, data]) => ({ data, diff --git a/web/vtadmin/src/hooks/api.ts b/web/vtadmin/src/hooks/api.ts index cce601f5389..10d47e3bf33 100644 --- a/web/vtadmin/src/hooks/api.ts +++ b/web/vtadmin/src/hooks/api.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { useQuery, useQueryClient, UseQueryOptions } from 'react-query'; +import { useQueries, useQuery, useQueryClient, UseQueryOptions, UseQueryResult } from 'react-query'; import { fetchClusters, fetchExperimentalTabletDebugVars, @@ -23,15 +23,16 @@ import { FetchSchemaParams, fetchSchemas, fetchTablet, + FetchTabletParams, fetchTablets, fetchVSchema, FetchVSchemaParams, fetchVTExplain, fetchWorkflow, fetchWorkflows, + TabletDebugVarsResponse, } from '../api/http'; import { vtadmin as pb } from '../proto/vtadmin'; -import { TabletDebugVars } from '../util/tabletDebugVars'; import { formatAlias } from '../util/tablets'; /** @@ -81,8 +82,8 @@ export const useTablet = (params: Parameters[0], options?: U }; export const useExperimentalTabletDebugVars = ( - params: Parameters[0], - options?: UseQueryOptions + params: FetchTabletParams, + options?: UseQueryOptions ) => { return useQuery( ['experimental/tablet/debug/vars', params], @@ -91,6 +92,20 @@ export const useExperimentalTabletDebugVars = ( ); }; +export const useManyExperimentalTabletDebugVars = ( + params: FetchTabletParams[], + defaultOptions: UseQueryOptions = {} +) => { + // Robust typing for useQueries is still in progress, so we do + // some sneaky type-casting. See https://github.com/tannerlinsley/react-query/issues/1675 + const queries = params.map((p) => ({ + queryKey: ['experimental/tablet/debug/vars', p], + queryFn: () => fetchExperimentalTabletDebugVars(p), + ...(defaultOptions as any), + })); + return useQueries(queries) as UseQueryResult[]; +}; + /** * useWorkflowsResponse is a query hook that fetches all workflows (by cluster) across every cluster. */ From d9c70281f441e95e5e670a62a1c612601b8968af Mon Sep 17 00:00:00 2001 From: Alex Charis Date: Mon, 14 Jun 2021 14:23:08 +0000 Subject: [PATCH 286/310] test three table engines from issue Signed-off-by: Alex Charis --- go/vt/sqlparser/parse_test.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/go/vt/sqlparser/parse_test.go b/go/vt/sqlparser/parse_test.go index 7be8c9ba615..364ccf3935d 100644 --- a/go/vt/sqlparser/parse_test.go +++ b/go/vt/sqlparser/parse_test.go @@ -3058,6 +3058,21 @@ func TestCreateTable(t *testing.T) { first_name varchar(10), full_name varchar(255) as (concat(first_name, ' ', last_name)) virtual comment 'hello world' )`, + }, { + input: `create table non_reserved_keyword (id int(11)) ENGINE = MEMORY`, + output: `create table non_reserved_keyword ( + id int(11) +) ENGINE MEMORY`, + }, { + input: `create table non_reserved_keyword (id int(11)) ENGINE = MEDIUMTEXT`, + output: `create table non_reserved_keyword ( + id int(11) +) ENGINE MEDIUMTEXT`, + }, { + input: `create table t1 (id int(11)) ENGINE = FOOBAR`, + output: `create table t1 ( + id int(11) +) ENGINE FOOBAR`, }, } for _, test := range createTableQueries { From 18e42597d931d992d5612b3778d668275226cc7e Mon Sep 17 00:00:00 2001 From: Sara Bee <855595+doeg@users.noreply.github.com> Date: Mon, 14 Jun 2021 11:12:47 -0400 Subject: [PATCH 287/310] [vtadmin-web] Add WorkflowStreamsLagChart Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com> --- .../charts/WorkflowStreamsLagChart.test.tsx | 97 + .../charts/WorkflowStreamsLagChart.tsx | 98 + .../WorkflowStreamsLagChart.test.tsx.snap | 2184 +++++++++++++++++ .../routes/workflow/WorkflowStreams.tsx | 7 +- web/vtadmin/src/util/tabletDebugVars.ts | 6 + 5 files changed, 2391 insertions(+), 1 deletion(-) create mode 100644 web/vtadmin/src/components/charts/WorkflowStreamsLagChart.test.tsx create mode 100644 web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx create mode 100644 web/vtadmin/src/components/charts/__snapshots__/WorkflowStreamsLagChart.test.tsx.snap diff --git a/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.test.tsx b/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.test.tsx new file mode 100644 index 00000000000..948b3e0b624 --- /dev/null +++ b/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.test.tsx @@ -0,0 +1,97 @@ +/** + * 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. + */ + +import { UseQueryResult } from 'react-query'; +import { TabletDebugVarsResponse } from '../../api/http'; +import { vtadmin as pb } from '../../proto/vtadmin'; +import { formatSeries } from './WorkflowStreamsLagChart'; + +describe('WorkflowStreamsLagChart', () => { + describe('formatSeries', () => { + it('should return series for all streams in the workflow', () => { + const workflow = pb.Workflow.create({ + cluster: { + id: 'zone1', + name: 'zone1', + }, + workflow: { + shard_streams: { + '-80/us_east_1a-123456': { + streams: [ + { id: 1, shard: '-80', tablet: { cell: 'us_east_1a', uid: 123456 } }, + { id: 2, shard: '-80', tablet: { cell: 'us_east_1a', uid: 123456 } }, + ], + }, + '80-/us_east_1a-789012': { + streams: [{ id: 1, shard: '80-', tablet: { cell: 'us_east_1a', uid: 789012 } }], + }, + }, + }, + }); + + const queries: Partial>[] = [ + { + data: { + params: { alias: 'us_east_1a-123456', clusterID: 'zone1' }, + data: { + VReplicationLag: { + All: [3, 3, 3], + '1': [1, 1, 1], + '2': [2, 2, 2], + }, + }, + }, + dataUpdatedAt: 1000000000000, + }, + { + data: { + params: { alias: 'us_east_1a-789012', clusterID: 'zone1' }, + data: { + VReplicationLag: { + All: [], + '1': [1, 1, 1], + // Some other stream running on the tablet that isn't part + // of this workflow. + '2': [2, 2, 2], + }, + }, + }, + dataUpdatedAt: 1000000000000, + }, + ]; + + // A sneaky cast to UseQueryResult since otherwise enumerating the many fields + // UseQueryResult (most of which we don't use) is pointlessly verbose. + const result = formatSeries(workflow, queries as UseQueryResult[]); + + // Use snapshot matching since defining expected values for arrays of 180 data points is... annoying. + expect(result).toMatchSnapshot(); + + // ...but! Add additional validation so that failing tests are easier to debug. + // (And because it can be tempting to not examine snapshot changes in detail...) :) + expect(result.length).toEqual(3); + + expect(result[0].name).toEqual('us_east_1a-123456/1'); + expect(result[1].name).toEqual('us_east_1a-123456/2'); + expect(result[2].name).toEqual('us_east_1a-789012/1'); + }); + + it('should handle empty input', () => { + const result = formatSeries(null, []); + expect(result).toEqual([]); + }); + }); +}); diff --git a/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx b/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx new file mode 100644 index 00000000000..699983527d3 --- /dev/null +++ b/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx @@ -0,0 +1,98 @@ +/** + * 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. + */ + +import { useMemo } from 'react'; +import { useManyExperimentalTabletDebugVars, useWorkflow } from '../../hooks/api'; +import { vtadmin } from '../../proto/vtadmin'; +import { getStreamVReplicationLagTimeseries, QPS_REFETCH_INTERVAL } from '../../util/tabletDebugVars'; +import { formatStreamKey, getStreams, getStreamTablets } from '../../util/workflows'; +import { Timeseries } from './Timeseries'; + +interface Props { + clusterID: string; + keyspace: string; + workflowName: string; +} + +export const WorkflowStreamsLagChart = ({ clusterID, keyspace, workflowName }: Props) => { + const { data: workflow, ...wq } = useWorkflow({ clusterID, keyspace, name: workflowName }); + + const queryParams = useMemo(() => { + const aliases = getStreamTablets(workflow); + return aliases.map((alias) => ({ alias, clusterID })); + }, [clusterID, workflow]); + + const tabletQueries = useManyExperimentalTabletDebugVars(queryParams, { + enabled: !!workflow, + refetchInterval: QPS_REFETCH_INTERVAL, + refetchIntervalInBackground: true, + }); + + const anyLoading = wq.isLoading || tabletQueries.some((q) => q.isLoading); + + const chartOptions: Highcharts.Options = useMemo(() => { + return { + series: formatSeries(workflow, tabletQueries), + yAxis: { + labels: { + format: '{text} s', + }, + }, + }; + }, [tabletQueries, workflow]); + + return ; +}; + +export const formatSeries = ( + workflow: vtadmin.Workflow | null | undefined, + tabletQueries: ReturnType +): Highcharts.SeriesOptionsType[] => { + if (!workflow) { + return []; + } + + // Get streamKeys for streams in this workflow. + const streamKeys = getStreams(workflow).map((s) => formatStreamKey(s)); + + return tabletQueries.reduce((acc, tq) => { + if (!tq.data) { + return acc; + } + + const tabletAlias = tq.data.params.alias; + + const lagData = getStreamVReplicationLagTimeseries(tq.data.data, tq.dataUpdatedAt); + Object.entries(lagData).forEach(([streamID, streamLagData]) => { + // Don't graph aggregate vreplication lag for the tablet, since that + // can include vreplication lag data for streams running on the tablet + // that are not in the current workflow. + if (streamID === 'All') { + return; + } + + // Don't graph series for streams that aren't in this workflow. + const streamKey = `${tabletAlias}/${streamID}`; + if (streamKeys.indexOf(streamKey) < 0) { + return; + } + + acc.push({ data: streamLagData, name: streamKey, type: 'line' }); + }); + + return acc; + }, [] as Highcharts.SeriesOptionsType[]); +}; diff --git a/web/vtadmin/src/components/charts/__snapshots__/WorkflowStreamsLagChart.test.tsx.snap b/web/vtadmin/src/components/charts/__snapshots__/WorkflowStreamsLagChart.test.tsx.snap new file mode 100644 index 00000000000..9b60d5253f3 --- /dev/null +++ b/web/vtadmin/src/components/charts/__snapshots__/WorkflowStreamsLagChart.test.tsx.snap @@ -0,0 +1,2184 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`WorkflowStreamsLagChart formatSeries should return series for all streams in the workflow 1`] = ` +Array [ + Object { + "data": Array [ + Object { + "x": 999997852000, + "y": 0, + }, + Object { + "x": 999997864000, + "y": 0, + }, + Object { + "x": 999997876000, + "y": 0, + }, + Object { + "x": 999997888000, + "y": 0, + }, + Object { + "x": 999997900000, + "y": 0, + }, + Object { + "x": 999997912000, + "y": 0, + }, + Object { + "x": 999997924000, + "y": 0, + }, + Object { + "x": 999997936000, + "y": 0, + }, + Object { + "x": 999997948000, + "y": 0, + }, + Object { + "x": 999997960000, + "y": 0, + }, + Object { + "x": 999997972000, + "y": 0, + }, + Object { + "x": 999997984000, + "y": 0, + }, + Object { + "x": 999997996000, + "y": 0, + }, + Object { + "x": 999998008000, + "y": 0, + }, + Object { + "x": 999998020000, + "y": 0, + }, + Object { + "x": 999998032000, + "y": 0, + }, + Object { + "x": 999998044000, + "y": 0, + }, + Object { + "x": 999998056000, + "y": 0, + }, + Object { + "x": 999998068000, + "y": 0, + }, + Object { + "x": 999998080000, + "y": 0, + }, + Object { + "x": 999998092000, + "y": 0, + }, + Object { + "x": 999998104000, + "y": 0, + }, + Object { + "x": 999998116000, + "y": 0, + }, + Object { + "x": 999998128000, + "y": 0, + }, + Object { + "x": 999998140000, + "y": 0, + }, + Object { + "x": 999998152000, + "y": 0, + }, + Object { + "x": 999998164000, + "y": 0, + }, + Object { + "x": 999998176000, + "y": 0, + }, + Object { + "x": 999998188000, + "y": 0, + }, + Object { + "x": 999998200000, + "y": 0, + }, + Object { + "x": 999998212000, + "y": 0, + }, + Object { + "x": 999998224000, + "y": 0, + }, + Object { + "x": 999998236000, + "y": 0, + }, + Object { + "x": 999998248000, + "y": 0, + }, + Object { + "x": 999998260000, + "y": 0, + }, + Object { + "x": 999998272000, + "y": 0, + }, + Object { + "x": 999998284000, + "y": 0, + }, + Object { + "x": 999998296000, + "y": 0, + }, + Object { + "x": 999998308000, + "y": 0, + }, + Object { + "x": 999998320000, + "y": 0, + }, + Object { + "x": 999998332000, + "y": 0, + }, + Object { + "x": 999998344000, + "y": 0, + }, + Object { + "x": 999998356000, + "y": 0, + }, + Object { + "x": 999998368000, + "y": 0, + }, + Object { + "x": 999998380000, + "y": 0, + }, + Object { + "x": 999998392000, + "y": 0, + }, + Object { + "x": 999998404000, + "y": 0, + }, + Object { + "x": 999998416000, + "y": 0, + }, + Object { + "x": 999998428000, + "y": 0, + }, + Object { + "x": 999998440000, + "y": 0, + }, + Object { + "x": 999998452000, + "y": 0, + }, + Object { + "x": 999998464000, + "y": 0, + }, + Object { + "x": 999998476000, + "y": 0, + }, + Object { + "x": 999998488000, + "y": 0, + }, + Object { + "x": 999998500000, + "y": 0, + }, + Object { + "x": 999998512000, + "y": 0, + }, + Object { + "x": 999998524000, + "y": 0, + }, + Object { + "x": 999998536000, + "y": 0, + }, + Object { + "x": 999998548000, + "y": 0, + }, + Object { + "x": 999998560000, + "y": 0, + }, + Object { + "x": 999998572000, + "y": 0, + }, + Object { + "x": 999998584000, + "y": 0, + }, + Object { + "x": 999998596000, + "y": 0, + }, + Object { + "x": 999998608000, + "y": 0, + }, + Object { + "x": 999998620000, + "y": 0, + }, + Object { + "x": 999998632000, + "y": 0, + }, + Object { + "x": 999998644000, + "y": 0, + }, + Object { + "x": 999998656000, + "y": 0, + }, + Object { + "x": 999998668000, + "y": 0, + }, + Object { + "x": 999998680000, + "y": 0, + }, + Object { + "x": 999998692000, + "y": 0, + }, + Object { + "x": 999998704000, + "y": 0, + }, + Object { + "x": 999998716000, + "y": 0, + }, + Object { + "x": 999998728000, + "y": 0, + }, + Object { + "x": 999998740000, + "y": 0, + }, + Object { + "x": 999998752000, + "y": 0, + }, + Object { + "x": 999998764000, + "y": 0, + }, + Object { + "x": 999998776000, + "y": 0, + }, + Object { + "x": 999998788000, + "y": 0, + }, + Object { + "x": 999998800000, + "y": 0, + }, + Object { + "x": 999998812000, + "y": 0, + }, + Object { + "x": 999998824000, + "y": 0, + }, + Object { + "x": 999998836000, + "y": 0, + }, + Object { + "x": 999998848000, + "y": 0, + }, + Object { + "x": 999998860000, + "y": 0, + }, + Object { + "x": 999998872000, + "y": 0, + }, + Object { + "x": 999998884000, + "y": 0, + }, + Object { + "x": 999998896000, + "y": 0, + }, + Object { + "x": 999998908000, + "y": 0, + }, + Object { + "x": 999998920000, + "y": 0, + }, + Object { + "x": 999998932000, + "y": 0, + }, + Object { + "x": 999998944000, + "y": 0, + }, + Object { + "x": 999998956000, + "y": 0, + }, + Object { + "x": 999998968000, + "y": 0, + }, + Object { + "x": 999998980000, + "y": 0, + }, + Object { + "x": 999998992000, + "y": 0, + }, + Object { + "x": 999999004000, + "y": 0, + }, + Object { + "x": 999999016000, + "y": 0, + }, + Object { + "x": 999999028000, + "y": 0, + }, + Object { + "x": 999999040000, + "y": 0, + }, + Object { + "x": 999999052000, + "y": 0, + }, + Object { + "x": 999999064000, + "y": 0, + }, + Object { + "x": 999999076000, + "y": 0, + }, + Object { + "x": 999999088000, + "y": 0, + }, + Object { + "x": 999999100000, + "y": 0, + }, + Object { + "x": 999999112000, + "y": 0, + }, + Object { + "x": 999999124000, + "y": 0, + }, + Object { + "x": 999999136000, + "y": 0, + }, + Object { + "x": 999999148000, + "y": 0, + }, + Object { + "x": 999999160000, + "y": 0, + }, + Object { + "x": 999999172000, + "y": 0, + }, + Object { + "x": 999999184000, + "y": 0, + }, + Object { + "x": 999999196000, + "y": 0, + }, + Object { + "x": 999999208000, + "y": 0, + }, + Object { + "x": 999999220000, + "y": 0, + }, + Object { + "x": 999999232000, + "y": 0, + }, + Object { + "x": 999999244000, + "y": 0, + }, + Object { + "x": 999999256000, + "y": 0, + }, + Object { + "x": 999999268000, + "y": 0, + }, + Object { + "x": 999999280000, + "y": 0, + }, + Object { + "x": 999999292000, + "y": 0, + }, + Object { + "x": 999999304000, + "y": 0, + }, + Object { + "x": 999999316000, + "y": 0, + }, + Object { + "x": 999999328000, + "y": 0, + }, + Object { + "x": 999999340000, + "y": 0, + }, + Object { + "x": 999999352000, + "y": 0, + }, + Object { + "x": 999999364000, + "y": 0, + }, + Object { + "x": 999999376000, + "y": 0, + }, + Object { + "x": 999999388000, + "y": 0, + }, + Object { + "x": 999999400000, + "y": 0, + }, + Object { + "x": 999999412000, + "y": 0, + }, + Object { + "x": 999999424000, + "y": 0, + }, + Object { + "x": 999999436000, + "y": 0, + }, + Object { + "x": 999999448000, + "y": 0, + }, + Object { + "x": 999999460000, + "y": 0, + }, + Object { + "x": 999999472000, + "y": 0, + }, + Object { + "x": 999999484000, + "y": 0, + }, + Object { + "x": 999999496000, + "y": 0, + }, + Object { + "x": 999999508000, + "y": 0, + }, + Object { + "x": 999999520000, + "y": 0, + }, + Object { + "x": 999999532000, + "y": 0, + }, + Object { + "x": 999999544000, + "y": 0, + }, + Object { + "x": 999999556000, + "y": 0, + }, + Object { + "x": 999999568000, + "y": 0, + }, + Object { + "x": 999999580000, + "y": 0, + }, + Object { + "x": 999999592000, + "y": 0, + }, + Object { + "x": 999999604000, + "y": 0, + }, + Object { + "x": 999999616000, + "y": 0, + }, + Object { + "x": 999999628000, + "y": 0, + }, + Object { + "x": 999999640000, + "y": 0, + }, + Object { + "x": 999999652000, + "y": 0, + }, + Object { + "x": 999999664000, + "y": 0, + }, + Object { + "x": 999999676000, + "y": 0, + }, + Object { + "x": 999999688000, + "y": 0, + }, + Object { + "x": 999999700000, + "y": 0, + }, + Object { + "x": 999999712000, + "y": 0, + }, + Object { + "x": 999999724000, + "y": 0, + }, + Object { + "x": 999999736000, + "y": 0, + }, + Object { + "x": 999999748000, + "y": 0, + }, + Object { + "x": 999999760000, + "y": 0, + }, + Object { + "x": 999999772000, + "y": 0, + }, + Object { + "x": 999999784000, + "y": 0, + }, + Object { + "x": 999999796000, + "y": 0, + }, + Object { + "x": 999999808000, + "y": 0, + }, + Object { + "x": 999999820000, + "y": 0, + }, + Object { + "x": 999999832000, + "y": 0, + }, + Object { + "x": 999999844000, + "y": 0, + }, + Object { + "x": 999999856000, + "y": 0, + }, + Object { + "x": 999999868000, + "y": 0, + }, + Object { + "x": 999999880000, + "y": 0, + }, + Object { + "x": 999999892000, + "y": 0, + }, + Object { + "x": 999999904000, + "y": 0, + }, + Object { + "x": 999999916000, + "y": 0, + }, + Object { + "x": 999999928000, + "y": 0, + }, + Object { + "x": 999999940000, + "y": 0, + }, + Object { + "x": 999999952000, + "y": 0, + }, + Object { + "x": 999999964000, + "y": 0, + }, + Object { + "x": 999999976000, + "y": 1, + }, + Object { + "x": 999999988000, + "y": 1, + }, + Object { + "x": 1000000000000, + "y": 1, + }, + ], + "name": "us_east_1a-123456/1", + "type": "line", + }, + Object { + "data": Array [ + Object { + "x": 999997852000, + "y": 0, + }, + Object { + "x": 999997864000, + "y": 0, + }, + Object { + "x": 999997876000, + "y": 0, + }, + Object { + "x": 999997888000, + "y": 0, + }, + Object { + "x": 999997900000, + "y": 0, + }, + Object { + "x": 999997912000, + "y": 0, + }, + Object { + "x": 999997924000, + "y": 0, + }, + Object { + "x": 999997936000, + "y": 0, + }, + Object { + "x": 999997948000, + "y": 0, + }, + Object { + "x": 999997960000, + "y": 0, + }, + Object { + "x": 999997972000, + "y": 0, + }, + Object { + "x": 999997984000, + "y": 0, + }, + Object { + "x": 999997996000, + "y": 0, + }, + Object { + "x": 999998008000, + "y": 0, + }, + Object { + "x": 999998020000, + "y": 0, + }, + Object { + "x": 999998032000, + "y": 0, + }, + Object { + "x": 999998044000, + "y": 0, + }, + Object { + "x": 999998056000, + "y": 0, + }, + Object { + "x": 999998068000, + "y": 0, + }, + Object { + "x": 999998080000, + "y": 0, + }, + Object { + "x": 999998092000, + "y": 0, + }, + Object { + "x": 999998104000, + "y": 0, + }, + Object { + "x": 999998116000, + "y": 0, + }, + Object { + "x": 999998128000, + "y": 0, + }, + Object { + "x": 999998140000, + "y": 0, + }, + Object { + "x": 999998152000, + "y": 0, + }, + Object { + "x": 999998164000, + "y": 0, + }, + Object { + "x": 999998176000, + "y": 0, + }, + Object { + "x": 999998188000, + "y": 0, + }, + Object { + "x": 999998200000, + "y": 0, + }, + Object { + "x": 999998212000, + "y": 0, + }, + Object { + "x": 999998224000, + "y": 0, + }, + Object { + "x": 999998236000, + "y": 0, + }, + Object { + "x": 999998248000, + "y": 0, + }, + Object { + "x": 999998260000, + "y": 0, + }, + Object { + "x": 999998272000, + "y": 0, + }, + Object { + "x": 999998284000, + "y": 0, + }, + Object { + "x": 999998296000, + "y": 0, + }, + Object { + "x": 999998308000, + "y": 0, + }, + Object { + "x": 999998320000, + "y": 0, + }, + Object { + "x": 999998332000, + "y": 0, + }, + Object { + "x": 999998344000, + "y": 0, + }, + Object { + "x": 999998356000, + "y": 0, + }, + Object { + "x": 999998368000, + "y": 0, + }, + Object { + "x": 999998380000, + "y": 0, + }, + Object { + "x": 999998392000, + "y": 0, + }, + Object { + "x": 999998404000, + "y": 0, + }, + Object { + "x": 999998416000, + "y": 0, + }, + Object { + "x": 999998428000, + "y": 0, + }, + Object { + "x": 999998440000, + "y": 0, + }, + Object { + "x": 999998452000, + "y": 0, + }, + Object { + "x": 999998464000, + "y": 0, + }, + Object { + "x": 999998476000, + "y": 0, + }, + Object { + "x": 999998488000, + "y": 0, + }, + Object { + "x": 999998500000, + "y": 0, + }, + Object { + "x": 999998512000, + "y": 0, + }, + Object { + "x": 999998524000, + "y": 0, + }, + Object { + "x": 999998536000, + "y": 0, + }, + Object { + "x": 999998548000, + "y": 0, + }, + Object { + "x": 999998560000, + "y": 0, + }, + Object { + "x": 999998572000, + "y": 0, + }, + Object { + "x": 999998584000, + "y": 0, + }, + Object { + "x": 999998596000, + "y": 0, + }, + Object { + "x": 999998608000, + "y": 0, + }, + Object { + "x": 999998620000, + "y": 0, + }, + Object { + "x": 999998632000, + "y": 0, + }, + Object { + "x": 999998644000, + "y": 0, + }, + Object { + "x": 999998656000, + "y": 0, + }, + Object { + "x": 999998668000, + "y": 0, + }, + Object { + "x": 999998680000, + "y": 0, + }, + Object { + "x": 999998692000, + "y": 0, + }, + Object { + "x": 999998704000, + "y": 0, + }, + Object { + "x": 999998716000, + "y": 0, + }, + Object { + "x": 999998728000, + "y": 0, + }, + Object { + "x": 999998740000, + "y": 0, + }, + Object { + "x": 999998752000, + "y": 0, + }, + Object { + "x": 999998764000, + "y": 0, + }, + Object { + "x": 999998776000, + "y": 0, + }, + Object { + "x": 999998788000, + "y": 0, + }, + Object { + "x": 999998800000, + "y": 0, + }, + Object { + "x": 999998812000, + "y": 0, + }, + Object { + "x": 999998824000, + "y": 0, + }, + Object { + "x": 999998836000, + "y": 0, + }, + Object { + "x": 999998848000, + "y": 0, + }, + Object { + "x": 999998860000, + "y": 0, + }, + Object { + "x": 999998872000, + "y": 0, + }, + Object { + "x": 999998884000, + "y": 0, + }, + Object { + "x": 999998896000, + "y": 0, + }, + Object { + "x": 999998908000, + "y": 0, + }, + Object { + "x": 999998920000, + "y": 0, + }, + Object { + "x": 999998932000, + "y": 0, + }, + Object { + "x": 999998944000, + "y": 0, + }, + Object { + "x": 999998956000, + "y": 0, + }, + Object { + "x": 999998968000, + "y": 0, + }, + Object { + "x": 999998980000, + "y": 0, + }, + Object { + "x": 999998992000, + "y": 0, + }, + Object { + "x": 999999004000, + "y": 0, + }, + Object { + "x": 999999016000, + "y": 0, + }, + Object { + "x": 999999028000, + "y": 0, + }, + Object { + "x": 999999040000, + "y": 0, + }, + Object { + "x": 999999052000, + "y": 0, + }, + Object { + "x": 999999064000, + "y": 0, + }, + Object { + "x": 999999076000, + "y": 0, + }, + Object { + "x": 999999088000, + "y": 0, + }, + Object { + "x": 999999100000, + "y": 0, + }, + Object { + "x": 999999112000, + "y": 0, + }, + Object { + "x": 999999124000, + "y": 0, + }, + Object { + "x": 999999136000, + "y": 0, + }, + Object { + "x": 999999148000, + "y": 0, + }, + Object { + "x": 999999160000, + "y": 0, + }, + Object { + "x": 999999172000, + "y": 0, + }, + Object { + "x": 999999184000, + "y": 0, + }, + Object { + "x": 999999196000, + "y": 0, + }, + Object { + "x": 999999208000, + "y": 0, + }, + Object { + "x": 999999220000, + "y": 0, + }, + Object { + "x": 999999232000, + "y": 0, + }, + Object { + "x": 999999244000, + "y": 0, + }, + Object { + "x": 999999256000, + "y": 0, + }, + Object { + "x": 999999268000, + "y": 0, + }, + Object { + "x": 999999280000, + "y": 0, + }, + Object { + "x": 999999292000, + "y": 0, + }, + Object { + "x": 999999304000, + "y": 0, + }, + Object { + "x": 999999316000, + "y": 0, + }, + Object { + "x": 999999328000, + "y": 0, + }, + Object { + "x": 999999340000, + "y": 0, + }, + Object { + "x": 999999352000, + "y": 0, + }, + Object { + "x": 999999364000, + "y": 0, + }, + Object { + "x": 999999376000, + "y": 0, + }, + Object { + "x": 999999388000, + "y": 0, + }, + Object { + "x": 999999400000, + "y": 0, + }, + Object { + "x": 999999412000, + "y": 0, + }, + Object { + "x": 999999424000, + "y": 0, + }, + Object { + "x": 999999436000, + "y": 0, + }, + Object { + "x": 999999448000, + "y": 0, + }, + Object { + "x": 999999460000, + "y": 0, + }, + Object { + "x": 999999472000, + "y": 0, + }, + Object { + "x": 999999484000, + "y": 0, + }, + Object { + "x": 999999496000, + "y": 0, + }, + Object { + "x": 999999508000, + "y": 0, + }, + Object { + "x": 999999520000, + "y": 0, + }, + Object { + "x": 999999532000, + "y": 0, + }, + Object { + "x": 999999544000, + "y": 0, + }, + Object { + "x": 999999556000, + "y": 0, + }, + Object { + "x": 999999568000, + "y": 0, + }, + Object { + "x": 999999580000, + "y": 0, + }, + Object { + "x": 999999592000, + "y": 0, + }, + Object { + "x": 999999604000, + "y": 0, + }, + Object { + "x": 999999616000, + "y": 0, + }, + Object { + "x": 999999628000, + "y": 0, + }, + Object { + "x": 999999640000, + "y": 0, + }, + Object { + "x": 999999652000, + "y": 0, + }, + Object { + "x": 999999664000, + "y": 0, + }, + Object { + "x": 999999676000, + "y": 0, + }, + Object { + "x": 999999688000, + "y": 0, + }, + Object { + "x": 999999700000, + "y": 0, + }, + Object { + "x": 999999712000, + "y": 0, + }, + Object { + "x": 999999724000, + "y": 0, + }, + Object { + "x": 999999736000, + "y": 0, + }, + Object { + "x": 999999748000, + "y": 0, + }, + Object { + "x": 999999760000, + "y": 0, + }, + Object { + "x": 999999772000, + "y": 0, + }, + Object { + "x": 999999784000, + "y": 0, + }, + Object { + "x": 999999796000, + "y": 0, + }, + Object { + "x": 999999808000, + "y": 0, + }, + Object { + "x": 999999820000, + "y": 0, + }, + Object { + "x": 999999832000, + "y": 0, + }, + Object { + "x": 999999844000, + "y": 0, + }, + Object { + "x": 999999856000, + "y": 0, + }, + Object { + "x": 999999868000, + "y": 0, + }, + Object { + "x": 999999880000, + "y": 0, + }, + Object { + "x": 999999892000, + "y": 0, + }, + Object { + "x": 999999904000, + "y": 0, + }, + Object { + "x": 999999916000, + "y": 0, + }, + Object { + "x": 999999928000, + "y": 0, + }, + Object { + "x": 999999940000, + "y": 0, + }, + Object { + "x": 999999952000, + "y": 0, + }, + Object { + "x": 999999964000, + "y": 0, + }, + Object { + "x": 999999976000, + "y": 2, + }, + Object { + "x": 999999988000, + "y": 2, + }, + Object { + "x": 1000000000000, + "y": 2, + }, + ], + "name": "us_east_1a-123456/2", + "type": "line", + }, + Object { + "data": Array [ + Object { + "x": 999997852000, + "y": 0, + }, + Object { + "x": 999997864000, + "y": 0, + }, + Object { + "x": 999997876000, + "y": 0, + }, + Object { + "x": 999997888000, + "y": 0, + }, + Object { + "x": 999997900000, + "y": 0, + }, + Object { + "x": 999997912000, + "y": 0, + }, + Object { + "x": 999997924000, + "y": 0, + }, + Object { + "x": 999997936000, + "y": 0, + }, + Object { + "x": 999997948000, + "y": 0, + }, + Object { + "x": 999997960000, + "y": 0, + }, + Object { + "x": 999997972000, + "y": 0, + }, + Object { + "x": 999997984000, + "y": 0, + }, + Object { + "x": 999997996000, + "y": 0, + }, + Object { + "x": 999998008000, + "y": 0, + }, + Object { + "x": 999998020000, + "y": 0, + }, + Object { + "x": 999998032000, + "y": 0, + }, + Object { + "x": 999998044000, + "y": 0, + }, + Object { + "x": 999998056000, + "y": 0, + }, + Object { + "x": 999998068000, + "y": 0, + }, + Object { + "x": 999998080000, + "y": 0, + }, + Object { + "x": 999998092000, + "y": 0, + }, + Object { + "x": 999998104000, + "y": 0, + }, + Object { + "x": 999998116000, + "y": 0, + }, + Object { + "x": 999998128000, + "y": 0, + }, + Object { + "x": 999998140000, + "y": 0, + }, + Object { + "x": 999998152000, + "y": 0, + }, + Object { + "x": 999998164000, + "y": 0, + }, + Object { + "x": 999998176000, + "y": 0, + }, + Object { + "x": 999998188000, + "y": 0, + }, + Object { + "x": 999998200000, + "y": 0, + }, + Object { + "x": 999998212000, + "y": 0, + }, + Object { + "x": 999998224000, + "y": 0, + }, + Object { + "x": 999998236000, + "y": 0, + }, + Object { + "x": 999998248000, + "y": 0, + }, + Object { + "x": 999998260000, + "y": 0, + }, + Object { + "x": 999998272000, + "y": 0, + }, + Object { + "x": 999998284000, + "y": 0, + }, + Object { + "x": 999998296000, + "y": 0, + }, + Object { + "x": 999998308000, + "y": 0, + }, + Object { + "x": 999998320000, + "y": 0, + }, + Object { + "x": 999998332000, + "y": 0, + }, + Object { + "x": 999998344000, + "y": 0, + }, + Object { + "x": 999998356000, + "y": 0, + }, + Object { + "x": 999998368000, + "y": 0, + }, + Object { + "x": 999998380000, + "y": 0, + }, + Object { + "x": 999998392000, + "y": 0, + }, + Object { + "x": 999998404000, + "y": 0, + }, + Object { + "x": 999998416000, + "y": 0, + }, + Object { + "x": 999998428000, + "y": 0, + }, + Object { + "x": 999998440000, + "y": 0, + }, + Object { + "x": 999998452000, + "y": 0, + }, + Object { + "x": 999998464000, + "y": 0, + }, + Object { + "x": 999998476000, + "y": 0, + }, + Object { + "x": 999998488000, + "y": 0, + }, + Object { + "x": 999998500000, + "y": 0, + }, + Object { + "x": 999998512000, + "y": 0, + }, + Object { + "x": 999998524000, + "y": 0, + }, + Object { + "x": 999998536000, + "y": 0, + }, + Object { + "x": 999998548000, + "y": 0, + }, + Object { + "x": 999998560000, + "y": 0, + }, + Object { + "x": 999998572000, + "y": 0, + }, + Object { + "x": 999998584000, + "y": 0, + }, + Object { + "x": 999998596000, + "y": 0, + }, + Object { + "x": 999998608000, + "y": 0, + }, + Object { + "x": 999998620000, + "y": 0, + }, + Object { + "x": 999998632000, + "y": 0, + }, + Object { + "x": 999998644000, + "y": 0, + }, + Object { + "x": 999998656000, + "y": 0, + }, + Object { + "x": 999998668000, + "y": 0, + }, + Object { + "x": 999998680000, + "y": 0, + }, + Object { + "x": 999998692000, + "y": 0, + }, + Object { + "x": 999998704000, + "y": 0, + }, + Object { + "x": 999998716000, + "y": 0, + }, + Object { + "x": 999998728000, + "y": 0, + }, + Object { + "x": 999998740000, + "y": 0, + }, + Object { + "x": 999998752000, + "y": 0, + }, + Object { + "x": 999998764000, + "y": 0, + }, + Object { + "x": 999998776000, + "y": 0, + }, + Object { + "x": 999998788000, + "y": 0, + }, + Object { + "x": 999998800000, + "y": 0, + }, + Object { + "x": 999998812000, + "y": 0, + }, + Object { + "x": 999998824000, + "y": 0, + }, + Object { + "x": 999998836000, + "y": 0, + }, + Object { + "x": 999998848000, + "y": 0, + }, + Object { + "x": 999998860000, + "y": 0, + }, + Object { + "x": 999998872000, + "y": 0, + }, + Object { + "x": 999998884000, + "y": 0, + }, + Object { + "x": 999998896000, + "y": 0, + }, + Object { + "x": 999998908000, + "y": 0, + }, + Object { + "x": 999998920000, + "y": 0, + }, + Object { + "x": 999998932000, + "y": 0, + }, + Object { + "x": 999998944000, + "y": 0, + }, + Object { + "x": 999998956000, + "y": 0, + }, + Object { + "x": 999998968000, + "y": 0, + }, + Object { + "x": 999998980000, + "y": 0, + }, + Object { + "x": 999998992000, + "y": 0, + }, + Object { + "x": 999999004000, + "y": 0, + }, + Object { + "x": 999999016000, + "y": 0, + }, + Object { + "x": 999999028000, + "y": 0, + }, + Object { + "x": 999999040000, + "y": 0, + }, + Object { + "x": 999999052000, + "y": 0, + }, + Object { + "x": 999999064000, + "y": 0, + }, + Object { + "x": 999999076000, + "y": 0, + }, + Object { + "x": 999999088000, + "y": 0, + }, + Object { + "x": 999999100000, + "y": 0, + }, + Object { + "x": 999999112000, + "y": 0, + }, + Object { + "x": 999999124000, + "y": 0, + }, + Object { + "x": 999999136000, + "y": 0, + }, + Object { + "x": 999999148000, + "y": 0, + }, + Object { + "x": 999999160000, + "y": 0, + }, + Object { + "x": 999999172000, + "y": 0, + }, + Object { + "x": 999999184000, + "y": 0, + }, + Object { + "x": 999999196000, + "y": 0, + }, + Object { + "x": 999999208000, + "y": 0, + }, + Object { + "x": 999999220000, + "y": 0, + }, + Object { + "x": 999999232000, + "y": 0, + }, + Object { + "x": 999999244000, + "y": 0, + }, + Object { + "x": 999999256000, + "y": 0, + }, + Object { + "x": 999999268000, + "y": 0, + }, + Object { + "x": 999999280000, + "y": 0, + }, + Object { + "x": 999999292000, + "y": 0, + }, + Object { + "x": 999999304000, + "y": 0, + }, + Object { + "x": 999999316000, + "y": 0, + }, + Object { + "x": 999999328000, + "y": 0, + }, + Object { + "x": 999999340000, + "y": 0, + }, + Object { + "x": 999999352000, + "y": 0, + }, + Object { + "x": 999999364000, + "y": 0, + }, + Object { + "x": 999999376000, + "y": 0, + }, + Object { + "x": 999999388000, + "y": 0, + }, + Object { + "x": 999999400000, + "y": 0, + }, + Object { + "x": 999999412000, + "y": 0, + }, + Object { + "x": 999999424000, + "y": 0, + }, + Object { + "x": 999999436000, + "y": 0, + }, + Object { + "x": 999999448000, + "y": 0, + }, + Object { + "x": 999999460000, + "y": 0, + }, + Object { + "x": 999999472000, + "y": 0, + }, + Object { + "x": 999999484000, + "y": 0, + }, + Object { + "x": 999999496000, + "y": 0, + }, + Object { + "x": 999999508000, + "y": 0, + }, + Object { + "x": 999999520000, + "y": 0, + }, + Object { + "x": 999999532000, + "y": 0, + }, + Object { + "x": 999999544000, + "y": 0, + }, + Object { + "x": 999999556000, + "y": 0, + }, + Object { + "x": 999999568000, + "y": 0, + }, + Object { + "x": 999999580000, + "y": 0, + }, + Object { + "x": 999999592000, + "y": 0, + }, + Object { + "x": 999999604000, + "y": 0, + }, + Object { + "x": 999999616000, + "y": 0, + }, + Object { + "x": 999999628000, + "y": 0, + }, + Object { + "x": 999999640000, + "y": 0, + }, + Object { + "x": 999999652000, + "y": 0, + }, + Object { + "x": 999999664000, + "y": 0, + }, + Object { + "x": 999999676000, + "y": 0, + }, + Object { + "x": 999999688000, + "y": 0, + }, + Object { + "x": 999999700000, + "y": 0, + }, + Object { + "x": 999999712000, + "y": 0, + }, + Object { + "x": 999999724000, + "y": 0, + }, + Object { + "x": 999999736000, + "y": 0, + }, + Object { + "x": 999999748000, + "y": 0, + }, + Object { + "x": 999999760000, + "y": 0, + }, + Object { + "x": 999999772000, + "y": 0, + }, + Object { + "x": 999999784000, + "y": 0, + }, + Object { + "x": 999999796000, + "y": 0, + }, + Object { + "x": 999999808000, + "y": 0, + }, + Object { + "x": 999999820000, + "y": 0, + }, + Object { + "x": 999999832000, + "y": 0, + }, + Object { + "x": 999999844000, + "y": 0, + }, + Object { + "x": 999999856000, + "y": 0, + }, + Object { + "x": 999999868000, + "y": 0, + }, + Object { + "x": 999999880000, + "y": 0, + }, + Object { + "x": 999999892000, + "y": 0, + }, + Object { + "x": 999999904000, + "y": 0, + }, + Object { + "x": 999999916000, + "y": 0, + }, + Object { + "x": 999999928000, + "y": 0, + }, + Object { + "x": 999999940000, + "y": 0, + }, + Object { + "x": 999999952000, + "y": 0, + }, + Object { + "x": 999999964000, + "y": 0, + }, + Object { + "x": 999999976000, + "y": 1, + }, + Object { + "x": 999999988000, + "y": 1, + }, + Object { + "x": 1000000000000, + "y": 1, + }, + ], + "name": "us_east_1a-789012/1", + "type": "line", + }, +] +`; diff --git a/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx b/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx index b9c8a472a70..23437ac07ee 100644 --- a/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx +++ b/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx @@ -29,6 +29,7 @@ import { DataTable } from '../../dataTable/DataTable'; import { KeyspaceLink } from '../../links/KeyspaceLink'; import { TabletLink } from '../../links/TabletLink'; import { StreamStatePip } from '../../pips/StreamStatePip'; +import { WorkflowStreamsLagChart } from '../../charts/WorkflowStreamsLagChart'; interface Props { clusterID: string; @@ -39,7 +40,7 @@ interface Props { const COLUMNS = ['Stream', 'Source', 'Target', 'Tablet']; export const WorkflowStreams = ({ clusterID, keyspace, name }: Props) => { - const { data } = useWorkflow({ clusterID, keyspace, name }, { refetchInterval: 1000 }); + const { data } = useWorkflow({ clusterID, keyspace, name }); const streams = useMemo(() => { const rows = getStreams(data).map((stream) => ({ @@ -107,6 +108,10 @@ export const WorkflowStreams = ({ clusterID, keyspace, name }: Props) => { return (
+

Stream VReplication Lag

+ + +

Streams

{/* TODO(doeg): add a protobuf enum for this (https://github.com/vitessio/vitess/projects/12#card-60190340) */} {['Error', 'Copying', 'Running', 'Stopped'].map((streamState) => { if (!Array.isArray(streamsByState[streamState])) { diff --git a/web/vtadmin/src/util/tabletDebugVars.ts b/web/vtadmin/src/util/tabletDebugVars.ts index aebf108ca94..37ea08e49b1 100644 --- a/web/vtadmin/src/util/tabletDebugVars.ts +++ b/web/vtadmin/src/util/tabletDebugVars.ts @@ -37,6 +37,7 @@ export type TabletDebugVars = Partial<{ QPS: { [k: string]: number[] }; // See https://github.com/vitessio/vitess/blob/main/go/vt/vttablet/tabletmanager/vreplication/stats.go + VReplicationLag: { [k: string]: number[] }; VReplicationQPS: { [k: string]: number[] }; }>; @@ -50,6 +51,11 @@ export type TimeseriesMap = { [seriesName: string]: TimeseriesPoint[] }; export const getQPSTimeseries = (d: TabletDebugVars | null | undefined, endAt?: number): TimeseriesMap => formatTimeseriesMap(d?.QPS || {}, endAt); +export const getStreamVReplicationLagTimeseries = ( + d: TabletDebugVars | null | undefined, + endAt?: number +): TimeseriesMap => formatTimeseriesMap(d?.VReplicationLag || {}, endAt); + export const getVReplicationQPSTimeseries = (d: TabletDebugVars | null | undefined, endAt?: number): TimeseriesMap => formatTimeseriesMap(d?.VReplicationQPS || {}, endAt); From cc331b89a19370d956872ca035a58e8af7323148 Mon Sep 17 00:00:00 2001 From: Sara Bee <855595+doeg@users.noreply.github.com> Date: Mon, 14 Jun 2021 11:54:10 -0400 Subject: [PATCH 288/310] [vtadmin-web] Improve WorkflowStreamsLagChart rendering when no data to show Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com> --- .../charts/WorkflowStreamsLagChart.tsx | 45 +++++++++++++++---- .../routes/workflow/WorkflowStreams.tsx | 8 +++- web/vtadmin/src/hooks/api.ts | 2 + 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx b/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx index 699983527d3..2cfb6491952 100644 --- a/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx +++ b/web/vtadmin/src/components/charts/WorkflowStreamsLagChart.tsx @@ -15,6 +15,7 @@ */ import { useMemo } from 'react'; + import { useManyExperimentalTabletDebugVars, useWorkflow } from '../../hooks/api'; import { vtadmin } from '../../proto/vtadmin'; import { getStreamVReplicationLagTimeseries, QPS_REFETCH_INTERVAL } from '../../util/tabletDebugVars'; @@ -27,6 +28,10 @@ interface Props { workflowName: string; } +// Default min/max values (in seconds) for the y-axis when there is no data to show. +const DEFAULT_Y_MAX = 5; +const DEFAULT_Y_MIN = 0; + export const WorkflowStreamsLagChart = ({ clusterID, keyspace, workflowName }: Props) => { const { data: workflow, ...wq } = useWorkflow({ clusterID, keyspace, name: workflowName }); @@ -44,12 +49,22 @@ export const WorkflowStreamsLagChart = ({ clusterID, keyspace, workflowName }: P const anyLoading = wq.isLoading || tabletQueries.some((q) => q.isLoading); const chartOptions: Highcharts.Options = useMemo(() => { + const series = formatSeries(workflow, tabletQueries); + const allSeriesEmpty = series.every((s) => !s.data?.length); + return { - series: formatSeries(workflow, tabletQueries), + series, yAxis: { labels: { format: '{text} s', }, + // The desired behaviour is to show axes + grid lines + // even when there is no data to show. Unfortunately, setting + // softMin/softMax (which is more flexible) doesn't work with showEmpty. + // Instead, we must set explicit min/max, but only when all series are empty. + // If at least one series has data, allow min/max to be automatically calculated. + max: allSeriesEmpty ? DEFAULT_Y_MAX : null, + min: allSeriesEmpty ? DEFAULT_Y_MIN : null, }, }; }, [tabletQueries, workflow]); @@ -57,10 +72,11 @@ export const WorkflowStreamsLagChart = ({ clusterID, keyspace, workflowName }: P return ; }; +// Internal function, exported only for testing. export const formatSeries = ( workflow: vtadmin.Workflow | null | undefined, tabletQueries: ReturnType -): Highcharts.SeriesOptionsType[] => { +): Highcharts.SeriesLineOptions[] => { if (!workflow) { return []; } @@ -68,9 +84,19 @@ export const formatSeries = ( // Get streamKeys for streams in this workflow. const streamKeys = getStreams(workflow).map((s) => formatStreamKey(s)); - return tabletQueries.reduce((acc, tq) => { + // Initialize the timeseries from the workflow, so that every stream in the workflow + // is shown in the legend, even if the /debug/vars data isn't (yet) available. + const seriesByStreamKey: { [streamKey: string]: Highcharts.SeriesLineOptions } = {}; + + streamKeys.forEach((streamKey) => { + if (streamKey) { + seriesByStreamKey[streamKey] = { data: [], name: streamKey, type: 'line' }; + } + }); + + tabletQueries.forEach((tq) => { if (!tq.data) { - return acc; + return; } const tabletAlias = tq.data.params.alias; @@ -84,15 +110,16 @@ export const formatSeries = ( return; } - // Don't graph series for streams that aren't in this workflow. const streamKey = `${tabletAlias}/${streamID}`; - if (streamKeys.indexOf(streamKey) < 0) { + + // Don't graph series for streams that aren't in this workflow. + if (!(streamKey in seriesByStreamKey)) { return; } - acc.push({ data: streamLagData, name: streamKey, type: 'line' }); + seriesByStreamKey[streamKey].data = streamLagData; }); + }); - return acc; - }, [] as Highcharts.SeriesOptionsType[]); + return Object.values(seriesByStreamKey); }; diff --git a/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx b/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx index 23437ac07ee..61cdb5d4859 100644 --- a/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx +++ b/web/vtadmin/src/components/routes/workflow/WorkflowStreams.tsx @@ -108,8 +108,12 @@ export const WorkflowStreams = ({ clusterID, keyspace, name }: Props) => { return (
-

Stream VReplication Lag

- + {process.env.REACT_APP_ENABLE_EXPERIMENTAL_TABLET_DEBUG_VARS && ( + <> +

Stream VReplication Lag

+ + + )}

Streams

{/* TODO(doeg): add a protobuf enum for this (https://github.com/vitessio/vitess/projects/12#card-60190340) */} diff --git a/web/vtadmin/src/hooks/api.ts b/web/vtadmin/src/hooks/api.ts index 10d47e3bf33..8b2c89f2584 100644 --- a/web/vtadmin/src/hooks/api.ts +++ b/web/vtadmin/src/hooks/api.ts @@ -92,6 +92,8 @@ export const useExperimentalTabletDebugVars = ( ); }; +// Future enhancement: add vtadmin-api endpoint to fetch /debug/vars +// for multiple tablets in a single request. https://github.com/vitessio/vitess/projects/12#card-63086674 export const useManyExperimentalTabletDebugVars = ( params: FetchTabletParams[], defaultOptions: UseQueryOptions = {} From c6dafba9241c487fcd6cd6358dd5da7f123fe753 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Sat, 12 Jun 2021 12:21:49 -0400 Subject: [PATCH 289/310] Add additional fields to BackupInfo proto and filtering options to GetBackupsRequest Signed-off-by: Andrew Mason --- go/vt/proto/mysqlctl/mysqlctl.pb.go | 299 ++++++-- go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go | 262 +++++++ go/vt/proto/vtctldata/vtctldata.pb.go | 718 +++++++++--------- go/vt/proto/vtctldata/vtctldata_vtproto.pb.go | 87 +++ proto/mysqlctl.proto | 34 + proto/vtctldata.proto | 14 + web/vtadmin/src/proto/vtadmin.d.ts | 66 ++ web/vtadmin/src/proto/vtadmin.js | 256 +++++++ 8 files changed, 1318 insertions(+), 418 deletions(-) diff --git a/go/vt/proto/mysqlctl/mysqlctl.pb.go b/go/vt/proto/mysqlctl/mysqlctl.pb.go index f9aa3920e53..457c19b6d0f 100644 --- a/go/vt/proto/mysqlctl/mysqlctl.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl.pb.go @@ -29,6 +29,8 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + topodata "vitess.io/vitess/go/vt/proto/topodata" + vttime "vitess.io/vitess/go/vt/proto/vttime" ) const ( @@ -38,6 +40,66 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +// Status is an enum representing the possible status of a backup. +type BackupInfo_Status int32 + +const ( + BackupInfo_UNKNOWN BackupInfo_Status = 0 + BackupInfo_INCOMPLETE BackupInfo_Status = 1 + BackupInfo_COMPLETE BackupInfo_Status = 2 + // A backup status of INVALID should be set if the backup is complete + // but unusable in some way (partial upload, corrupt file, etc). + BackupInfo_INVALID BackupInfo_Status = 3 + // A backup status of VALID should be set if the backup is both + // complete and usuable. + BackupInfo_VALID BackupInfo_Status = 4 +) + +// Enum value maps for BackupInfo_Status. +var ( + BackupInfo_Status_name = map[int32]string{ + 0: "UNKNOWN", + 1: "INCOMPLETE", + 2: "COMPLETE", + 3: "INVALID", + 4: "VALID", + } + BackupInfo_Status_value = map[string]int32{ + "UNKNOWN": 0, + "INCOMPLETE": 1, + "COMPLETE": 2, + "INVALID": 3, + "VALID": 4, + } +) + +func (x BackupInfo_Status) Enum() *BackupInfo_Status { + p := new(BackupInfo_Status) + *p = x + return p +} + +func (x BackupInfo_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (BackupInfo_Status) Descriptor() protoreflect.EnumDescriptor { + return file_mysqlctl_proto_enumTypes[0].Descriptor() +} + +func (BackupInfo_Status) Type() protoreflect.EnumType { + return &file_mysqlctl_proto_enumTypes[0] +} + +func (x BackupInfo_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use BackupInfo_Status.Descriptor instead. +func (BackupInfo_Status) EnumDescriptor() ([]byte, []int) { + return file_mysqlctl_proto_rawDescGZIP(), []int{10, 0} +} + type StartRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -442,8 +504,16 @@ type BackupInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Directory string `protobuf:"bytes,2,opt,name=directory,proto3" json:"directory,omitempty"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Directory string `protobuf:"bytes,2,opt,name=directory,proto3" json:"directory,omitempty"` + Keyspace string `protobuf:"bytes,3,opt,name=keyspace,proto3" json:"keyspace,omitempty"` + Shard string `protobuf:"bytes,4,opt,name=shard,proto3" json:"shard,omitempty"` + TabletAlias *topodata.TabletAlias `protobuf:"bytes,5,opt,name=tablet_alias,json=tabletAlias,proto3" json:"tablet_alias,omitempty"` + Time *vttime.Time `protobuf:"bytes,6,opt,name=time,proto3" json:"time,omitempty"` + // Engine is the name of the backupengine implementation used to create + // this backup. + Engine string `protobuf:"bytes,7,opt,name=engine,proto3" json:"engine,omitempty"` + Status BackupInfo_Status `protobuf:"varint,8,opt,name=status,proto3,enum=mysqlctl.BackupInfo_Status" json:"status,omitempty"` } func (x *BackupInfo) Reset() { @@ -492,61 +562,124 @@ func (x *BackupInfo) GetDirectory() string { return "" } +func (x *BackupInfo) GetKeyspace() string { + if x != nil { + return x.Keyspace + } + return "" +} + +func (x *BackupInfo) GetShard() string { + if x != nil { + return x.Shard + } + return "" +} + +func (x *BackupInfo) GetTabletAlias() *topodata.TabletAlias { + if x != nil { + return x.TabletAlias + } + return nil +} + +func (x *BackupInfo) GetTime() *vttime.Time { + if x != nil { + return x.Time + } + return nil +} + +func (x *BackupInfo) GetEngine() string { + if x != nil { + return x.Engine + } + return "" +} + +func (x *BackupInfo) GetStatus() BackupInfo_Status { + if x != nil { + return x.Status + } + return BackupInfo_UNKNOWN +} + var File_mysqlctl_proto protoreflect.FileDescriptor var file_mysqlctl_proto_rawDesc = []byte{ 0x0a, 0x0e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x08, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x22, 0x2f, 0x0a, 0x0c, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x79, - 0x73, 0x71, 0x6c, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x0a, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x64, 0x41, 0x72, 0x67, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0f, - 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x26, 0x0a, 0x0f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x6d, 0x79, 0x73, 0x71, - 0x6c, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, - 0x72, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64, - 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x52, - 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, - 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x15, 0x0a, 0x13, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x69, 0x6e, 0x69, - 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x16, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x66, 0x72, 0x65, - 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x3e, 0x0a, 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, - 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, - 0x32, 0x8a, 0x03, 0x0a, 0x08, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x43, 0x74, 0x6c, 0x12, 0x3a, 0x0a, - 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, - 0x6c, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, - 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x08, 0x53, 0x68, 0x75, - 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x19, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, - 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1a, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x53, 0x68, 0x75, 0x74, - 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, - 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, - 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x75, 0x6e, + 0x12, 0x08, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x1a, 0x0e, 0x74, 0x6f, 0x70, 0x6f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x76, 0x74, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2f, 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x79, 0x73, 0x71, + 0x6c, 0x64, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x6d, + 0x79, 0x73, 0x71, 0x6c, 0x64, 0x41, 0x72, 0x67, 0x73, 0x22, 0x0f, 0x0a, 0x0d, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x39, 0x0a, 0x0f, 0x53, 0x68, + 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, + 0x0f, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77, 0x61, 0x69, 0x74, 0x46, 0x6f, 0x72, 0x4d, + 0x79, 0x73, 0x71, 0x6c, 0x64, 0x22, 0x12, 0x0a, 0x10, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, - 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0c, 0x52, 0x65, 0x69, 0x6e, - 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, - 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, - 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, 0x0d, 0x52, 0x65, 0x66, - 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1e, 0x2e, 0x6d, 0x79, 0x73, - 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x79, 0x73, - 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x27, 0x5a, - 0x25, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, - 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x79, - 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x74, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, + 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15, + 0x0a, 0x13, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x0a, + 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xe6, + 0x02, 0x0a, 0x0a, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x74, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x65, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, + 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, + 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4b, 0x0a, 0x06, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x0e, 0x0a, 0x0a, 0x49, 0x4e, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, + 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x02, 0x12, + 0x0b, 0x0a, 0x07, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x10, 0x04, 0x32, 0x8a, 0x03, 0x0a, 0x08, 0x4d, 0x79, 0x73, 0x71, + 0x6c, 0x43, 0x74, 0x6c, 0x12, 0x3a, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x16, 0x2e, + 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x43, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x12, 0x19, 0x2e, 0x6d, + 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, + 0x74, 0x6c, 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0f, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, + 0x6c, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x20, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, + 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, 0x70, 0x67, 0x72, + 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x79, 0x73, + 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x75, 0x6e, 0x4d, 0x79, 0x73, 0x71, 0x6c, 0x55, 0x70, + 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x4f, 0x0a, 0x0c, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, + 0x1d, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x69, 0x6e, 0x69, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, + 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x69, 0x6e, 0x69, 0x74, + 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x52, 0x0a, 0x0d, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1e, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x27, 0x5a, 0x25, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, + 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -561,36 +694,43 @@ func file_mysqlctl_proto_rawDescGZIP() []byte { return file_mysqlctl_proto_rawDescData } +var file_mysqlctl_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_mysqlctl_proto_msgTypes = make([]protoimpl.MessageInfo, 11) var file_mysqlctl_proto_goTypes = []interface{}{ - (*StartRequest)(nil), // 0: mysqlctl.StartRequest - (*StartResponse)(nil), // 1: mysqlctl.StartResponse - (*ShutdownRequest)(nil), // 2: mysqlctl.ShutdownRequest - (*ShutdownResponse)(nil), // 3: mysqlctl.ShutdownResponse - (*RunMysqlUpgradeRequest)(nil), // 4: mysqlctl.RunMysqlUpgradeRequest - (*RunMysqlUpgradeResponse)(nil), // 5: mysqlctl.RunMysqlUpgradeResponse - (*ReinitConfigRequest)(nil), // 6: mysqlctl.ReinitConfigRequest - (*ReinitConfigResponse)(nil), // 7: mysqlctl.ReinitConfigResponse - (*RefreshConfigRequest)(nil), // 8: mysqlctl.RefreshConfigRequest - (*RefreshConfigResponse)(nil), // 9: mysqlctl.RefreshConfigResponse - (*BackupInfo)(nil), // 10: mysqlctl.BackupInfo + (BackupInfo_Status)(0), // 0: mysqlctl.BackupInfo.Status + (*StartRequest)(nil), // 1: mysqlctl.StartRequest + (*StartResponse)(nil), // 2: mysqlctl.StartResponse + (*ShutdownRequest)(nil), // 3: mysqlctl.ShutdownRequest + (*ShutdownResponse)(nil), // 4: mysqlctl.ShutdownResponse + (*RunMysqlUpgradeRequest)(nil), // 5: mysqlctl.RunMysqlUpgradeRequest + (*RunMysqlUpgradeResponse)(nil), // 6: mysqlctl.RunMysqlUpgradeResponse + (*ReinitConfigRequest)(nil), // 7: mysqlctl.ReinitConfigRequest + (*ReinitConfigResponse)(nil), // 8: mysqlctl.ReinitConfigResponse + (*RefreshConfigRequest)(nil), // 9: mysqlctl.RefreshConfigRequest + (*RefreshConfigResponse)(nil), // 10: mysqlctl.RefreshConfigResponse + (*BackupInfo)(nil), // 11: mysqlctl.BackupInfo + (*topodata.TabletAlias)(nil), // 12: topodata.TabletAlias + (*vttime.Time)(nil), // 13: vttime.Time } var file_mysqlctl_proto_depIdxs = []int32{ - 0, // 0: mysqlctl.MysqlCtl.Start:input_type -> mysqlctl.StartRequest - 2, // 1: mysqlctl.MysqlCtl.Shutdown:input_type -> mysqlctl.ShutdownRequest - 4, // 2: mysqlctl.MysqlCtl.RunMysqlUpgrade:input_type -> mysqlctl.RunMysqlUpgradeRequest - 6, // 3: mysqlctl.MysqlCtl.ReinitConfig:input_type -> mysqlctl.ReinitConfigRequest - 8, // 4: mysqlctl.MysqlCtl.RefreshConfig:input_type -> mysqlctl.RefreshConfigRequest - 1, // 5: mysqlctl.MysqlCtl.Start:output_type -> mysqlctl.StartResponse - 3, // 6: mysqlctl.MysqlCtl.Shutdown:output_type -> mysqlctl.ShutdownResponse - 5, // 7: mysqlctl.MysqlCtl.RunMysqlUpgrade:output_type -> mysqlctl.RunMysqlUpgradeResponse - 7, // 8: mysqlctl.MysqlCtl.ReinitConfig:output_type -> mysqlctl.ReinitConfigResponse - 9, // 9: mysqlctl.MysqlCtl.RefreshConfig:output_type -> mysqlctl.RefreshConfigResponse - 5, // [5:10] is the sub-list for method output_type - 0, // [0:5] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name + 12, // 0: mysqlctl.BackupInfo.tablet_alias:type_name -> topodata.TabletAlias + 13, // 1: mysqlctl.BackupInfo.time:type_name -> vttime.Time + 0, // 2: mysqlctl.BackupInfo.status:type_name -> mysqlctl.BackupInfo.Status + 1, // 3: mysqlctl.MysqlCtl.Start:input_type -> mysqlctl.StartRequest + 3, // 4: mysqlctl.MysqlCtl.Shutdown:input_type -> mysqlctl.ShutdownRequest + 5, // 5: mysqlctl.MysqlCtl.RunMysqlUpgrade:input_type -> mysqlctl.RunMysqlUpgradeRequest + 7, // 6: mysqlctl.MysqlCtl.ReinitConfig:input_type -> mysqlctl.ReinitConfigRequest + 9, // 7: mysqlctl.MysqlCtl.RefreshConfig:input_type -> mysqlctl.RefreshConfigRequest + 2, // 8: mysqlctl.MysqlCtl.Start:output_type -> mysqlctl.StartResponse + 4, // 9: mysqlctl.MysqlCtl.Shutdown:output_type -> mysqlctl.ShutdownResponse + 6, // 10: mysqlctl.MysqlCtl.RunMysqlUpgrade:output_type -> mysqlctl.RunMysqlUpgradeResponse + 8, // 11: mysqlctl.MysqlCtl.ReinitConfig:output_type -> mysqlctl.ReinitConfigResponse + 10, // 12: mysqlctl.MysqlCtl.RefreshConfig:output_type -> mysqlctl.RefreshConfigResponse + 8, // [8:13] is the sub-list for method output_type + 3, // [3:8] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_mysqlctl_proto_init() } @@ -737,13 +877,14 @@ func file_mysqlctl_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_mysqlctl_proto_rawDesc, - NumEnums: 0, + NumEnums: 1, NumMessages: 11, NumExtensions: 0, NumServices: 1, }, GoTypes: file_mysqlctl_proto_goTypes, DependencyIndexes: file_mysqlctl_proto_depIdxs, + EnumInfos: file_mysqlctl_proto_enumTypes, MessageInfos: file_mysqlctl_proto_msgTypes, }.Build() File_mysqlctl_proto = out.File diff --git a/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go b/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go index 8cd92a5a43c..21ea5fa0ede 100644 --- a/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go +++ b/go/vt/proto/mysqlctl/mysqlctl_vtproto.pb.go @@ -9,6 +9,8 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" io "io" bits "math/bits" + topodata "vitess.io/vitess/go/vt/proto/topodata" + vttime "vitess.io/vitess/go/vt/proto/vttime" ) const ( @@ -397,6 +399,56 @@ func (m *BackupInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.Status != 0 { + i = encodeVarint(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x40 + } + if len(m.Engine) > 0 { + i -= len(m.Engine) + copy(dAtA[i:], m.Engine) + i = encodeVarint(dAtA, i, uint64(len(m.Engine))) + i-- + dAtA[i] = 0x3a + } + if m.Time != nil { + { + size, err := m.Time.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.TabletAlias != nil { + { + size, err := m.TabletAlias.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarint(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.Shard) > 0 { + i -= len(m.Shard) + copy(dAtA[i:], m.Shard) + i = encodeVarint(dAtA, i, uint64(len(m.Shard))) + i-- + dAtA[i] = 0x22 + } + if len(m.Keyspace) > 0 { + i -= len(m.Keyspace) + copy(dAtA[i:], m.Keyspace) + i = encodeVarint(dAtA, i, uint64(len(m.Keyspace))) + i-- + dAtA[i] = 0x1a + } if len(m.Directory) > 0 { i -= len(m.Directory) copy(dAtA[i:], m.Directory) @@ -568,6 +620,29 @@ func (m *BackupInfo) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + l = len(m.Keyspace) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + l = len(m.Shard) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.TabletAlias != nil { + l = m.TabletAlias.SizeVT() + n += 1 + l + sov(uint64(l)) + } + if m.Time != nil { + l = m.Time.SizeVT() + n += 1 + l + sov(uint64(l)) + } + l = len(m.Engine) + if l > 0 { + n += 1 + l + sov(uint64(l)) + } + if m.Status != 0 { + n += 1 + sov(uint64(m.Status)) + } if m.unknownFields != nil { n += len(m.unknownFields) } @@ -1235,6 +1310,193 @@ func (m *BackupInfo) UnmarshalVT(dAtA []byte) error { } m.Directory = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Keyspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Shard", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Shard = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TabletAlias", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TabletAlias == nil { + m.TabletAlias = &topodata.TabletAlias{} + } + if err := m.TabletAlias.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Time == nil { + m.Time = &vttime.Time{} + } + if err := m.Time.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Engine", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Engine = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= BackupInfo_Status(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/go/vt/proto/vtctldata/vtctldata.pb.go b/go/vt/proto/vtctldata/vtctldata.pb.go index c7430f821c5..163afba3601 100644 --- a/go/vt/proto/vtctldata/vtctldata.pb.go +++ b/go/vt/proto/vtctldata/vtctldata.pb.go @@ -2142,6 +2142,20 @@ type GetBackupsRequest struct { Keyspace string `protobuf:"bytes,1,opt,name=keyspace,proto3" json:"keyspace,omitempty"` Shard string `protobuf:"bytes,2,opt,name=shard,proto3" json:"shard,omitempty"` + // Limit, if nonzero, will return only the most N recent backups. + Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + // Detailed indicates whether to use the backupengine, if supported, to + // populate additional fields, such as Engine and Status, on BackupInfo + // objects in the response. If not set, or if the backupengine does not + // support populating these fields, Engine will always be empty, and Status + // will always be UNKNOWN. + Detailed bool `protobuf:"varint,4,opt,name=detailed,proto3" json:"detailed,omitempty"` + // DetailedLimit, if nonzero, will only populate additional fields (see Detailed) + // on the N most recent backups. The Limit field still dictates the total + // number of backup info objects returned, so, in reality, min(Limit, DetailedLimit) + // backup infos will have additional fields set, and any remaining backups + // will not. + DetailedLimit uint32 `protobuf:"varint,5,opt,name=detailed_limit,json=detailedLimit,proto3" json:"detailed_limit,omitempty"` } func (x *GetBackupsRequest) Reset() { @@ -2190,6 +2204,27 @@ func (x *GetBackupsRequest) GetShard() string { return "" } +func (x *GetBackupsRequest) GetLimit() uint32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *GetBackupsRequest) GetDetailed() bool { + if x != nil { + return x.Detailed + } + return false +} + +func (x *GetBackupsRequest) GetDetailedLimit() uint32 { + if x != nil { + return x.DetailedLimit + } + return 0 +} + type GetBackupsResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -5910,358 +5945,363 @@ var file_vtctldata_proto_rawDesc = []byte{ 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, - 0x72, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x45, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, - 0x68, 0x61, 0x72, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, - 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x62, 0x61, - 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x79, - 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, - 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, - 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, - 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x19, 0x0a, 0x17, - 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x30, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x65, - 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, - 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0xb6, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, - 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x49, 0x0a, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x07, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, - 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x15, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6b, - 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x52, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x30, - 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, - 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x22, 0x55, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, - 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, - 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, - 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, - 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, - 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, - 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, - 0x22, 0x50, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x22, 0x4c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, - 0x22, 0x3a, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x4a, 0x0a, 0x16, - 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, - 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x76, 0x74, - 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, - 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0c, 0x73, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, - 0x56, 0x0a, 0x11, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, + 0x72, 0x64, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9e, 0x01, + 0x0a, 0x11, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x64, + 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x64, 0x65, 0x74, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0d, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x44, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x63, 0x74, 0x6c, + 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x62, 0x61, 0x63, + 0x6b, 0x75, 0x70, 0x73, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x46, + 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x22, 0x30, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, + 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xb6, 0x01, + 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x61, 0x6c, 0x69, + 0x61, 0x73, 0x65, 0x73, 0x1a, 0x50, 0x0a, 0x0c, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x72, - 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, - 0x65, 0x6c, 0x6c, 0x22, 0x4e, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, - 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, - 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x0a, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x22, 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x15, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x49, 0x0a, + 0x14, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x22, 0x30, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x46, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x2f, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x55, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x0d, 0x72, 0x6f, 0x75, 0x74, 0x69, + 0x6e, 0x67, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, + 0x52, 0x75, 0x6c, 0x65, 0x73, 0x52, 0x0c, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x75, + 0x6c, 0x65, 0x73, 0x22, 0x84, 0x02, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x76, 0x69, 0x65, + 0x77, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x56, 0x69, 0x65, 0x77, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, + 0x12, 0x28, 0x0a, 0x10, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5f, + 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x73, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x50, 0x0a, 0x11, 0x47, 0x65, + 0x74, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x3b, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x23, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x4c, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x0a, 0x10, 0x47, 0x65, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, + 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0x4a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, - 0x6c, 0x73, 0x22, 0xc5, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, - 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x53, 0x0a, 0x10, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, - 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x10, 0x47, 0x65, - 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, - 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x3d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, - 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, - 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, - 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x12, 0x3c, 0x0a, - 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, - 0x62, 0x6c, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x2f, 0x0a, - 0x11, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x42, - 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, - 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x22, 0x52, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, - 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, - 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, - 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, - 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x17, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x6c, 0x73, 0x22, 0xcc, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, + 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, 0x79, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x73, 0x72, 0x76, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x56, 0x0a, 0x11, 0x53, 0x72, 0x76, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x4b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x22, 0x4e, 0x0a, + 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x0c, 0x73, 0x72, 0x76, 0x5f, 0x76, 0x5f, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, + 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x52, 0x0a, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x2d, 0x0a, + 0x15, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0xc5, 0x01, 0x0a, + 0x16, 0x47, 0x65, 0x74, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x0d, 0x73, 0x72, 0x76, 0x5f, 0x76, + 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x72, + 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0b, 0x73, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x1a, + 0x53, 0x0a, 0x10, 0x53, 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x53, + 0x72, 0x76, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4c, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, + 0x61, 0x73, 0x22, 0x3d, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x22, 0xb1, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, + 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x65, 0x73, 0x22, 0x40, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, + 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x07, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x73, 0x22, 0x2f, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x53, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0x42, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, + 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, + 0x0a, 0x08, 0x76, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x11, 0x2e, 0x76, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x4b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x52, 0x07, 0x76, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x52, 0x0a, 0x13, + 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x4f, 0x6e, 0x6c, 0x79, + 0x22, 0x49, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x09, 0x77, 0x6f, 0x72, 0x6b, + 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x74, + 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, + 0x52, 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x73, 0x22, 0xfb, 0x01, 0x0a, 0x17, + 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x52, 0x0a, 0x1a, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x52, 0x17, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x45, 0x6c, 0x65, + 0x63, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, + 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x42, 0x0a, 0x18, 0x49, 0x6e, 0x69, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x89, 0x02, + 0x0a, 0x1b, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, - 0x52, 0x0a, 0x1a, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5f, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x17, 0x70, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, - 0x42, 0x0a, 0x18, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x65, - 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, - 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x73, 0x22, 0x89, 0x02, 0x0a, 0x1b, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, - 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, - 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3a, 0x0a, - 0x0d, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, + 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0c, 0x61, 0x76, 0x6f, - 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, - 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, - 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, - 0xba, 0x01, 0x0a, 0x1c, 0x50, 0x6c, 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x3a, 0x0a, 0x0d, 0x61, 0x76, 0x6f, 0x69, 0x64, + 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0c, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x12, 0x44, 0x0a, 0x15, 0x77, 0x61, 0x69, 0x74, 0x5f, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x76, 0x74, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x44, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x61, 0x69, 0x74, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x73, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xba, 0x01, 0x0a, 0x1c, 0x50, 0x6c, + 0x61, 0x6e, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, + 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, + 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, + 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, + 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, + 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x32, 0x0a, 0x1a, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x64, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, - 0x72, 0x64, 0x12, 0x40, 0x0a, 0x10, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x5f, 0x70, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0f, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, 0x64, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x12, 0x26, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6c, 0x6f, 0x67, 0x75, 0x74, 0x69, 0x6c, 0x2e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x32, 0x0a, 0x1a, - 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x47, 0x72, - 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, - 0x6c, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, - 0x22, 0x1d, 0x0a, 0x1b, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x56, 0x53, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x4f, 0x0a, 0x13, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x0c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x0b, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, - 0x22, 0x16, 0x0a, 0x14, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x64, 0x0a, 0x1a, 0x52, 0x65, 0x66, 0x72, + 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x4b, 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x73, 0x5f, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x22, 0x7f, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, + 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, + 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, + 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, + 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, + 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, + 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, + 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, + 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, + 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0x7b, 0x0a, 0x16, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, + 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, + 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x22, 0x54, 0x0a, 0x20, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x22, 0x4b, - 0x0a, 0x1b, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x65, 0x42, 0x79, - 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, - 0x12, 0x69, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x72, 0x65, 0x66, 0x72, - 0x65, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x69, 0x73, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x61, 0x6c, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x22, 0x7f, 0x0a, 0x19, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, 0x6c, - 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x1c, 0x0a, 0x1a, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x43, 0x65, - 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9b, 0x01, 0x0a, 0x16, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x68, 0x61, 0x72, 0x64, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x6c, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x63, 0x65, 0x6c, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, - 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, - 0x65, 0x63, 0x75, 0x72, 0x73, 0x69, 0x76, 0x65, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x53, 0x68, 0x61, 0x72, 0x64, 0x43, 0x65, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x46, 0x0a, 0x15, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, - 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0x7b, 0x0a, 0x16, 0x52, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x2f, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, - 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x07, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x20, 0x53, 0x68, 0x61, 0x72, - 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xaa, - 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x5a, - 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, - 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, 0x0a, 0x18, 0x52, 0x65, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4e, 0x0a, 0x0e, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, - 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x52, 0x0a, 0x21, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, - 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, - 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, - 0xc6, 0x01, 0x0a, 0x22, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, - 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, - 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, - 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x12, 0x36, 0x0a, 0x0b, 0x6f, 0x6c, 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, - 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6f, 0x6c, - 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, - 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, - 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, - 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, - 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, - 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, - 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x65, 0x0a, 0x18, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, - 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, - 0x61, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, - 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, 0x72, 0x64, 0x22, 0xaa, 0x03, 0x0a, 0x21, 0x53, 0x68, 0x61, + 0x72, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x78, + 0x0a, 0x14, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x13, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x12, 0x5a, 0x0a, 0x0a, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x74, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x76, + 0x74, 0x63, 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x64, 0x52, 0x65, + 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x4d, 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x4d, 0x61, 0x70, 0x1a, 0x5f, 0x0a, 0x18, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x2d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4e, 0x0a, 0x0e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x4d, + 0x61, 0x70, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x26, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x52, 0x0a, 0x21, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2d, 0x0a, 0x06, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x52, 0x06, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x22, 0xc6, 0x01, 0x0a, 0x22, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x52, 0x65, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, + 0x73, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x68, 0x61, + 0x72, 0x64, 0x12, 0x36, 0x0a, 0x0b, 0x6e, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, + 0x6e, 0x65, 0x77, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x36, 0x0a, 0x0b, 0x6f, 0x6c, + 0x64, 0x5f, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x6f, 0x6c, 0x64, 0x50, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x22, 0x5c, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x2f, 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, + 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, + 0x22, 0x5d, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, + 0x0a, 0x09, 0x63, 0x65, 0x6c, 0x6c, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, + 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x63, 0x65, 0x6c, 0x6c, 0x49, 0x6e, 0x66, 0x6f, 0x22, + 0x64, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, + 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, + 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, + 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x65, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, + 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x35, 0x0a, 0x0b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x5f, 0x61, + 0x6c, 0x69, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x74, 0x6f, 0x70, + 0x6f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, + 0x52, 0x0a, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x42, 0x28, 0x5a, 0x26, + 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x2f, 0x76, 0x69, 0x74, 0x65, 0x73, 0x73, + 0x2f, 0x67, 0x6f, 0x2f, 0x76, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x74, 0x63, + 0x74, 0x6c, 0x64, 0x61, 0x74, 0x61, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go index 8e721925cb9..c08c719b52c 100644 --- a/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go +++ b/go/vt/proto/vtctldata/vtctldata_vtproto.pb.go @@ -2425,6 +2425,26 @@ func (m *GetBackupsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { i -= len(m.unknownFields) copy(dAtA[i:], m.unknownFields) } + if m.DetailedLimit != 0 { + i = encodeVarint(dAtA, i, uint64(m.DetailedLimit)) + i-- + dAtA[i] = 0x28 + } + if m.Detailed { + i-- + if m.Detailed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.Limit != 0 { + i = encodeVarint(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x18 + } if len(m.Shard) > 0 { i -= len(m.Shard) copy(dAtA[i:], m.Shard) @@ -6171,6 +6191,15 @@ func (m *GetBackupsRequest) SizeVT() (n int) { if l > 0 { n += 1 + l + sov(uint64(l)) } + if m.Limit != 0 { + n += 1 + sov(uint64(m.Limit)) + } + if m.Detailed { + n += 2 + } + if m.DetailedLimit != 0 { + n += 1 + sov(uint64(m.DetailedLimit)) + } if m.unknownFields != nil { n += len(m.unknownFields) } @@ -12945,6 +12974,64 @@ func (m *GetBackupsRequest) UnmarshalVT(dAtA []byte) error { } m.Shard = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Detailed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Detailed = bool(v != 0) + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DetailedLimit", wireType) + } + m.DetailedLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DetailedLimit |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skip(dAtA[iNdEx:]) diff --git a/proto/mysqlctl.proto b/proto/mysqlctl.proto index adcd921d004..8b6cb387fdc 100644 --- a/proto/mysqlctl.proto +++ b/proto/mysqlctl.proto @@ -22,6 +22,9 @@ option go_package = "vitess.io/vitess/go/vt/proto/mysqlctl"; package mysqlctl; +import "topodata.proto"; +import "vttime.proto"; + message StartRequest{ repeated string mysqld_args = 1; } @@ -59,4 +62,35 @@ service MysqlCtl { message BackupInfo { string name = 1; string directory = 2; + + string keyspace = 3; + string shard = 4; + + // The following fields will be extracted from the .Name field. If an error + // occurs during extraction/parsing, these fields may not be set, but + // VtctldServer.GetBackups will not fail. + + topodata.TabletAlias tablet_alias = 5; + vttime.Time time = 6; + + // The following fields are may or may not be currently set. Work is inflight + // to fully-support these fields in all backupengine/storage implementations. + + // Engine is the name of the backupengine implementation used to create + // this backup. + string engine = 7; + Status status = 8; + + // Status is an enum representing the possible status of a backup. + enum Status { + UNKNOWN = 0; + INCOMPLETE = 1; + COMPLETE = 2; + // A backup status of INVALID should be set if the backup is complete + // but unusable in some way (partial upload, corrupt file, etc). + INVALID = 3; + // A backup status of VALID should be set if the backup is both + // complete and usuable. + VALID = 4; + } } diff --git a/proto/vtctldata.proto b/proto/vtctldata.proto index 01832c9cf5d..ec42a8ff5dc 100644 --- a/proto/vtctldata.proto +++ b/proto/vtctldata.proto @@ -358,6 +358,20 @@ message FindAllShardsInKeyspaceResponse { message GetBackupsRequest { string keyspace = 1; string shard = 2; + // Limit, if nonzero, will return only the most N recent backups. + uint32 limit = 3; + // Detailed indicates whether to use the backupengine, if supported, to + // populate additional fields, such as Engine and Status, on BackupInfo + // objects in the response. If not set, or if the backupengine does not + // support populating these fields, Engine will always be empty, and Status + // will always be UNKNOWN. + bool detailed = 4; + // DetailedLimit, if nonzero, will only populate additional fields (see Detailed) + // on the N most recent backups. The Limit field still dictates the total + // number of backup info objects returned, so, in reality, min(Limit, DetailedLimit) + // backup infos will have additional fields set, and any remaining backups + // will not. + uint32 detailed_limit = 5; } message GetBackupsResponse { diff --git a/web/vtadmin/src/proto/vtadmin.d.ts b/web/vtadmin/src/proto/vtadmin.d.ts index 9775ce7b631..35240c6c63c 100644 --- a/web/vtadmin/src/proto/vtadmin.d.ts +++ b/web/vtadmin/src/proto/vtadmin.d.ts @@ -27377,6 +27377,15 @@ export namespace vtctldata { /** GetBackupsRequest shard */ shard?: (string|null); + + /** GetBackupsRequest limit */ + limit?: (number|null); + + /** GetBackupsRequest detailed */ + detailed?: (boolean|null); + + /** GetBackupsRequest detailed_limit */ + detailed_limit?: (number|null); } /** Represents a GetBackupsRequest. */ @@ -27394,6 +27403,15 @@ export namespace vtctldata { /** GetBackupsRequest shard. */ public shard: string; + /** GetBackupsRequest limit. */ + public limit: number; + + /** GetBackupsRequest detailed. */ + public detailed: boolean; + + /** GetBackupsRequest detailed_limit. */ + public detailed_limit: number; + /** * Creates a new GetBackupsRequest instance using the specified properties. * @param [properties] Properties to set @@ -36599,6 +36617,24 @@ export namespace mysqlctl { /** BackupInfo directory */ directory?: (string|null); + + /** BackupInfo keyspace */ + keyspace?: (string|null); + + /** BackupInfo shard */ + shard?: (string|null); + + /** BackupInfo tablet_alias */ + tablet_alias?: (topodata.ITabletAlias|null); + + /** BackupInfo time */ + time?: (vttime.ITime|null); + + /** BackupInfo engine */ + engine?: (string|null); + + /** BackupInfo status */ + status?: (mysqlctl.BackupInfo.Status|null); } /** Represents a BackupInfo. */ @@ -36616,6 +36652,24 @@ export namespace mysqlctl { /** BackupInfo directory. */ public directory: string; + /** BackupInfo keyspace. */ + public keyspace: string; + + /** BackupInfo shard. */ + public shard: string; + + /** BackupInfo tablet_alias. */ + public tablet_alias?: (topodata.ITabletAlias|null); + + /** BackupInfo time. */ + public time?: (vttime.ITime|null); + + /** BackupInfo engine. */ + public engine: string; + + /** BackupInfo status. */ + public status: mysqlctl.BackupInfo.Status; + /** * Creates a new BackupInfo instance using the specified properties. * @param [properties] Properties to set @@ -36686,4 +36740,16 @@ export namespace mysqlctl { */ public toJSON(): { [k: string]: any }; } + + namespace BackupInfo { + + /** Status enum. */ + enum Status { + UNKNOWN = 0, + INCOMPLETE = 1, + COMPLETE = 2, + INVALID = 3, + VALID = 4 + } + } } diff --git a/web/vtadmin/src/proto/vtadmin.js b/web/vtadmin/src/proto/vtadmin.js index c0abe9aea41..acd2c904753 100644 --- a/web/vtadmin/src/proto/vtadmin.js +++ b/web/vtadmin/src/proto/vtadmin.js @@ -65747,6 +65747,9 @@ $root.vtctldata = (function() { * @interface IGetBackupsRequest * @property {string|null} [keyspace] GetBackupsRequest keyspace * @property {string|null} [shard] GetBackupsRequest shard + * @property {number|null} [limit] GetBackupsRequest limit + * @property {boolean|null} [detailed] GetBackupsRequest detailed + * @property {number|null} [detailed_limit] GetBackupsRequest detailed_limit */ /** @@ -65780,6 +65783,30 @@ $root.vtctldata = (function() { */ GetBackupsRequest.prototype.shard = ""; + /** + * GetBackupsRequest limit. + * @member {number} limit + * @memberof vtctldata.GetBackupsRequest + * @instance + */ + GetBackupsRequest.prototype.limit = 0; + + /** + * GetBackupsRequest detailed. + * @member {boolean} detailed + * @memberof vtctldata.GetBackupsRequest + * @instance + */ + GetBackupsRequest.prototype.detailed = false; + + /** + * GetBackupsRequest detailed_limit. + * @member {number} detailed_limit + * @memberof vtctldata.GetBackupsRequest + * @instance + */ + GetBackupsRequest.prototype.detailed_limit = 0; + /** * Creates a new GetBackupsRequest instance using the specified properties. * @function create @@ -65808,6 +65835,12 @@ $root.vtctldata = (function() { writer.uint32(/* id 1, wireType 2 =*/10).string(message.keyspace); if (message.shard != null && Object.hasOwnProperty.call(message, "shard")) writer.uint32(/* id 2, wireType 2 =*/18).string(message.shard); + if (message.limit != null && Object.hasOwnProperty.call(message, "limit")) + writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.limit); + if (message.detailed != null && Object.hasOwnProperty.call(message, "detailed")) + writer.uint32(/* id 4, wireType 0 =*/32).bool(message.detailed); + if (message.detailed_limit != null && Object.hasOwnProperty.call(message, "detailed_limit")) + writer.uint32(/* id 5, wireType 0 =*/40).uint32(message.detailed_limit); return writer; }; @@ -65848,6 +65881,15 @@ $root.vtctldata = (function() { case 2: message.shard = reader.string(); break; + case 3: + message.limit = reader.uint32(); + break; + case 4: + message.detailed = reader.bool(); + break; + case 5: + message.detailed_limit = reader.uint32(); + break; default: reader.skipType(tag & 7); break; @@ -65889,6 +65931,15 @@ $root.vtctldata = (function() { if (message.shard != null && message.hasOwnProperty("shard")) if (!$util.isString(message.shard)) return "shard: string expected"; + if (message.limit != null && message.hasOwnProperty("limit")) + if (!$util.isInteger(message.limit)) + return "limit: integer expected"; + if (message.detailed != null && message.hasOwnProperty("detailed")) + if (typeof message.detailed !== "boolean") + return "detailed: boolean expected"; + if (message.detailed_limit != null && message.hasOwnProperty("detailed_limit")) + if (!$util.isInteger(message.detailed_limit)) + return "detailed_limit: integer expected"; return null; }; @@ -65908,6 +65959,12 @@ $root.vtctldata = (function() { message.keyspace = String(object.keyspace); if (object.shard != null) message.shard = String(object.shard); + if (object.limit != null) + message.limit = object.limit >>> 0; + if (object.detailed != null) + message.detailed = Boolean(object.detailed); + if (object.detailed_limit != null) + message.detailed_limit = object.detailed_limit >>> 0; return message; }; @@ -65927,11 +65984,20 @@ $root.vtctldata = (function() { if (options.defaults) { object.keyspace = ""; object.shard = ""; + object.limit = 0; + object.detailed = false; + object.detailed_limit = 0; } if (message.keyspace != null && message.hasOwnProperty("keyspace")) object.keyspace = message.keyspace; if (message.shard != null && message.hasOwnProperty("shard")) object.shard = message.shard; + if (message.limit != null && message.hasOwnProperty("limit")) + object.limit = message.limit; + if (message.detailed != null && message.hasOwnProperty("detailed")) + object.detailed = message.detailed; + if (message.detailed_limit != null && message.hasOwnProperty("detailed_limit")) + object.detailed_limit = message.detailed_limit; return object; }; @@ -87244,6 +87310,12 @@ $root.mysqlctl = (function() { * @interface IBackupInfo * @property {string|null} [name] BackupInfo name * @property {string|null} [directory] BackupInfo directory + * @property {string|null} [keyspace] BackupInfo keyspace + * @property {string|null} [shard] BackupInfo shard + * @property {topodata.ITabletAlias|null} [tablet_alias] BackupInfo tablet_alias + * @property {vttime.ITime|null} [time] BackupInfo time + * @property {string|null} [engine] BackupInfo engine + * @property {mysqlctl.BackupInfo.Status|null} [status] BackupInfo status */ /** @@ -87277,6 +87349,54 @@ $root.mysqlctl = (function() { */ BackupInfo.prototype.directory = ""; + /** + * BackupInfo keyspace. + * @member {string} keyspace + * @memberof mysqlctl.BackupInfo + * @instance + */ + BackupInfo.prototype.keyspace = ""; + + /** + * BackupInfo shard. + * @member {string} shard + * @memberof mysqlctl.BackupInfo + * @instance + */ + BackupInfo.prototype.shard = ""; + + /** + * BackupInfo tablet_alias. + * @member {topodata.ITabletAlias|null|undefined} tablet_alias + * @memberof mysqlctl.BackupInfo + * @instance + */ + BackupInfo.prototype.tablet_alias = null; + + /** + * BackupInfo time. + * @member {vttime.ITime|null|undefined} time + * @memberof mysqlctl.BackupInfo + * @instance + */ + BackupInfo.prototype.time = null; + + /** + * BackupInfo engine. + * @member {string} engine + * @memberof mysqlctl.BackupInfo + * @instance + */ + BackupInfo.prototype.engine = ""; + + /** + * BackupInfo status. + * @member {mysqlctl.BackupInfo.Status} status + * @memberof mysqlctl.BackupInfo + * @instance + */ + BackupInfo.prototype.status = 0; + /** * Creates a new BackupInfo instance using the specified properties. * @function create @@ -87305,6 +87425,18 @@ $root.mysqlctl = (function() { writer.uint32(/* id 1, wireType 2 =*/10).string(message.name); if (message.directory != null && Object.hasOwnProperty.call(message, "directory")) writer.uint32(/* id 2, wireType 2 =*/18).string(message.directory); + if (message.keyspace != null && Object.hasOwnProperty.call(message, "keyspace")) + writer.uint32(/* id 3, wireType 2 =*/26).string(message.keyspace); + if (message.shard != null && Object.hasOwnProperty.call(message, "shard")) + writer.uint32(/* id 4, wireType 2 =*/34).string(message.shard); + if (message.tablet_alias != null && Object.hasOwnProperty.call(message, "tablet_alias")) + $root.topodata.TabletAlias.encode(message.tablet_alias, writer.uint32(/* id 5, wireType 2 =*/42).fork()).ldelim(); + if (message.time != null && Object.hasOwnProperty.call(message, "time")) + $root.vttime.Time.encode(message.time, writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim(); + if (message.engine != null && Object.hasOwnProperty.call(message, "engine")) + writer.uint32(/* id 7, wireType 2 =*/58).string(message.engine); + if (message.status != null && Object.hasOwnProperty.call(message, "status")) + writer.uint32(/* id 8, wireType 0 =*/64).int32(message.status); return writer; }; @@ -87345,6 +87477,24 @@ $root.mysqlctl = (function() { case 2: message.directory = reader.string(); break; + case 3: + message.keyspace = reader.string(); + break; + case 4: + message.shard = reader.string(); + break; + case 5: + message.tablet_alias = $root.topodata.TabletAlias.decode(reader, reader.uint32()); + break; + case 6: + message.time = $root.vttime.Time.decode(reader, reader.uint32()); + break; + case 7: + message.engine = reader.string(); + break; + case 8: + message.status = reader.int32(); + break; default: reader.skipType(tag & 7); break; @@ -87386,6 +87536,36 @@ $root.mysqlctl = (function() { if (message.directory != null && message.hasOwnProperty("directory")) if (!$util.isString(message.directory)) return "directory: string expected"; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + if (!$util.isString(message.keyspace)) + return "keyspace: string expected"; + if (message.shard != null && message.hasOwnProperty("shard")) + if (!$util.isString(message.shard)) + return "shard: string expected"; + if (message.tablet_alias != null && message.hasOwnProperty("tablet_alias")) { + var error = $root.topodata.TabletAlias.verify(message.tablet_alias); + if (error) + return "tablet_alias." + error; + } + if (message.time != null && message.hasOwnProperty("time")) { + var error = $root.vttime.Time.verify(message.time); + if (error) + return "time." + error; + } + if (message.engine != null && message.hasOwnProperty("engine")) + if (!$util.isString(message.engine)) + return "engine: string expected"; + if (message.status != null && message.hasOwnProperty("status")) + switch (message.status) { + default: + return "status: enum value expected"; + case 0: + case 1: + case 2: + case 3: + case 4: + break; + } return null; }; @@ -87405,6 +87585,44 @@ $root.mysqlctl = (function() { message.name = String(object.name); if (object.directory != null) message.directory = String(object.directory); + if (object.keyspace != null) + message.keyspace = String(object.keyspace); + if (object.shard != null) + message.shard = String(object.shard); + if (object.tablet_alias != null) { + if (typeof object.tablet_alias !== "object") + throw TypeError(".mysqlctl.BackupInfo.tablet_alias: object expected"); + message.tablet_alias = $root.topodata.TabletAlias.fromObject(object.tablet_alias); + } + if (object.time != null) { + if (typeof object.time !== "object") + throw TypeError(".mysqlctl.BackupInfo.time: object expected"); + message.time = $root.vttime.Time.fromObject(object.time); + } + if (object.engine != null) + message.engine = String(object.engine); + switch (object.status) { + case "UNKNOWN": + case 0: + message.status = 0; + break; + case "INCOMPLETE": + case 1: + message.status = 1; + break; + case "COMPLETE": + case 2: + message.status = 2; + break; + case "INVALID": + case 3: + message.status = 3; + break; + case "VALID": + case 4: + message.status = 4; + break; + } return message; }; @@ -87424,11 +87642,29 @@ $root.mysqlctl = (function() { if (options.defaults) { object.name = ""; object.directory = ""; + object.keyspace = ""; + object.shard = ""; + object.tablet_alias = null; + object.time = null; + object.engine = ""; + object.status = options.enums === String ? "UNKNOWN" : 0; } if (message.name != null && message.hasOwnProperty("name")) object.name = message.name; if (message.directory != null && message.hasOwnProperty("directory")) object.directory = message.directory; + if (message.keyspace != null && message.hasOwnProperty("keyspace")) + object.keyspace = message.keyspace; + if (message.shard != null && message.hasOwnProperty("shard")) + object.shard = message.shard; + if (message.tablet_alias != null && message.hasOwnProperty("tablet_alias")) + object.tablet_alias = $root.topodata.TabletAlias.toObject(message.tablet_alias, options); + if (message.time != null && message.hasOwnProperty("time")) + object.time = $root.vttime.Time.toObject(message.time, options); + if (message.engine != null && message.hasOwnProperty("engine")) + object.engine = message.engine; + if (message.status != null && message.hasOwnProperty("status")) + object.status = options.enums === String ? $root.mysqlctl.BackupInfo.Status[message.status] : message.status; return object; }; @@ -87443,6 +87679,26 @@ $root.mysqlctl = (function() { return this.constructor.toObject(this, $protobuf.util.toJSONOptions); }; + /** + * Status enum. + * @name mysqlctl.BackupInfo.Status + * @enum {number} + * @property {number} UNKNOWN=0 UNKNOWN value + * @property {number} INCOMPLETE=1 INCOMPLETE value + * @property {number} COMPLETE=2 COMPLETE value + * @property {number} INVALID=3 INVALID value + * @property {number} VALID=4 VALID value + */ + BackupInfo.Status = (function() { + var valuesById = {}, values = Object.create(valuesById); + values[valuesById[0] = "UNKNOWN"] = 0; + values[valuesById[1] = "INCOMPLETE"] = 1; + values[valuesById[2] = "COMPLETE"] = 2; + values[valuesById[3] = "INVALID"] = 3; + values[valuesById[4] = "VALID"] = 4; + return values; + })(); + return BackupInfo; })(); From 468c607fece6dda477b61e815adf072d395d28a3 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Wed, 9 Jun 2021 14:44:13 -0400 Subject: [PATCH 290/310] [protutil] Add conversion functions to/from `vttime.Time`/`time.Time` Signed-off-by: Andrew Mason --- go/protoutil/time.go | 44 +++++++++++++++++++++++++++++++++ go/protoutil/time_test.go | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 go/protoutil/time.go create mode 100644 go/protoutil/time_test.go diff --git a/go/protoutil/time.go b/go/protoutil/time.go new file mode 100644 index 00000000000..c226001d4b2 --- /dev/null +++ b/go/protoutil/time.go @@ -0,0 +1,44 @@ +/* +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 protoutil + +import ( + "time" + + "vitess.io/vitess/go/vt/proto/vttime" +) + +// TimeFromProto converts a vttime.Time proto message into a time.Time object. +func TimeFromProto(tpb *vttime.Time) time.Time { + if tpb == nil { + return time.Time{} + } + + return time.Unix(tpb.Seconds, int64(tpb.Nanoseconds)) +} + +// TimeToProto converts a time.Time object into a vttime.Time proto mesasge. +func TimeToProto(t time.Time) *vttime.Time { + secs, nanos := t.Unix(), t.UnixNano() + + nsecs := secs * 1e9 + extraNanos := nanos - nsecs + return &vttime.Time{ + Seconds: secs, + Nanoseconds: int32(extraNanos), + } +} diff --git a/go/protoutil/time_test.go b/go/protoutil/time_test.go new file mode 100644 index 00000000000..eb3ecb2f0a9 --- /dev/null +++ b/go/protoutil/time_test.go @@ -0,0 +1,52 @@ +/* +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 protoutil + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "vitess.io/vitess/go/test/utils" + "vitess.io/vitess/go/vt/proto/vttime" +) + +func TestTimeFromProto(t *testing.T) { + now := time.Date(2021, time.June, 12, 13, 14, 15, 0 /* nanos */, time.UTC) + vtt := TimeToProto(now) + + utils.MustMatch(t, now, TimeFromProto(vtt)) + + vtt.Nanoseconds = 100 + utils.MustMatch(t, now.Add(100*time.Nanosecond), TimeFromProto(vtt)) + + vtt.Nanoseconds = 1e9 + utils.MustMatch(t, now.Add(time.Second), TimeFromProto(vtt)) + + assert.True(t, TimeFromProto(nil).IsZero(), "expected Go time from nil vttime to be Zero") +} + +func TestTimeToProto(t *testing.T) { + now := time.Date(2021, time.June, 12, 13, 14, 15, 0 /* nanos */, time.UTC) + secs := now.Unix() + utils.MustMatch(t, &vttime.Time{Seconds: secs}, TimeToProto(now)) + + // Testing secs/nanos conversions + utils.MustMatch(t, &vttime.Time{Seconds: secs, Nanoseconds: 100}, TimeToProto(now.Add(100*time.Nanosecond))) + utils.MustMatch(t, &vttime.Time{Seconds: secs + 1}, TimeToProto(now.Add(1e9*time.Nanosecond))) // this should rollover to a full second +} From 6c51a7e16d44223baf529766385e2f4b09a12655 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Sat, 12 Jun 2021 14:47:39 -0400 Subject: [PATCH 291/310] [vtctldserver] Update `BackupHandleToProto` to parse time/tablet info, add limiting Signed-off-by: Andrew Mason --- go/vt/mysqlctl/mysqlctlproto/backup.go | 33 +++++- go/vt/mysqlctl/mysqlctlproto/backup_test.go | 114 ++++++++++++++++++++ go/vt/vtctl/grpcvtctldserver/server.go | 38 ++++++- go/vt/vtctl/grpcvtctldserver/server_test.go | 51 +++++++++ 4 files changed, 231 insertions(+), 5 deletions(-) create mode 100644 go/vt/mysqlctl/mysqlctlproto/backup_test.go diff --git a/go/vt/mysqlctl/mysqlctlproto/backup.go b/go/vt/mysqlctl/mysqlctlproto/backup.go index 6fa2755b441..6c0cc08f9fe 100644 --- a/go/vt/mysqlctl/mysqlctlproto/backup.go +++ b/go/vt/mysqlctl/mysqlctlproto/backup.go @@ -17,15 +17,46 @@ limitations under the License. package mysqlctlproto import ( + "strings" + "time" + + "vitess.io/vitess/go/protoutil" + "vitess.io/vitess/go/vt/log" + "vitess.io/vitess/go/vt/mysqlctl" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + "vitess.io/vitess/go/vt/topo/topoproto" mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" ) // BackupHandleToProto returns a BackupInfo proto from a BackupHandle. func BackupHandleToProto(bh backupstorage.BackupHandle) *mysqlctlpb.BackupInfo { - return &mysqlctlpb.BackupInfo{ + bi := &mysqlctlpb.BackupInfo{ Name: bh.Name(), Directory: bh.Directory(), } + + if parts := strings.Split(bi.Name, "."); len(parts) == 3 { + // parts[0]: date part of mysqlctl.BackupTimestampFormat + // parts[1]: time part of mysqlctl.BackupTimestampFormat + // parts[2]: tablet alias + timestamp := strings.Join(parts[:2], ".") + aliasStr := parts[2] + + backupTime, err := time.Parse(mysqlctl.BackupTimestampFormat, timestamp) + if err != nil { + log.Errorf("error parsing backup time for %s/%s: %s", bi.Directory, bi.Name, err) + } else { + bi.Time = protoutil.TimeToProto(backupTime) + } + + alias, err := topoproto.ParseTabletAlias(aliasStr) + if err != nil { + log.Errorf("error parsing tablet alias for %s/%s: %s", bi.Directory, bi.Name, err) + } else { + bi.TabletAlias = alias + } + } + + return bi } diff --git a/go/vt/mysqlctl/mysqlctlproto/backup_test.go b/go/vt/mysqlctl/mysqlctlproto/backup_test.go new file mode 100644 index 00000000000..a5e31295a0e --- /dev/null +++ b/go/vt/mysqlctl/mysqlctlproto/backup_test.go @@ -0,0 +1,114 @@ +/* +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 mysqlctlproto + +import ( + "path" + "testing" + "time" + + "vitess.io/vitess/go/protoutil" + "vitess.io/vitess/go/test/utils" + "vitess.io/vitess/go/vt/mysqlctl/backupstorage" + + mysqlctlpb "vitess.io/vitess/go/vt/proto/mysqlctl" + topodatapb "vitess.io/vitess/go/vt/proto/topodata" +) + +type backupHandle struct { + backupstorage.BackupHandle + name string + directory string +} + +func (bh *backupHandle) Name() string { return bh.name } +func (bh *backupHandle) Directory() string { return bh.directory } +func (bh *backupHandle) testname() string { return path.Join(bh.directory, bh.name) } + +func TestBackupHandleToProto(t *testing.T) { + t.Parallel() + + now := time.Date(2021, time.June, 12, 15, 4, 5, 0, time.UTC) + tests := []struct { + bh *backupHandle + want *mysqlctlpb.BackupInfo + }{ + { + bh: &backupHandle{ + name: "2021-06-12.150405.zone1-100", + directory: "foo", + }, + want: &mysqlctlpb.BackupInfo{ + Name: "2021-06-12.150405.zone1-100", + Directory: "foo", + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Time: protoutil.TimeToProto(now), + }, + }, + { + bh: &backupHandle{ + name: "bar", + directory: "foo", + }, + want: &mysqlctlpb.BackupInfo{ + Name: "bar", + Directory: "foo", + }, + }, + { + bh: &backupHandle{ + name: "invalid.time.zone1-100", + directory: "foo", + }, + want: &mysqlctlpb.BackupInfo{ + Name: "invalid.time.zone1-100", + Directory: "foo", + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 100, + }, + Time: nil, + }, + }, + { + bh: &backupHandle{ + name: "2021-06-12.150405.not_an_alias", + directory: "foo", + }, + want: &mysqlctlpb.BackupInfo{ + Name: "2021-06-12.150405.not_an_alias", + Directory: "foo", + TabletAlias: nil, + Time: protoutil.TimeToProto(now), + }, + }, + } + + for _, tt := range tests { + tt := tt + + t.Run(tt.bh.testname(), func(t *testing.T) { + t.Parallel() + + got := BackupHandleToProto(tt.bh) + utils.MustMatch(t, tt.want, got) + }) + } +} diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 647517ee0d4..4dec80c2664 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -654,6 +654,9 @@ func (s *VtctldServer) GetBackups(ctx context.Context, req *vtctldatapb.GetBacku span.Annotate("keyspace", req.Keyspace) span.Annotate("shard", req.Shard) + span.Annotate("limit", req.Limit) + span.Annotate("detailed", req.Detailed) + span.Annotate("detailed_limit", req.DetailedLimit) bs, err := backupstorage.GetBackupStorage() if err != nil { @@ -669,15 +672,42 @@ func (s *VtctldServer) GetBackups(ctx context.Context, req *vtctldatapb.GetBacku return nil, err } - resp := &vtctldatapb.GetBackupsResponse{ - Backups: make([]*mysqlctlpb.BackupInfo, len(bhs)), + totalBackups := len(bhs) + if req.Limit > 0 { + totalBackups = int(req.Limit) } + totalDetailedBackups := len(bhs) + if req.DetailedLimit > 0 { + totalDetailedBackups = int(req.DetailedLimit) + } + + backups := make([]*mysqlctlpb.BackupInfo, 0, totalBackups) + backupsToSkip := len(bhs) - totalBackups + backupsToSkipDetails := totalBackups - totalDetailedBackups + for i, bh := range bhs { - resp.Backups[i] = mysqlctlproto.BackupHandleToProto(bh) + if i < backupsToSkip { + continue + } + + bi := mysqlctlproto.BackupHandleToProto(bh) + bi.Keyspace = req.Keyspace + bi.Shard = req.Shard + + if req.Detailed { + if i >= backupsToSkipDetails { // nolint:staticcheck + // (TODO:@ajm188) Update backupengine/backupstorage implementations + // to get Status info for backups. + } + } + + backups = append(backups, bi) } - return resp, nil + return &vtctldatapb.GetBackupsResponse{ + Backups: backups, + }, nil } // GetCellInfoNames is part of the vtctlservicepb.VtctldServer interface. diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 7a5cb9f44a4..274398102c4 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -2738,10 +2738,14 @@ func TestGetBackups(t *testing.T) { { Directory: "testkeyspace/-", Name: "backup1", + Keyspace: "testkeyspace", + Shard: "-", }, { Directory: "testkeyspace/-", Name: "backup2", + Keyspace: "testkeyspace", + Shard: "-", }, }, } @@ -2774,6 +2778,53 @@ func TestGetBackups(t *testing.T) { }) assert.Error(t, err) }) + + t.Run("parsing times and aliases", func(t *testing.T) { + testutil.BackupStorage.Backups["ks2/-80"] = []string{ + "2021-06-11.123456.zone1-101", + } + + resp, err := vtctld.GetBackups(ctx, &vtctldatapb.GetBackupsRequest{ + Keyspace: "ks2", + Shard: "-80", + }) + require.NoError(t, err) + expected := &vtctldatapb.GetBackupsResponse{ + Backups: []*mysqlctlpb.BackupInfo{ + { + Directory: "ks2/-80", + Name: "2021-06-11.123456.zone1-101", + Keyspace: "ks2", + Shard: "-80", + Time: protoutil.TimeToProto(time.Date(2021, time.June, 11, 12, 34, 56, 0, time.UTC)), + TabletAlias: &topodatapb.TabletAlias{ + Cell: "zone1", + Uid: 101, + }, + }, + }, + } + utils.MustMatch(t, expected, resp) + }) + + t.Run("limiting", func(t *testing.T) { + unlimited, err := vtctld.GetBackups(ctx, &vtctldatapb.GetBackupsRequest{ + Keyspace: "testkeyspace", + Shard: "-", + }) + require.NoError(t, err) + + limited, err := vtctld.GetBackups(ctx, &vtctldatapb.GetBackupsRequest{ + Keyspace: "testkeyspace", + Shard: "-", + Limit: 1, + }) + require.NoError(t, err) + + assert.Equal(t, len(limited.Backups), 1, "expected limited backups to have length 1") + assert.Less(t, len(limited.Backups), len(unlimited.Backups), "expected limited backups to be less than unlimited") + utils.MustMatch(t, limited.Backups[0], unlimited.Backups[len(unlimited.Backups)-1], "expected limiting to keep N most recent") + }) } func TestGetKeyspace(t *testing.T) { From a4e226db6ef2114c0abcea1ba018d643a58e60cb Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Sat, 12 Jun 2021 14:52:45 -0400 Subject: [PATCH 292/310] [vtctldclient] Update CLI entrypoint for GetBackups We're not including the Detailed fields here yet, because they are unused in the server implementation (for now). Signed-off-by: Andrew Mason --- .../vtctldclient/internal/command/backups.go | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/go/cmd/vtctldclient/internal/command/backups.go b/go/cmd/vtctldclient/internal/command/backups.go index 21d5673ef34..02fca34b620 100644 --- a/go/cmd/vtctldclient/internal/command/backups.go +++ b/go/cmd/vtctldclient/internal/command/backups.go @@ -23,30 +23,50 @@ import ( "github.com/spf13/cobra" "vitess.io/vitess/go/cmd/vtctldclient/cli" + "vitess.io/vitess/go/vt/topo/topoproto" + vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) // GetBackups makes a GetBackups gRPC call to a vtctld. var GetBackups = &cobra.Command{ - Use: "GetBackups keyspace shard", - Args: cobra.ExactArgs(2), + Use: "GetBackups ", + Args: cobra.ExactArgs(1), RunE: commandGetBackups, } +var getBackupsOptions = struct { + Limit uint32 + OutputJSON bool +}{} + func commandGetBackups(cmd *cobra.Command, args []string) error { - cli.FinishedParsing(cmd) + keyspace, shard, err := topoproto.ParseKeyspaceShard(cmd.Flags().Arg(0)) + if err != nil { + return err + } - keyspace := cmd.Flags().Arg(0) - shard := cmd.Flags().Arg(1) + cli.FinishedParsing(cmd) resp, err := client.GetBackups(commandCtx, &vtctldatapb.GetBackupsRequest{ Keyspace: keyspace, Shard: shard, + Limit: getBackupsOptions.Limit, }) if err != nil { return err } + if getBackupsOptions.OutputJSON { + data, err := cli.MarshalJSON(resp) + if err != nil { + return err + } + + fmt.Printf("%s\n", data) + return nil + } + names := make([]string, len(resp.Backups)) for i, b := range resp.Backups { names[i] = b.Name @@ -58,5 +78,7 @@ func commandGetBackups(cmd *cobra.Command, args []string) error { } func init() { + GetBackups.Flags().Uint32VarP(&getBackupsOptions.Limit, "limit", "l", 0, "Retrieve only the most recent N backups") + GetBackups.Flags().BoolVarP(&getBackupsOptions.OutputJSON, "json", "j", false, "Output backup info in JSON format rather than a list of backups") Root.AddCommand(GetBackups) } From 411950ff265cfd1f7b2d41b19cf5e35e7cb8d978 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Mon, 14 Jun 2021 16:55:25 -0400 Subject: [PATCH 293/310] Move the parsing around, add link to issue Signed-off-by: Andrew Mason --- go/vt/mysqlctl/backup.go | 36 ++++++++++++++++++++++++++ go/vt/mysqlctl/mysqlctlproto/backup.go | 34 +++++++----------------- proto/mysqlctl.proto | 1 + 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/go/vt/mysqlctl/backup.go b/go/vt/mysqlctl/backup.go index f057cdf4b12..8480c4615ec 100644 --- a/go/vt/mysqlctl/backup.go +++ b/go/vt/mysqlctl/backup.go @@ -32,7 +32,10 @@ import ( "vitess.io/vitess/go/vt/log" "vitess.io/vitess/go/vt/mysqlctl/backupstorage" "vitess.io/vitess/go/vt/proto/vtrpc" + "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vterrors" + + topodatapb "vitess.io/vitess/go/vt/proto/topodata" ) // This file handles the backup and restore related code @@ -138,6 +141,39 @@ func Backup(ctx context.Context, params BackupParams) error { return finishErr } +// ParseBackupName parses the backup name for a given dir/name, according to +// the format generated by mysqlctl.Backup. An error is returned only if the +// backup name does not have the expected number of parts; errors parsing the +// timestamp and tablet alias are logged, and a nil value is returned for those +// fields in case of error. +func ParseBackupName(dir string, name string) (backupTime *time.Time, alias *topodatapb.TabletAlias, err error) { + parts := strings.Split(name, ".") + if len(parts) != 3 { + return nil, nil, vterrors.Errorf(vtrpc.Code_INVALID_ARGUMENT, "cannot backup name %s, expected .